Skip to content

Commit

Permalink
feat(css_parser): recognize multiple semicolons after declaretion
Browse files Browse the repository at this point in the history
  • Loading branch information
fireairforce committed Oct 23, 2024
1 parent d59d43d commit 26e7fa8
Show file tree
Hide file tree
Showing 24 changed files with 633 additions and 299 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

Contributed by @fireairforce

- Fix [#3836](https://github.com/biomejs/biome/issues/3836), css parser allow multiple semicolons after a declaration, the following example will now parsed correctly:

```css
.foo {
color: red;;
}
```

Contributed by @fireairforce


## v1.9.4 (2024-10-17)

### Analyzer
Expand Down
6 changes: 6 additions & 0 deletions crates/biome_css_factory/src/generated/node_factory.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions crates/biome_css_factory/src/generated/syntax_factory.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ impl FormatRule<AnyCssDeclarationOrRule> for FormatAnyCssDeclarationOrRule {
AnyCssDeclarationOrRule::AnyCssRule(node) => node.format().fmt(f),
AnyCssDeclarationOrRule::CssBogus(node) => node.format().fmt(f),
AnyCssDeclarationOrRule::CssDeclarationWithSemicolon(node) => node.format().fmt(f),
AnyCssDeclarationOrRule::CssEmptyDeclaration(node) => node.format().fmt(f),
AnyCssDeclarationOrRule::CssMetavariable(node) => node.format().fmt(f),
}
}
Expand Down
21 changes: 21 additions & 0 deletions crates/biome_css_formatter/src/css/auxiliary/empty_declaration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::prelude::*;
use biome_css_syntax::{CssEmptyDeclaration, CssEmptyDeclarationFields, CssSyntaxKind};
use biome_formatter::write;
use biome_rowan::{AstNode, SyntaxNodeOptionExt};
#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssEmptyDeclaration;
impl FormatNodeRule<CssEmptyDeclaration> for FormatCssEmptyDeclaration {
fn fmt_fields(&self, node: &CssEmptyDeclaration, f: &mut CssFormatter) -> FormatResult<()> {
let CssEmptyDeclarationFields { semicolon_token } = node.as_fields();
let parent_kind = node.syntax().parent().kind();

if matches!(
parent_kind,
Some(CssSyntaxKind::CSS_DECLARATION_WITH_SEMICOLON,)
) {
write!(f, [semicolon_token.format()])
} else {
write!(f, [format_removed(&semicolon_token?)])
}
}
}
1 change: 1 addition & 0 deletions crates/biome_css_formatter/src/css/auxiliary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub(crate) mod declaration_or_at_rule_block;
pub(crate) mod declaration_or_rule_block;
pub(crate) mod declaration_with_semicolon;
pub(crate) mod document_custom_matcher;
pub(crate) mod empty_declaration;
pub(crate) mod font_family_name;
pub(crate) mod font_feature_values_block;
pub(crate) mod font_feature_values_item;
Expand Down
40 changes: 40 additions & 0 deletions crates/biome_css_formatter/src/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,46 @@ impl IntoFormat<CssFormatContext> for biome_css_syntax::CssDocumentCustomMatcher
)
}
}
impl FormatRule<biome_css_syntax::CssEmptyDeclaration>
for crate::css::auxiliary::empty_declaration::FormatCssEmptyDeclaration
{
type Context = CssFormatContext;
#[inline(always)]
fn fmt(
&self,
node: &biome_css_syntax::CssEmptyDeclaration,
f: &mut CssFormatter,
) -> FormatResult<()> {
FormatNodeRule::<biome_css_syntax::CssEmptyDeclaration>::fmt(self, node, f)
}
}
impl AsFormat<CssFormatContext> for biome_css_syntax::CssEmptyDeclaration {
type Format<'a> = FormatRefWithRule<
'a,
biome_css_syntax::CssEmptyDeclaration,
crate::css::auxiliary::empty_declaration::FormatCssEmptyDeclaration,
>;
fn format(&self) -> Self::Format<'_> {
#![allow(clippy::default_constructed_unit_structs)]
FormatRefWithRule::new(
self,
crate::css::auxiliary::empty_declaration::FormatCssEmptyDeclaration::default(),
)
}
}
impl IntoFormat<CssFormatContext> for biome_css_syntax::CssEmptyDeclaration {
type Format = FormatOwnedWithRule<
biome_css_syntax::CssEmptyDeclaration,
crate::css::auxiliary::empty_declaration::FormatCssEmptyDeclaration,
>;
fn into_format(self) -> Self::Format {
#![allow(clippy::default_constructed_unit_structs)]
FormatOwnedWithRule::new(
self,
crate::css::auxiliary::empty_declaration::FormatCssEmptyDeclaration::default(),
)
}
}
impl FormatRule<biome_css_syntax::CssFontFaceAtRule>
for crate::css::statements::font_face_at_rule::FormatCssFontFaceAtRule
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ a {
--bs-font-monospace: sfmono-regular , menlo , monaco , consolas ,
'Liberation Mono' , 'Courier New' , monospace;
}

