diff --git a/crates/swc_css_parser/src/parser/base.rs b/crates/swc_css_parser/src/parser/base.rs index 9eef30ca032..38bc22c8ccf 100644 --- a/crates/swc_css_parser/src/parser/base.rs +++ b/crates/swc_css_parser/src/parser/base.rs @@ -373,7 +373,10 @@ where '[' } _ => { - unreachable!(); + return Err(Error::new( + span, + ErrorKind::Expected("'{', '(' or '[' token"), + )); } }; // Create a simple block with its associated token set to the current input diff --git a/crates/swc_css_parser/tests/recovery/at-rule/font-face/input.css b/crates/swc_css_parser/tests/recovery/at-rule/font-face/input.css new file mode 100644 index 00000000000..990dbb11ce7 --- /dev/null +++ b/crates/swc_css_parser/tests/recovery/at-rule/font-face/input.css @@ -0,0 +1,21 @@ +@font-face { + invalid +} + +@font-face { + invalid; +} + +@font-face { + 123 +} + +@font-face { + 123; +} + +@font-face foo {} + +@font-face foo; + +@font-face ; diff --git a/crates/swc_css_parser/tests/recovery/at-rule/font-face/output.json b/crates/swc_css_parser/tests/recovery/at-rule/font-face/output.json new file mode 100644 index 00000000000..7312aa7e911 --- /dev/null +++ b/crates/swc_css_parser/tests/recovery/at-rule/font-face/output.json @@ -0,0 +1,380 @@ +{ + "type": "Stylesheet", + "span": { + "start": 0, + "end": 155, + "ctxt": 0 + }, + "rules": [ + { + "type": "FontFaceRule", + "span": { + "start": 0, + "end": 26, + "ctxt": 0 + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 11, + "end": 26, + "ctxt": 0 + }, + "name": "{", + "value": [ + { + "type": "Tokens", + "span": { + "start": 17, + "end": 25, + "ctxt": 0 + }, + "tokens": [ + { + "type": "PreservedToken", + "span": { + "start": 17, + "end": 24, + "ctxt": 0 + }, + "token": { + "Ident": { + "value": "invalid", + "raw": "invalid" + } + } + }, + { + "type": "PreservedToken", + "span": { + "start": 24, + "end": 25, + "ctxt": 0 + }, + "token": { + "WhiteSpace": { + "value": "\n" + } + } + } + ] + } + ] + } + }, + { + "type": "FontFaceRule", + "span": { + "start": 28, + "end": 55, + "ctxt": 0 + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 39, + "end": 55, + "ctxt": 0 + }, + "name": "{", + "value": [ + { + "type": "Tokens", + "span": { + "start": 45, + "end": 53, + "ctxt": 0 + }, + "tokens": [ + { + "type": "PreservedToken", + "span": { + "start": 45, + "end": 52, + "ctxt": 0 + }, + "token": { + "Ident": { + "value": "invalid", + "raw": "invalid" + } + } + }, + { + "type": "PreservedToken", + "span": { + "start": 52, + "end": 53, + "ctxt": 0 + }, + "token": "Semi" + } + ] + } + ] + } + }, + { + "type": "FontFaceRule", + "span": { + "start": 57, + "end": 79, + "ctxt": 0 + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 68, + "end": 79, + "ctxt": 0 + }, + "name": "{", + "value": [ + { + "type": "Tokens", + "span": { + "start": 74, + "end": 78, + "ctxt": 0 + }, + "tokens": [ + { + "type": "PreservedToken", + "span": { + "start": 74, + "end": 77, + "ctxt": 0 + }, + "token": { + "Number": { + "value": 123.0, + "raw": "123", + "type": "integer" + } + } + }, + { + "type": "PreservedToken", + "span": { + "start": 77, + "end": 78, + "ctxt": 0 + }, + "token": { + "WhiteSpace": { + "value": "\n" + } + } + } + ] + } + ] + } + }, + { + "type": "FontFaceRule", + "span": { + "start": 81, + "end": 104, + "ctxt": 0 + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 92, + "end": 104, + "ctxt": 0 + }, + "name": "{", + "value": [ + { + "type": "Tokens", + "span": { + "start": 98, + "end": 102, + "ctxt": 0 + }, + "tokens": [ + { + "type": "PreservedToken", + "span": { + "start": 98, + "end": 101, + "ctxt": 0 + }, + "token": { + "Number": { + "value": 123.0, + "raw": "123", + "type": "integer" + } + } + }, + { + "type": "PreservedToken", + "span": { + "start": 101, + "end": 102, + "ctxt": 0 + }, + "token": "Semi" + } + ] + } + ] + } + }, + { + "type": "UnknownAtRule", + "span": { + "start": 106, + "end": 123, + "ctxt": 0 + }, + "name": { + "type": "Ident", + "span": { + "start": 107, + "end": 116, + "ctxt": 0 + }, + "value": "font-face", + "raw": "font-face" + }, + "prelude": [ + { + "type": "PreservedToken", + "span": { + "start": 116, + "end": 117, + "ctxt": 0 + }, + "token": { + "WhiteSpace": { + "value": " " + } + } + }, + { + "type": "PreservedToken", + "span": { + "start": 117, + "end": 120, + "ctxt": 0 + }, + "token": { + "Ident": { + "value": "foo", + "raw": "foo" + } + } + }, + { + "type": "PreservedToken", + "span": { + "start": 120, + "end": 121, + "ctxt": 0 + }, + "token": { + "WhiteSpace": { + "value": " " + } + } + } + ], + "block": { + "type": "SimpleBlock", + "span": { + "start": 121, + "end": 123, + "ctxt": 0 + }, + "name": "{", + "value": [] + } + }, + { + "type": "UnknownAtRule", + "span": { + "start": 125, + "end": 140, + "ctxt": 0 + }, + "name": { + "type": "Ident", + "span": { + "start": 126, + "end": 135, + "ctxt": 0 + }, + "value": "font-face", + "raw": "font-face" + }, + "prelude": [ + { + "type": "PreservedToken", + "span": { + "start": 135, + "end": 136, + "ctxt": 0 + }, + "token": { + "WhiteSpace": { + "value": " " + } + } + }, + { + "type": "PreservedToken", + "span": { + "start": 136, + "end": 139, + "ctxt": 0 + }, + "token": { + "Ident": { + "value": "foo", + "raw": "foo" + } + } + } + ], + "block": null + }, + { + "type": "UnknownAtRule", + "span": { + "start": 142, + "end": 154, + "ctxt": 0 + }, + "name": { + "type": "Ident", + "span": { + "start": 143, + "end": 152, + "ctxt": 0 + }, + "value": "font-face", + "raw": "font-face" + }, + "prelude": [ + { + "type": "PreservedToken", + "span": { + "start": 152, + "end": 153, + "ctxt": 0 + }, + "token": { + "WhiteSpace": { + "value": " " + } + } + } + ], + "block": null + } + ] +} diff --git a/crates/swc_css_parser/tests/recovery/at-rule/font-face/output.swc-stderr b/crates/swc_css_parser/tests/recovery/at-rule/font-face/output.swc-stderr new file mode 100644 index 00000000000..8d9d7b6564e --- /dev/null +++ b/crates/swc_css_parser/tests/recovery/at-rule/font-face/output.swc-stderr @@ -0,0 +1,42 @@ +error: Expected ":" + --> $DIR/tests/recovery/at-rule/font-face/input.css:3:1 + | +3 | } + | ^ + +error: Expected ":" + --> $DIR/tests/recovery/at-rule/font-face/input.css:6:12 + | +6 | invalid; + | ^ + +error: Expected whitespace, semicolon, EOF, at-keyword or ident token + --> $DIR/tests/recovery/at-rule/font-face/input.css:10:5 + | +10 | 123 + | ^^^ + +error: Expected whitespace, semicolon, EOF, at-keyword or ident token + --> $DIR/tests/recovery/at-rule/font-face/input.css:14:5 + | +14 | 123; + | ^^^ + +error: Expected '{', '(' or '[' token + --> $DIR/tests/recovery/at-rule/font-face/input.css:17:12 + | +17 | @font-face foo {} + | ^^^ + +error: Expected '{', '(' or '[' token + --> $DIR/tests/recovery/at-rule/font-face/input.css:19:12 + | +19 | @font-face foo; + | ^^^ + +error: Expected '{', '(' or '[' token + --> $DIR/tests/recovery/at-rule/font-face/input.css:21:12 + | +21 | @font-face ; + | ^ +