diff --git a/CHANGELOG.md b/CHANGELOG.md index 078a1f14bbe9..93e05df209ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,13 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b #### Bug fixes -- Fix [#3069](https://github.com/biomejs/biome/issues/3069), prevent overwriting paths when using `--staged` or `--changed` options. Contributed by @unvalley +- Fix [#3069](https://github.com/biomejs/biome/issues/3069), prevent overwriting paths when using `--staged` or `--changed` options. Contributed by @unvalley + +### Linter + +#### Bug fixes + +- The `no-empty-block` css lint rule now treats empty blocks containing comments as valid ones. Contributed by @Sec-ant ## 1.8.0 (2024-06-04) diff --git a/crates/biome_css_analyze/src/lint/nursery/no_empty_block.rs b/crates/biome_css_analyze/src/lint/nursery/no_empty_block.rs index a65eb18a74da..966c88cdf54f 100644 --- a/crates/biome_css_analyze/src/lint/nursery/no_empty_block.rs +++ b/crates/biome_css_analyze/src/lint/nursery/no_empty_block.rs @@ -57,7 +57,7 @@ impl Rule for NoEmptyBlock { fn run(ctx: &RuleContext) -> Option { let node = ctx.query(); - if node.is_empty() { + if node.is_empty_without_comments() { return Some(node.clone()); } diff --git a/crates/biome_css_analyze/tests/specs/nursery/noEmptyBlock/valid.css.snap b/crates/biome_css_analyze/tests/specs/nursery/noEmptyBlock/valid.css.snap index a029567d6246..8ebfac1bab70 100644 --- a/crates/biome_css_analyze/tests/specs/nursery/noEmptyBlock/valid.css.snap +++ b/crates/biome_css_analyze/tests/specs/nursery/noEmptyBlock/valid.css.snap @@ -75,99 +75,3 @@ a { @import "foo.css"; @import url(x.css) ``` - -# Diagnostics -``` -valid.css:3:3 lint/nursery/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! An empty block isn't allowed. - - 1 │ /* CssDeclarationOrRuleBlock */ - 2 │ a { color: pink; } - > 3 │ a { /* foo */ } - │ ^^^^^^^^^^^^^ - 4 │ a { - 5 │ /* foo */ - - i Consider removing the empty block or adding styles inside it. - - -``` - -``` -valid.css:4:3 lint/nursery/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! An empty block isn't allowed. - - 2 │ a { color: pink; } - 3 │ a { /* foo */ } - > 4 │ a { - │ ^ - > 5 │ /* foo */ - > 6 │ } - │ ^ - 7 │ a { - 8 │ /* foo */ - - i Consider removing the empty block or adding styles inside it. - - -``` - -``` -valid.css:7:3 lint/nursery/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! An empty block isn't allowed. - - 5 │ /* foo */ - 6 │ } - > 7 │ a { - │ ^ - > 8 │ /* foo */ - > 9 │ /* bar */ - > 10 │ } - │ ^ - 11 │ a { - 12 │ /*\nfoo\nbar\n*/ - - i Consider removing the empty block or adding styles inside it. - - -``` - -``` -valid.css:11:3 lint/nursery/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! An empty block isn't allowed. - - 9 │ /* bar */ - 10 │ } - > 11 │ a { - │ ^ - > 12 │ /*\nfoo\nbar\n*/ - > 13 │ } - │ ^ - 14 │ - 15 │ /* CssRuleBlock */ - - i Consider removing the empty block or adding styles inside it. - - -``` - -``` -valid.css:17:18 lint/nursery/noEmptyBlock ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! An empty block isn't allowed. - - 15 │ /* CssRuleBlock */ - 16 │ @media print { a { color: pink; } } - > 17 │ @media print { a { /* foo */ } } - │ ^^^^^^^^^^^^^ - 18 │ - 19 │ /* CssDeclarationBlock */ - - i Consider removing the empty block or adding styles inside it. - - -``` diff --git a/crates/biome_css_syntax/src/stmt_ext.rs b/crates/biome_css_syntax/src/stmt_ext.rs index 23ac09280501..e0fc5c449ca2 100644 --- a/crates/biome_css_syntax/src/stmt_ext.rs +++ b/crates/biome_css_syntax/src/stmt_ext.rs @@ -10,6 +10,7 @@ declare_node_union! { } impl CssBlockLike { + /// Retrieves the left curly token "{" of the css block-like. pub fn l_curly_token(&self) -> SyntaxResult { match self { CssBlockLike::CssKeyframesBlock(block) => block.l_curly_token(), @@ -22,6 +23,7 @@ impl CssBlockLike { } } + /// Retrieves the right curly token "}" of the css block-like. pub fn r_curly_token(&self) -> SyntaxResult { match self { CssBlockLike::CssKeyframesBlock(block) => block.r_curly_token(), @@ -34,6 +36,7 @@ impl CssBlockLike { } } + /// Checks if the css block-like is empty, even if it may have comments inside. pub fn is_empty(&self) -> bool { match self { CssBlockLike::CssKeyframesBlock(block) => block.items().is_empty(), @@ -45,4 +48,15 @@ impl CssBlockLike { CssBlockLike::CssDeclarationOrRuleBlock(block) => block.items().is_empty(), } } + + /// Checks if the css block-like is empty without comments inside. + pub fn is_empty_without_comments(&self) -> bool { + self.is_empty() + && !self + .l_curly_token() + .is_ok_and(|token| token.has_trailing_comments()) + && !self + .r_curly_token() + .is_ok_and(|token| token.has_leading_comments()) + } }