a {
color: red;;;;
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ a {
'Liberation Mono' , 'Courier New' , monospace;
}

a {
color: red;;;;
}
```


Expand Down Expand Up @@ -96,4 +99,8 @@ a {
--bs-font-monospace: sfmono-regular, menlo, monaco, consolas,
"Liberation Mono", "Courier New", monospace;
}

a {
color: red;
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ font-size: 12px;
```diff
--- Prettier
+++ Biome
@@ -1,13 +1,14 @@
@@ -1,13 +1,13 @@
/* comment 1 */
:root {
/* comment 2 */
Expand All @@ -41,7 +41,6 @@ font-size: 12px;
/* comment 9 */
- };
+ }
+ ;
/* comment 10 */
}
/* comment 11 */
Expand All @@ -60,7 +59,6 @@ font-size: 12px;
font-size: 12px;
/* comment 9 */
}
;
/* comment 10 */
}
/* comment 11 */
Expand Down Expand Up @@ -127,25 +125,5 @@ custom-properties.css:4:12 parse ━━━━━━━━━━━━━━━
- past
- future
custom-properties.css:10:4 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Expected a declaration, or an at rule but instead found ';'.
8 │ font-size: 12px;
9 │ /* comment 9 */
> 10 │ };
│ ^
11 │ /* comment 10 */
12 │ }
i Expected a declaration, or an at rule here.
8 │ font-size: 12px;
9 │ /* comment 9 */
> 10 │ };
│ ^
11 │ /* comment 10 */
12 │ }
```
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ input:not(/* comment 125 */[/* comment 126 */disabled/* comment 127 */]/* commen
/* comment 161 */
} /* comment 162 */
/* comment 163 */
@@ -201,30 +188,35 @@
@@ -201,30 +188,34 @@
/* comment 165 */
} /* comment 166 */

Expand Down Expand Up @@ -482,7 +482,6 @@ input:not(/* comment 125 */[/* comment 126 */disabled/* comment 127 */]/* commen
justify-content: center;
- };
+ }
+ ;
}
```

Expand Down Expand Up @@ -709,7 +708,6 @@ input:not(
align-items: center;
justify-content: center;
}
;
}
```

Expand Down Expand Up @@ -854,26 +852,6 @@ selectors.css:152:75 parse ━━━━━━━━━━━━━━━━━
- past
- future
selectors.css:156:6 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Expected a declaration, or an at rule but instead found ';'.
154 │ align-items: center;
155 │ justify-content: center;
> 156 │ };
│ ^
157 │ }
158 │
i Expected a declaration, or an at rule here.
154 │ align-items: center;
155 │ justify-content: center;
> 156 │ };
│ ^
157 │ }
158 │
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ a {
```diff
--- Prettier
+++ Biome
@@ -13,17 +13,19 @@
@@ -13,16 +13,17 @@
content: url(https://example.com/\)\).jpg);
content: url(https://example.com/\(\(.jpg);
content: url(https://example.com/\ \ .jpg);
Expand All @@ -69,8 +69,6 @@ a {
no-repeat url(foo.ttf?query=foo,bar,),
no-repeat url(foo.woff2?foo=rgb\(255,255,0\))
no-repeat url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
+ ;
}
```

# Output
Expand Down Expand Up @@ -105,7 +103,6 @@ a {
no-repeat url(foo.ttf?query=foo,bar,),
no-repeat url(foo.woff2?foo=rgb\(255,255,0\))
no-repeat url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
;
}
```

Expand Down Expand Up @@ -165,26 +162,6 @@ url.css:3:33 parse ━━━━━━━━━━━━━━━━━━━━
- custom property
- function
url.css:30:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Expected a declaration, or an at rule but instead found ';'.
28 │ no-repeat url(foo.woff2?foo=rgb\(255,255,0\))
29 │ no-repeat url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
> 30 │ ;
│ ^
31 │ }
32 │
i Expected a declaration, or an at rule here.
28 │ no-repeat url(foo.woff2?foo=rgb\(255,255,0\))
29 │ no-repeat url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
> 30 │ ;
│ ^
31 │ }
32 │
```

Expand Down
Loading

0 comments on commit 26e7fa8

Please sign in to comment.