feat(css/parser): Add more error recovery (#2849)

This commit is contained in:
Alexander Akait 2021-11-29 18:26:57 +03:00 committed by GitHub
parent 435faccc2e
commit d7183d82e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 471 additions and 141 deletions

View File

@ -38,8 +38,6 @@ struct Ctx {
disallow_comma_in_media_query: bool,
is_in_delimited_value: bool,
allow_at_selector: bool,
recover_from_property_value: bool,

View File

@ -344,9 +344,7 @@ where
_ => {}
}
if is_one_of!(self, "<!--", "-->")
|| (self.ctx.is_in_delimited_value && is_one_of!(self, "!", ";"))
{
if is_one_of!(self, "<!--", "-->", "!", ";") {
let token = self.input.bump()?.unwrap();
return Ok(Value::Lazy(Tokens {
span,
@ -526,7 +524,6 @@ where
self.input.skip_ws()?;
let ctx = Ctx {
is_in_delimited_value: true,
allow_separating_value_with_space: false,
..self.ctx
};
@ -555,7 +552,6 @@ where
} else {
let ctx = Ctx {
allow_operation_in_value: true,
is_in_delimited_value: true,
..self.ctx
};

View File

@ -0,0 +1,9 @@
.class {
prop: ;
color: red;
}
.class {
prop: !!;
color: red;
}

View File

@ -0,0 +1,318 @@
{
"type": "Stylesheet",
"span": {
"start": 0,
"end": 81,
"ctxt": 0
},
"rules": [
{
"type": "QualifiedRule",
"span": {
"start": 0,
"end": 38,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 0,
"end": 6,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 0,
"end": 6,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 0,
"end": 6,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": null,
"subclassSelectors": [
{
"type": "ClassSelector",
"span": {
"start": 0,
"end": 6,
"ctxt": 0
},
"text": {
"type": "Identifier",
"span": {
"start": 1,
"end": 6,
"ctxt": 0
},
"value": "class",
"raw": "class"
}
}
]
}
]
}
]
},
"block": {
"type": "Block",
"span": {
"start": 7,
"end": 38,
"ctxt": 0
},
"items": [
{
"type": "Declaration",
"span": {
"start": 13,
"end": 30,
"ctxt": 0
},
"property": {
"type": "Identifier",
"span": {
"start": 13,
"end": 17,
"ctxt": 0
},
"value": "prop",
"raw": "prop"
},
"value": [
{
"type": "Tokens",
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"tokens": [
{
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
}
]
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 25,
"end": 35,
"ctxt": 0
},
"property": {
"type": "Identifier",
"span": {
"start": 25,
"end": 30,
"ctxt": 0
},
"value": "color",
"raw": "color"
},
"value": [
{
"type": "Identifier",
"span": {
"start": 32,
"end": 35,
"ctxt": 0
},
"value": "red",
"raw": "red"
}
],
"important": null
}
]
}
},
{
"type": "QualifiedRule",
"span": {
"start": 40,
"end": 80,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 40,
"end": 46,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 40,
"end": 46,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 40,
"end": 46,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": null,
"subclassSelectors": [
{
"type": "ClassSelector",
"span": {
"start": 40,
"end": 46,
"ctxt": 0
},
"text": {
"type": "Identifier",
"span": {
"start": 41,
"end": 46,
"ctxt": 0
},
"value": "class",
"raw": "class"
}
}
]
}
]
}
]
},
"block": {
"type": "Block",
"span": {
"start": 47,
"end": 80,
"ctxt": 0
},
"items": [
{
"type": "Tokens",
"span": {
"start": 53,
"end": 61,
"ctxt": 0
},
"tokens": [
{
"span": {
"start": 53,
"end": 57,
"ctxt": 0
},
"token": {
"Ident": {
"value": "prop",
"raw": "prop"
}
}
},
{
"span": {
"start": 57,
"end": 58,
"ctxt": 0
},
"token": "Colon"
},
{
"span": {
"start": 58,
"end": 59,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"span": {
"start": 59,
"end": 60,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"span": {
"start": 60,
"end": 61,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
}
]
},
{
"type": "Declaration",
"span": {
"start": 67,
"end": 77,
"ctxt": 0
},
"property": {
"type": "Identifier",
"span": {
"start": 67,
"end": 72,
"ctxt": 0
},
"value": "color",
"raw": "color"
},
"value": [
{
"type": "Identifier",
"span": {
"start": 74,
"end": 77,
"ctxt": 0
},
"value": "red",
"raw": "red"
}
],
"important": null
}
]
}
}
]
}

View File

@ -0,0 +1,14 @@
error: Expected a property value
--> $DIR/tests/recovery/declaration/input.css:2:10
|
2 | prop: ;
| ^
error: Expected !important
--> $DIR/tests/recovery/declaration/input.css:7:12
|
7 | prop: !!;
| ____________^
8 | | color: red;
| |____^

View File

@ -1,6 +1,8 @@
error: Expected Declaration value
--> $DIR/tests/recovery/delim-token/bang/input.css:2:12
error: Expected !important
--> $DIR/tests/recovery/delim-token/bang/input.css:2:13
|
2 | color: !!;
| ^
| _____________^
3 | | }
| |_

View File

@ -71,34 +71,31 @@
},
"items": [
{
"type": "Tokens",
"type": "Declaration",
"span": {
"start": 8,
"end": 14,
"end": 24,
"ctxt": 0
},
"tokens": [
{
"property": {
"type": "Identifier",
"span": {
"start": 8,
"end": 12,
"ctxt": 0
},
"token": {
"Ident": {
"value": "prop",
"raw": "prop"
}
}
},
"value": [
{
"type": "Tokens",
"span": {
"start": 12,
"end": 13,
"start": 13,
"end": 14,
"ctxt": 0
},
"token": "Colon"
},
"tokens": [
{
"span": {
"start": 13,
@ -112,36 +109,36 @@
}
}
]
}
],
"important": null
},
{
"type": "Tokens",
"type": "Declaration",
"span": {
"start": 20,
"end": 29,
"end": 39,
"ctxt": 0
},
"tokens": [
{
"property": {
"type": "Identifier",
"span": {
"start": 20,
"end": 24,
"ctxt": 0
},
"token": {
"Ident": {
"value": "prop",
"raw": "prop"
}
}
},
"value": [
{
"type": "Tokens",
"span": {
"start": 24,
"end": 25,
"start": 25,
"end": 29,
"ctxt": 0
},
"token": "Colon"
},
"tokens": [
{
"span": {
"start": 25,
@ -155,36 +152,36 @@
}
}
]
}
],
"important": null
},
{
"type": "Tokens",
"type": "Declaration",
"span": {
"start": 35,
"end": 42,
"end": 52,
"ctxt": 0
},
"tokens": [
{
"property": {
"type": "Identifier",
"span": {
"start": 35,
"end": 39,
"ctxt": 0
},
"token": {
"Ident": {
"value": "prop",
"raw": "prop"
}
}
},
"value": [
{
"type": "Tokens",
"span": {
"start": 39,
"end": 40,
"start": 40,
"end": 42,
"ctxt": 0
},
"token": "Colon"
},
"tokens": [
{
"span": {
"start": 40,
@ -198,50 +195,49 @@
}
}
]
}
],
"important": null
},
{
"type": "Tokens",
"type": "Declaration",
"span": {
"start": 48,
"end": 63,
"end": 64,
"ctxt": 0
},
"tokens": [
{
"property": {
"type": "Identifier",
"span": {
"start": 48,
"end": 52,
"ctxt": 0
},
"token": {
"Ident": {
"value": "prop",
"raw": "prop"
}
}
},
"value": [
{
"type": "Tokens",
"span": {
"start": 52,
"end": 53,
"start": 63,
"end": 64,
"ctxt": 0
},
"token": "Colon"
},
"tokens": [
{
"span": {
"start": 53,
"end": 63,
"start": 63,
"end": 64,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " \n\n "
}
}
"token": "Semi"
}
]
}
],
"important": null
}
]
}
}

View File

@ -1,24 +1,21 @@
error: Expected Declaration value
--> $DIR/tests/recovery/whitespaces/input.css:2:11
error: Expected a property value
--> $DIR/tests/recovery/whitespaces/input.css:2:10
|
2 | prop: ;
| ^
error: Expected Declaration value
--> $DIR/tests/recovery/whitespaces/input.css:3:14
error: Expected a property value
--> $DIR/tests/recovery/whitespaces/input.css:3:10
|
3 | prop: ;
| ^
| ^^^^
error: Expected Declaration value
--> $DIR/tests/recovery/whitespaces/input.css:6:1
error: Expected a property value
--> $DIR/tests/recovery/whitespaces/input.css:4:10
|
6 | ;
| ^
error: Expected Declaration value
--> $DIR/tests/recovery/whitespaces/input.css:9:5
|
9 | ;
| ^
4 | prop:
| __________^
5 | |
6 | | ;
| |_