Skip to content

Commit

Permalink
fix(css/parser): Fix parsing of <general-enclosed> (#6380)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Nov 10, 2022
1 parent 4035f59 commit d18eaf1
Show file tree
Hide file tree
Showing 31 changed files with 2,995 additions and 49 deletions.

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

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

Expand Up @@ -45,7 +45,7 @@ div {
background: url('\"foo\"');
}
.bar {
background: url(http://example.com/image.svg param(--color var(--primary-color);
background: url(http://example.com/image.svg param(--color var(--primary-color)));
}
.baz {
background: url("http://example.com/image.svg" param(--color var(--primary-color)));
Expand Down

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

45 changes: 33 additions & 12 deletions crates/swc_css_parser/src/parser/at_rules/mod.rs
Expand Up @@ -1170,13 +1170,21 @@ where

self.input.skip_ws();

let declaration = self.parse()?;
let declaration = match self.try_to_parse_declaration_in_parens() {
Some(declaration) => declaration,
None => {
let span = self.input.cur_span();

self.input.skip_ws();
return Err(Error::new(
span,
ErrorKind::Expected("declaration in parens"),
));
}
};

expect!(self, ")");

Ok(SupportsFeature::Declaration(declaration))
Ok(SupportsFeature::Declaration(Box::new(declaration)))
}
Token::Function { value, .. } if &*value.to_ascii_lowercase() == "selector" => {
// TODO improve me
Expand Down Expand Up @@ -1219,16 +1227,25 @@ where
tok!("(") => {
let block = self.parse_as::<SimpleBlock>()?;

if let Some(first) = block.value.get(0) {
match first {
let mut found_ident = false;

for component_value in &block.value {
match component_value {
ComponentValue::PreservedToken(token_and_span) => {
match token_and_span.token {
Token::Ident { .. } => {}
Token::WhiteSpace { .. } => {
continue;
}
Token::Ident { .. } => {
found_ident = true;

break;
}
_ => {
return Err(Error::new(
block.span,
ErrorKind::Expected(
"ident token at first position in <general-enclosed>",
"ident at first position in <general-enclosed>",
),
));
}
Expand All @@ -1238,22 +1255,26 @@ where
return Err(Error::new(
block.span,
ErrorKind::Expected(
"ident token at first position in <general-enclosed>",
"ident at first position in <general-enclosed>",
),
));
}
}
}

if !found_ident {
return Err(Error::new(
block.span,
ErrorKind::Expected("ident at first position in <general-enclosed>"),
));
}

Ok(GeneralEnclosed::SimpleBlock(block))
}
_ => {
let span = self.input.cur_span();

Err(Error::new(
span,
ErrorKind::Expected("function or '(' token"),
))
Err(Error::new(span, ErrorKind::Expected("function or '('")))
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions crates/swc_css_parser/src/parser/syntax/mod.rs
Expand Up @@ -752,8 +752,7 @@ where
let mut important_ident = None;

loop {
// TODO fix me `)`, workaround
if is_one_of!(self, EOF, ")") {
if is_one_of!(self, EOF) {
if important_ident.is_none() {
if let Some(span) = &exclamation_point_span {
// TODO improve me to `<declaration-value>`
Expand Down
25 changes: 24 additions & 1 deletion crates/swc_css_parser/src/parser/util.rs
Expand Up @@ -5,7 +5,7 @@ use swc_css_ast::*;

use super::{
input::{Input, InputType, ParserInput},
Ctx, PResult, Parse, Parser,
Ctx, Error, PResult, Parse, Parser,
};

impl<I> Parser<I>
Expand Down Expand Up @@ -91,6 +91,29 @@ where
}
}
}

pub(super) fn try_to_parse_declaration_in_parens(&mut self) -> Option<Declaration> {
let mut temporary_list = ListOfComponentValues {
span: Default::default(),
children: vec![],
};

while !is_one_of!(self, ")", EOF) {
let component_value = match self.parse_as::<ComponentValue>() {
Ok(component_value) => component_value,
Err(_) => return None,
};

temporary_list.children.push(component_value);
}

match self
.parse_according_to_grammar::<Declaration>(&temporary_list, |parser| parser.parse_as())
{
Ok(decl) => Some(decl),
Err(_) => None,
}
}
}

pub(super) struct WithCtx<'w, I: 'w + ParserInput> {
Expand Down
3 changes: 3 additions & 0 deletions crates/swc_css_parser/tests/fixture/at-rule/import/input.css
Expand Up @@ -163,6 +163,9 @@ st.css');
@import url("fallback-layout.css") supports(not (display: flex));
@import url("narrow.css") supports(display: flex) screen and (max-width: 400px);

@import "test.css" supports( display: flex );
@import url("tabs.css") layer( framework.component );

/*.foo {*/
/* @import 'path.css';*/
/*}*/
207 changes: 206 additions & 1 deletion crates/swc_css_parser/tests/fixture/at-rule/import/output.json
Expand Up @@ -2,7 +2,7 @@
"type": "Stylesheet",
"span": {
"start": 1,
"end": 6482,
"end": 6591,
"ctxt": 0
},
"rules": [
Expand Down Expand Up @@ -12108,6 +12108,211 @@
}
},
"block": null
},
{
"type": "AtRule",
"span": {
"start": 6437,
"end": 6486,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 6438,
"end": 6444,
"ctxt": 0
},
"value": "import",
"raw": "import"
},
"prelude": {
"type": "ImportPrelude",
"span": {
"start": 6445,
"end": 6485,
"ctxt": 0
},
"href": {
"type": "String",
"span": {
"start": 6445,
"end": 6455,
"ctxt": 0
},
"value": "test.css",
"raw": "\"test.css\""
},
"layerName": null,
"importConditions": {
"type": "ImportCondition",
"span": {
"start": 6456,
"end": 6485,
"ctxt": 0
},
"supports": {
"type": "Function",
"span": {
"start": 6456,
"end": 6485,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 6456,
"end": 6464,
"ctxt": 0
},
"value": "supports",
"raw": "supports"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 6468,
"end": 6484,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 6468,
"end": 6475,
"ctxt": 0
},
"value": "display",
"raw": "display"
},
"value": [
{
"type": "Ident",
"span": {
"start": 6477,
"end": 6481,
"ctxt": 0
},
"value": "flex",
"raw": "flex"
}
],
"important": null
}
]
},
"media": null
}
},
"block": null
},
{
"type": "AtRule",
"span": {
"start": 6487,
"end": 6544,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 6488,
"end": 6494,
"ctxt": 0
},
"value": "import",
"raw": "import"
},
"prelude": {
"type": "ImportPrelude",
"span": {
"start": 6495,
"end": 6543,
"ctxt": 0
},
"href": {
"type": "Url",
"span": {
"start": 6495,
"end": 6510,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 6495,
"end": 6498,
"ctxt": 0
},
"value": "url",
"raw": "url"
},
"value": {
"type": "String",
"span": {
"start": 6499,
"end": 6509,
"ctxt": 0
},
"value": "tabs.css",
"raw": "\"tabs.css\""
},
"modifiers": []
},
"layerName": {
"type": "Function",
"span": {
"start": 6511,
"end": 6543,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 6511,
"end": 6516,
"ctxt": 0
},
"value": "layer",
"raw": "layer"
},
"value": [
{
"type": "LayerName",
"span": {
"start": 6520,
"end": 6539,
"ctxt": 0
},
"name": [
{
"type": "Ident",
"span": {
"start": 6520,
"end": 6529,
"ctxt": 0
},
"value": "framework",
"raw": "framework"
},
{
"type": "Ident",
"span": {
"start": 6530,
"end": 6539,
"ctxt": 0
},
"value": "component",
"raw": "component"
}
]
}
]
},
"importConditions": null
},
"block": null
}
]
}

