Skip to content

Commit

Permalink
feat(biome_css_parser): recognize multiple semicolons after declaretion
Browse files Browse the repository at this point in the history
  • Loading branch information
fireairforce committed Oct 22, 2024
1 parent a1ae7bf commit 3e8fe68
Show file tree
Hide file tree
Showing 17 changed files with 596 additions and 184 deletions.
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
10 changes: 10 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,10 @@
use crate::prelude::*;
use biome_css_syntax::CssEmptyDeclaration;
use biome_rowan::AstNode;
#[derive(Debug, Clone, Default)]
pub(crate) struct FormatCssEmptyDeclaration;
impl FormatNodeRule<CssEmptyDeclaration> for FormatCssEmptyDeclaration {
fn fmt_fields(&self, node: &CssEmptyDeclaration, f: &mut CssFormatter) -> FormatResult<()> {
format_verbatim_node(node.syntax()).fmt(f)
}
}
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 @@ -3,15 +3,16 @@ use crate::syntax::at_rule::{is_at_at_rule, parse_at_rule};
use crate::syntax::block::ParseBlockBody;
use crate::syntax::parse_error::expected_any_declaration_or_at_rule;
use crate::syntax::{
is_at_declaration, is_at_metavariable, is_at_nested_qualified_rule,
parse_declaration_with_semicolon, parse_metavariable, parse_nested_qualified_rule, try_parse,
is_at_declaration, is_at_declaration_semion, is_at_metavariable, is_at_nested_qualified_rule,
parse_declaration_with_semicolon, parse_empty_declaration, parse_metavariable,
parse_nested_qualified_rule, try_parse,
};
use biome_css_syntax::CssSyntaxKind::*;
use biome_css_syntax::{CssSyntaxKind, T};
use biome_parser::parse_lists::ParseNodeList;
use biome_parser::parse_recovery::{ParseRecovery, RecoveryResult};
use biome_parser::parsed_syntax::ParsedSyntax;
use biome_parser::parsed_syntax::ParsedSyntax::Absent;
use biome_parser::prelude::ParsedSyntax;
use biome_parser::prelude::ParsedSyntax::Absent;
use biome_parser::{CompletedMarker, Parser};

#[inline]
Expand Down Expand Up @@ -89,8 +90,6 @@ impl ParseNodeList for DeclarationOrRuleList {
if matches!(p.last(), Some(T![;])) || p.at(T!['}']) {
Ok(declaration)
} else {
// If neither condition is met, return an error to indicate parsing failure.
// And rewind the parser to the start of the declaration.
Err(())
}
});
Expand Down Expand Up @@ -129,6 +128,8 @@ impl ParseNodeList for DeclarationOrRuleList {
parse_nested_qualified_rule(p)
} else if is_at_metavariable(p) {
parse_metavariable(p)
} else if is_at_declaration_semion(p) {
parse_empty_declaration(p)
} else {
Absent
}
Expand Down
16 changes: 16 additions & 0 deletions crates/biome_css_parser/src/syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,27 @@ pub(crate) fn parse_declaration_with_semicolon(p: &mut CssParser) -> ParsedSynta
Present(m.complete(p, CSS_DECLARATION_WITH_SEMICOLON))
}

#[inline]
pub(crate) fn parse_empty_declaration(p: &mut CssParser) -> ParsedSyntax {
if p.at(T![;]) {
let m = p.start();
p.bump_any(); // bump ;
m.complete(p, CSS_EMPTY_DECLARATION).into()
} else {
Absent
}
}

#[inline]
fn is_at_declaration_important(p: &mut CssParser) -> bool {
p.at(T![!]) && p.nth_at(1, T![important])
}

#[inline]
pub(crate) fn is_at_declaration_semion(p: &mut CssParser) -> bool {
p.at(T![;]) && (p.nth_at(1, T![;]) || p.nth_at(1, T!['}']))
}

#[inline]
fn parse_declaration_important(p: &mut CssParser) -> ParsedSyntax {
if !is_at_declaration_important(p) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ a {
prop1: --custom;
}

a {
prop1: 1px;
prop2: 2px;;;
}

a {
prop1: 1px;;;
}

div {
flex: 1 1 auto !important;
}
Expand Down
Loading

0 comments on commit 3e8fe68

Please sign in to comment.