From 251e98c05576d0495647e93ae0fe179da7435db9 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Wed, 30 Nov 2022 08:07:46 +0300 Subject: [PATCH] refactor(css/parser): Canonicalize only if required (#6532) --- .../swc_css_parser/src/parser/at_rules/mod.rs | 23 +- crates/swc_css_parser/src/parser/mod.rs | 22 +- .../swc_css_parser/src/parser/syntax/mod.rs | 28 +- crates/swc_css_parser/src/parser/util.rs | 30 +- .../src/parser/values_and_units/mod.rs | 267 ++---------------- 5 files changed, 85 insertions(+), 285 deletions(-) diff --git a/crates/swc_css_parser/src/parser/at_rules/mod.rs b/crates/swc_css_parser/src/parser/at_rules/mod.rs index a932854650a..9d26cbca81d 100644 --- a/crates/swc_css_parser/src/parser/at_rules/mod.rs +++ b/crates/swc_css_parser/src/parser/at_rules/mod.rs @@ -187,7 +187,6 @@ where { let ctx = Ctx { in_import_at_rule: true, - block_contents_grammar: BlockContentsGrammar::DeclarationValue, ..self.ctx }; let func = self.with_ctx(ctx).parse_as::()?; @@ -784,7 +783,6 @@ where Token::Function { value, .. } if *value.to_ascii_lowercase() == *"supports" => { let ctx = Ctx { in_import_at_rule: true, - block_contents_grammar: BlockContentsGrammar::DeclarationValue, ..self.ctx }; let func = self.with_ctx(ctx).parse_as::()?; @@ -1189,7 +1187,6 @@ where Token::Function { value, .. } if &*value.to_ascii_lowercase() == "selector" => { // TODO improve me let ctx = Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, in_supports_at_rule: true, ..self.ctx }; @@ -1217,7 +1214,7 @@ where match cur!(self) { tok!("function") => { let ctx = Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationList, + need_canonicalize: false, ..self.ctx }; let function = self.with_ctx(ctx).parse_as::()?; @@ -1297,11 +1294,7 @@ where Ok(DocumentPreludeMatchingFunction::Url(self.parse()?)) } else { // TODO improve me - let ctx = Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }; - let function = self.with_ctx(ctx).parse_as::()?; + let function = self.parse()?; Ok(DocumentPreludeMatchingFunction::Function(function)) } @@ -1881,11 +1874,7 @@ where tok!("ident") => Ok(MediaFeatureValue::Ident(self.parse()?)), tok!("dimension") => Ok(MediaFeatureValue::Dimension(self.parse()?)), Token::Function { value, .. } if is_math_function(value) => { - let ctx = Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }; - let function = self.with_ctx(ctx).parse_as::()?; + let function = self.parse()?; Ok(MediaFeatureValue::Function(function)) } @@ -2478,11 +2467,7 @@ where tok!("ident") => Ok(SizeFeatureValue::Ident(self.parse()?)), tok!("dimension") => Ok(SizeFeatureValue::Dimension(self.parse()?)), Token::Function { value, .. } if is_math_function(value) => { - let ctx = Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }; - let function = self.with_ctx(ctx).parse_as::()?; + let function = self.parse()?; Ok(SizeFeatureValue::Function(function)) } diff --git a/crates/swc_css_parser/src/parser/mod.rs b/crates/swc_css_parser/src/parser/mod.rs index 8324e88ac32..cca37a26f2c 100644 --- a/crates/swc_css_parser/src/parser/mod.rs +++ b/crates/swc_css_parser/src/parser/mod.rs @@ -55,7 +55,6 @@ pub enum BlockContentsGrammar { DeclarationList, RuleList, Stylesheet, - DeclarationValue, } impl Default for BlockContentsGrammar { @@ -64,11 +63,12 @@ impl Default for BlockContentsGrammar { } } -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Clone, Copy)] struct Ctx { is_top_level: bool, block_contents_grammar: BlockContentsGrammar, mixed_with_declarations: bool, + need_canonicalize: bool, in_keyframes_at_rule: bool, in_supports_at_rule: bool, @@ -78,6 +78,24 @@ struct Ctx { in_font_feature_values_at_rule: bool, } +impl Default for Ctx { + fn default() -> Self { + Ctx { + is_top_level: false, + block_contents_grammar: BlockContentsGrammar::default(), + mixed_with_declarations: false, + need_canonicalize: true, + + in_keyframes_at_rule: false, + in_supports_at_rule: false, + in_import_at_rule: false, + in_page_at_rule: false, + in_container_at_rule: false, + in_font_feature_values_at_rule: false, + } + } +} + #[derive(Debug, Clone)] pub struct Parser where diff --git a/crates/swc_css_parser/src/parser/syntax/mod.rs b/crates/swc_css_parser/src/parser/syntax/mod.rs index 35b187046b1..d48373c3c98 100644 --- a/crates/swc_css_parser/src/parser/syntax/mod.rs +++ b/crates/swc_css_parser/src/parser/syntax/mod.rs @@ -181,7 +181,9 @@ where at_rule.span = span!(self, span.lo); // Canonicalization against a grammar - at_rule = self.canonicalize_at_rule_prelude(at_rule)?; + if self.ctx.need_canonicalize { + at_rule = self.canonicalize_at_rule_prelude(at_rule)?; + } return Ok(at_rule); } @@ -197,8 +199,10 @@ where at_rule.span = span!(self, span.lo); // Canonicalization against a grammar - at_rule = self.canonicalize_at_rule_prelude(at_rule)?; - at_rule = self.canonicalize_at_rule_block(at_rule)?; + if self.ctx.need_canonicalize { + at_rule = self.canonicalize_at_rule_prelude(at_rule)?; + at_rule = self.canonicalize_at_rule_block(at_rule)?; + } return Ok(at_rule); } @@ -267,8 +271,11 @@ where }; // Canonicalization against a grammar - qualified_rule = self.canonicalize_qualified_rule_prelude(qualified_rule)?; - qualified_rule = self.canonicalize_qualified_rule_block(qualified_rule)?; + if self.ctx.need_canonicalize { + qualified_rule = + self.canonicalize_qualified_rule_prelude(qualified_rule)?; + qualified_rule = self.canonicalize_qualified_rule_block(qualified_rule)?; + } return Ok(qualified_rule); } @@ -748,7 +755,9 @@ where } // Canonicalization against a grammar - declaration = self.canonicalize_declaration_value(declaration)?; + if self.ctx.need_canonicalize { + declaration = self.canonicalize_declaration_value(declaration)?; + } // 8. Return the declaration. Ok(declaration) @@ -774,7 +783,8 @@ where let function = self .with_ctx({ Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationList, + // We canonize it later + need_canonicalize: false, ..self.ctx } }) @@ -944,7 +954,9 @@ where function.span = span!(self, span.lo); // Canonicalization against a grammar - function = self.canonicalize_function_value(function)?; + if self.ctx.need_canonicalize { + function = self.canonicalize_function_value(function)?; + } return Ok(function); } diff --git a/crates/swc_css_parser/src/parser/util.rs b/crates/swc_css_parser/src/parser/util.rs index 22b96c1f7fb..979c497b0e4 100644 --- a/crates/swc_css_parser/src/parser/util.rs +++ b/crates/swc_css_parser/src/parser/util.rs @@ -267,27 +267,21 @@ where &mut self, mut function: Function, ) -> PResult { - match self.ctx.block_contents_grammar { - BlockContentsGrammar::DeclarationList => {} - _ => { - let function_name = function.name.value.to_ascii_lowercase(); + let function_name = function.name.value.to_ascii_lowercase(); + let locv = self.create_locv(function.value); - let locv = self.create_locv(function.value); + function.value = match self.parse_according_to_grammar(&locv, |parser| { + parser.parse_function_values(&function_name) + }) { + Ok(values) => values, + Err(err) => { + if *err.kind() != ErrorKind::Ignore { + self.errors.push(err); + } - function.value = match self.parse_according_to_grammar(&locv, |parser| { - parser.parse_function_values(&function_name) - }) { - Ok(values) => values, - Err(err) => { - if *err.kind() != ErrorKind::Ignore { - self.errors.push(err); - } - - locv.children - } - }; + locv.children } - } + }; Ok(function) } diff --git a/crates/swc_css_parser/src/parser/values_and_units/mod.rs b/crates/swc_css_parser/src/parser/values_and_units/mod.rs index 6e1c5e324f9..d67f92a6725 100644 --- a/crates/swc_css_parser/src/parser/values_and_units/mod.rs +++ b/crates/swc_css_parser/src/parser/values_and_units/mod.rs @@ -1,7 +1,7 @@ use swc_common::{BytePos, Span}; use swc_css_ast::*; -use super::{input::ParserInput, BlockContentsGrammar, Ctx, PResult, Parser}; +use super::{input::ParserInput, PResult, Parser}; use crate::{ error::{Error, ErrorKind}, Parse, @@ -56,13 +56,7 @@ where return Ok(ComponentValue::Color(self.parse()?)); } _ => { - return Ok(ComponentValue::Function( - self.with_ctx(Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - )); + return Ok(ComponentValue::Function(self.parse()?)); } }, @@ -484,15 +478,7 @@ where } tok!("number") => Ok(Some(ComponentValue::Number(parser.parse()?))), Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { is_legacy_syntax = false; @@ -550,15 +536,7 @@ where } } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } _ => { if !has_variable_before { @@ -613,15 +591,7 @@ where } tok!("number") => Ok(Some(ComponentValue::Number(parser.parse()?))), Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") if !is_legacy_syntax => { let ident: Ident = parser.parse()?; @@ -665,15 +635,7 @@ where Ok(Some(ComponentValue::Percentage(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -745,15 +707,7 @@ where } tok!("number") => Ok(Some(ComponentValue::Number(parser.parse()?))), Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") if !is_legacy_syntax => { let ident: Ident = parser.parse()?; @@ -797,15 +751,7 @@ where Ok(Some(ComponentValue::Percentage(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -858,15 +804,7 @@ where Ok(Some(ComponentValue::AlphaValue(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } _ => { if !has_variable_before { @@ -900,15 +838,7 @@ where Ok(Some(ComponentValue::AlphaValue(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -982,15 +912,7 @@ where Ok(Some(ComponentValue::Hue(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1035,15 +957,7 @@ where } tok!("number") => Ok(Some(ComponentValue::Number(parser.parse()?))), Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1106,15 +1020,7 @@ where Ok(Some(ComponentValue::Percentage(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1163,15 +1069,7 @@ where Ok(Some(ComponentValue::Number(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1239,15 +1137,7 @@ where Ok(Some(ComponentValue::Percentage(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1296,15 +1186,7 @@ where Ok(Some(ComponentValue::Number(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1350,15 +1232,7 @@ where Ok(Some(ComponentValue::Hue(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1441,15 +1315,7 @@ where Ok(Some(ComponentValue::AlphaValue(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") if !matches!(function_name, "device-cmyk") => { let ident: Ident = parser.parse()?; @@ -1558,15 +1424,7 @@ where Ok(Some(ComponentValue::Percentage(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1621,14 +1479,7 @@ where "var" | "env" | "constant" ) => { - ComponentValue::Function( - self.with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - ) + ComponentValue::Function(self.parse()?) } tok!("ident") => { let ident: Ident = self.parse()?; @@ -1659,15 +1510,7 @@ where Ok(Some(ComponentValue::Percentage(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") => { let ident: Ident = parser.parse()?; @@ -1723,15 +1566,7 @@ where } } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } _ => { if !has_variable_before { @@ -1768,15 +1603,7 @@ where Ok(Some(ComponentValue::AlphaValue(parser.parse()?))) } Token::Function { value, .. } if is_math_function(value) => { - Ok(Some(ComponentValue::Function( - parser - .with_ctx(Ctx { - block_contents_grammar: - BlockContentsGrammar::DeclarationValue, - ..parser.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(parser.parse()?))) } tok!("ident") if !matches!(function_name, "device-cmyk") => { let ident: Ident = parser.parse()?; @@ -1928,13 +1755,7 @@ where { *has_before_variable = true; - Ok(Some(ComponentValue::Function( - self.with_ctx(Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - ))) + Ok(Some(ComponentValue::Function(self.parse()?))) } _ => fallback(self, *has_before_variable), } @@ -2564,13 +2385,7 @@ where } // Token::Function { value, .. } if value.as_ref().eq_ignore_ascii_case("device-cmyk") => { - Ok(Color::Function( - self.with_ctx(Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - )) + Ok(Color::Function(self.parse()?)) } // _ => match self.parse() { @@ -2611,13 +2426,7 @@ where Ok(AbsoluteColorBase::NamedColorOrTransparent(self.parse()?)) } Token::Function { value, .. } if is_absolute_color_base_function(value) => { - Ok(AbsoluteColorBase::Function( - self.with_ctx(Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - )) + Ok(AbsoluteColorBase::Function(self.parse()?)) } _ => { return Err(Error::new( @@ -2728,13 +2537,7 @@ where return Err(Error::new(span, ErrorKind::Expected("math function token"))); } - Ok(CmykComponent::Function( - self.with_ctx(Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - )) + Ok(CmykComponent::Function(self.parse()?)) } _ => { unreachable!() @@ -2879,13 +2682,7 @@ where modifiers.push(UrlModifier::Ident(self.parse()?)); } tok!("function") => { - modifiers.push(UrlModifier::Function( - self.with_ctx(Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - )); + modifiers.push(UrlModifier::Function(self.parse()?)); } _ => { let span = self.input.cur_span(); @@ -3522,13 +3319,7 @@ where Ok(CalcValue::Sum(calc_sum_in_parens)) } - tok!("function") => Ok(CalcValue::Function( - self.with_ctx(Ctx { - block_contents_grammar: BlockContentsGrammar::DeclarationValue, - ..self.ctx - }) - .parse_as::()?, - )), + tok!("function") => Ok(CalcValue::Function(self.parse()?)), _ => { let span = self.input.cur_span();