1 comment on commit d18eaf1

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: d18eaf1 Previous: 56bc6b8 Ratio
es/full/bugs-1 334181 ns/iter (± 15353) 339604 ns/iter (± 16170) 0.98
es/full/minify/libraries/antd 1807295703 ns/iter (± 21529114) 1847726848 ns/iter (± 33506580) 0.98
es/full/minify/libraries/d3 382890604 ns/iter (± 9854715) 403013520 ns/iter (± 11894131) 0.95
es/full/minify/libraries/echarts 1550281151 ns/iter (± 23966487) 1589588769 ns/iter (± 19827934) 0.98
es/full/minify/libraries/jquery 99932496 ns/iter (± 2276596) 104512993 ns/iter (± 2689574) 0.96
es/full/minify/libraries/lodash 117077439 ns/iter (± 2074099) 121063417 ns/iter (± 3582786) 0.97
es/full/minify/libraries/moment 58081688 ns/iter (± 2549229) 60809416 ns/iter (± 2173186) 0.96
es/full/minify/libraries/react 19557835 ns/iter (± 615187) 20359757 ns/iter (± 573397) 0.96
es/full/minify/libraries/terser 288601151 ns/iter (± 5792842) 322970445 ns/iter (± 12428067) 0.89
es/full/minify/libraries/three 553874125 ns/iter (± 10510840) 571516513 ns/iter (± 15390451) 0.97
es/full/minify/libraries/typescript 3281984699 ns/iter (± 25632573) 3422833647 ns/iter (± 42640539) 0.96
es/full/minify/libraries/victory 802044392 ns/iter (± 13010396) 852205860 ns/iter (± 15830745) 0.94
es/full/minify/libraries/vue 147742953 ns/iter (± 4117084) 171873400 ns/iter (± 4943533) 0.86
es/full/codegen/es3 33105 ns/iter (± 1351) 34736 ns/iter (± 1240) 0.95
es/full/codegen/es5 33177 ns/iter (± 1126) 33801 ns/iter (± 1095) 0.98
es/full/codegen/es2015 32533 ns/iter (± 1212) 33818 ns/iter (± 3364) 0.96
es/full/codegen/es2016 33070 ns/iter (± 1734) 34384 ns/iter (± 1081) 0.96
es/full/codegen/es2017 33716 ns/iter (± 2226) 34272 ns/iter (± 1263) 0.98
es/full/codegen/es2018 33377 ns/iter (± 1765) 34274 ns/iter (± 1330) 0.97
es/full/codegen/es2019 33005 ns/iter (± 1832) 33560 ns/iter (± 1274) 0.98
es/full/codegen/es2020 33190 ns/iter (± 1469) 33570 ns/iter (± 950) 0.99
es/full/all/es3 188045310 ns/iter (± 6391223) 204574369 ns/iter (± 12820859) 0.92
es/full/all/es5 176610975 ns/iter (± 2633082) 190353588 ns/iter (± 12138313) 0.93
es/full/all/es2015 142850347 ns/iter (± 3516065) 149702186 ns/iter (± 9273478) 0.95
es/full/all/es2016 141708330 ns/iter (± 3608177) 149885499 ns/iter (± 7519214) 0.95
es/full/all/es2017 140653438 ns/iter (± 3723585) 148730928 ns/iter (± 7866854) 0.95
es/full/all/es2018 138564185 ns/iter (± 2206919) 145720852 ns/iter (± 7782054) 0.95
es/full/all/es2019 138434246 ns/iter (± 2987167) 145288555 ns/iter (± 7755768) 0.95
es/full/all/es2020 134636859 ns/iter (± 4748122) 139120267 ns/iter (± 7578809) 0.97
es/full/parser 693984 ns/iter (± 26613) 725566 ns/iter (± 29837) 0.96
es/full/base/fixer 25926 ns/iter (± 1259) 26640 ns/iter (± 1643) 0.97
es/full/base/resolver_and_hygiene 88318 ns/iter (± 2941) 92397 ns/iter (± 11222) 0.96
serialization of ast node 213 ns/iter (± 7) 214 ns/iter (± 5) 1.00
serialization of serde 212 ns/iter (± 8) 214 ns/iter (± 4) 0.99

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.