fix(css/parser): Fix recovery more for invalid component values in declaration value (#6560)

This commit is contained in:
Alexander Akait 2022-12-01 09:26:47 +03:00 committed by GitHub
parent 9a4fe8913e
commit db1eb483fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 3616 additions and 558 deletions

View File

@ -166,16 +166,4 @@ macro_rules! tok {
(">") => {
swc_css_ast::Token::Delim { value: '>', .. }
};
("important") => {
ident_tok!("important")
};
("local") => {
ident_tok!("local")
};
("global") => {
ident_tok!("global")
};
}

View File

@ -623,53 +623,39 @@ where
// 5. As long as the next input token is anything other than an <EOF-token>,
// consume a component value and append it to the declarations value.
let mut is_valid_to_canonicalize = true;
let mut last_whitespaces = (0, 0, 0);
let mut exclamation_point_span = None;
let mut important_ident = None;
loop {
if is_one_of!(self, EOF) {
if important_ident.is_none() {
if let Some(span) = &exclamation_point_span {
// TODO improve me to `<declaration-value>`
self.errors.push(Error::new(
*span,
ErrorKind::Unexpected("'!' in <declaration-value>"),
));
}
}
if is!(self, EOF) {
break;
}
let component_value = self.parse_as::<ComponentValue>()?;
match &component_value {
// Optimization for step 5
ComponentValue::PreservedToken(
token_and_span @ TokenAndSpan {
token: Token::Ident { value, .. },
..
},
) if exclamation_point_span.is_some()
&& value.to_ascii_lowercase() == js_word!("important") =>
{
important_ident = Some(token_and_span.clone());
}
// Optimization for step 6
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::Delim { value: '!', .. },
..
}) => {
exclamation_point_span = Some(*span);
}) if is!(self, " ") || is_case_insensitive_ident!(self, "important") => {
if let Some(span) = &exclamation_point_span {
is_valid_to_canonicalize = false;
self.errors.push(Error::new(
*span,
ErrorKind::Unexpected("'!' in declaration value"),
));
if important_ident.is_some() {
important_ident = None;
last_whitespaces = (last_whitespaces.2, 0, 0);
}
exclamation_point_span = Some(*span);
}
// Optimization for step 6
ComponentValue::PreservedToken(TokenAndSpan {
token: Token::WhiteSpace { .. },
..
@ -687,14 +673,31 @@ where
unreachable!();
}
},
ComponentValue::PreservedToken(
token_and_span @ TokenAndSpan {
token: Token::Ident { value, .. },
..
},
) if exclamation_point_span.is_some()
&& value.to_ascii_lowercase() == js_word!("important") =>
{
important_ident = Some(token_and_span.clone());
}
_ => {
if let Err(err) = self.validate_declaration_value(&component_value) {
is_valid_to_canonicalize = false;
self.errors.push(err);
}
last_whitespaces = (0, 0, 0);
if let Some(span) = &exclamation_point_span {
// TODO improve me to `<declaration-value>`
is_valid_to_canonicalize = false;
self.errors.push(Error::new(
*span,
ErrorKind::Unexpected("'!' in <declaration-value>"),
ErrorKind::Unexpected("'!' in declaration value"),
));
important_ident = None;
@ -755,7 +758,7 @@ where
}
// Canonicalization against a grammar
if self.ctx.need_canonicalize {
if is_valid_to_canonicalize && self.ctx.need_canonicalize {
declaration = self.canonicalize_declaration_value(declaration)?;
}

View File

@ -367,6 +367,85 @@ where
) -> PResult<Declaration> {
self.parse_according_to_grammar::<Declaration>(temporary_list, |parser| parser.parse_as())
}
// The <declaration-value> production matches any sequence of one or more
// tokens, so long as the sequence does not contain <bad-string-token>,
// <bad-url-token>, unmatched <)-token>, <]-token>, or <}-token>, or top-level
// <semicolon-token> tokens or <delim-token> tokens with a value of "!". It
// represents the entirety of what a valid declaration can have as its value.
pub(super) fn validate_declaration_value(
&mut self,
component_value: &ComponentValue,
) -> PResult<()> {
match component_value {
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::BadString { .. },
}) => {
return Err(Error::new(
*span,
ErrorKind::Unexpected("bad string in declaration value"),
));
}
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::BadUrl { .. },
}) => {
return Err(Error::new(
*span,
ErrorKind::Unexpected("bad url in declaration value"),
));
}
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::RParen,
}) => {
return Err(Error::new(
*span,
ErrorKind::Unexpected("')' in declaration value"),
));
}
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::RBracket,
}) => {
return Err(Error::new(
*span,
ErrorKind::Unexpected("']' in declaration value"),
));
}
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::RBrace,
}) => {
return Err(Error::new(
*span,
ErrorKind::Unexpected("'}' in declaration value"),
));
}
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::Semi,
}) => {
return Err(Error::new(
*span,
ErrorKind::Unexpected("';' in declaration value"),
));
}
ComponentValue::PreservedToken(TokenAndSpan {
span,
token: Token::Delim { value: '!' },
}) => {
return Err(Error::new(
*span,
ErrorKind::Unexpected("'!' in declaration value"),
));
}
_ => {}
}
Ok(())
}
}
pub(super) struct WithCtx<'w, I: 'w + ParserInput> {

View File

@ -116,84 +116,6 @@ where
Err(Error::new(span, ErrorKind::Expected("Declaration value")))
}
/// Parse value as <declaration-value>.
// pub(super) fn validate_declaration_value(&mut self) -> PResult<Vec<ComponentValue>> {
// let mut value = vec![];
// let mut balance_stack: Vec<Option<char>> = vec![];
//
// // The <declaration-value> production matches any sequence of one or more
// // tokens, so long as the sequence does not contain ...
// loop {
// if is!(self, EOF) {
// break;
// }
//
// match cur!(self) {
// // ... <bad-string-token>, <bad-url-token>,
// tok!("bad-string") | tok!("bad-url") => { break; },
//
// // ... unmatched <)-token>, <]-token>, or <}-token>,
// tok!(")") | tok!("]") | tok!("}") => {
// let value = match cur!(self) {
// tok!(")") => ')',
// tok!("]") => ']',
// tok!("}") => '}',
// _ => {
// unreachable!();
// }
// };
//
// let balance_close_type = match balance_stack.pop() {
// Some(v) => v,
// None => None,
// };
//
// if Some(value) != balance_close_type {
// break;
// }
// }
//
// tok!("function") | tok!("(") | tok!("[") | tok!("{") => {
// let value = match cur!(self) {
// tok!("function") | tok!("(") => ')',
// tok!("[") => ']',
// tok!("{") => '}',
// _ => {
// unreachable!();
// }
// };
//
// balance_stack.push(Some(value));
// }
//
// // ... or top-level <semicolon-token> tokens
// tok!(";") => {
// if balance_stack.is_empty() {
// break;
// }
// }
//
// // ... or <delim-token> tokens with a value of "!"
// tok!("!") => {
// if balance_stack.is_empty() {
// break;
// }
// }
//
// _ => {}
// }
//
// let token = self.input.bump();
//
// match token {
// Some(token) => value.push(ComponentValue::PreservedToken(token)),
// None => break,
// }
// }
//
// Ok(value)
// }
/// Parse value as <any-value>.
pub(super) fn parse_any_value(&mut self) -> PResult<Vec<TokenAndSpan>> {
let mut tokens = vec![];

View File

@ -587,7 +587,6 @@ fn span_visualizer_line_comment(input: PathBuf) {
"at-rule/page/without-page/input.css",
"function/calc/division/input.css",
"function/var/input.css",
"qualified-rule/only-block/input.css",
"whitespaces/input.css",
)
)]

View File

@ -22,6 +22,9 @@ div {
prop: center / 1em;
c\olor: red;
prop/**/: big;
prop: (;);
prop: [;];
prop: {;};
}
a { color: a/* ; */ b ; }

View File

@ -2,7 +2,7 @@
"type": "Stylesheet",
"span": {
"start": 1,
"end": 614,
"end": 659,
"ctxt": 0
},
"rules": [
@ -10,7 +10,7 @@
"type": "QualifiedRule",
"span": {
"start": 1,
"end": 535,
"end": 580,
"ctxt": 0
},
"prelude": {
@ -74,7 +74,7 @@
"type": "SimpleBlock",
"span": {
"start": 5,
"end": 535,
"end": 580,
"ctxt": 0
},
"name": {
@ -1388,6 +1388,153 @@
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 538,
"end": 547,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 538,
"end": 542,
"ctxt": 0
},
"value": "prop",
"raw": "prop"
},
"value": [
{
"type": "SimpleBlock",
"span": {
"start": 544,
"end": 547,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 544,
"end": 545,
"ctxt": 0
},
"token": "LParen"
},
"value": [
{
"type": "Delimiter",
"span": {
"start": 545,
"end": 546,
"ctxt": 0
},
"value": ";"
}
]
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 553,
"end": 562,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 553,
"end": 557,
"ctxt": 0
},
"value": "prop",
"raw": "prop"
},
"value": [
{
"type": "SimpleBlock",
"span": {
"start": 559,
"end": 562,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 559,
"end": 560,
"ctxt": 0
},
"token": "LBracket"
},
"value": [
{
"type": "Delimiter",
"span": {
"start": 560,
"end": 561,
"ctxt": 0
},
"value": ";"
}
]
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 568,
"end": 577,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 568,
"end": 572,
"ctxt": 0
},
"value": "prop",
"raw": "prop"
},
"value": [
{
"type": "SimpleBlock",
"span": {
"start": 574,
"end": 577,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 574,
"end": 575,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Delimiter",
"span": {
"start": 575,
"end": 576,
"ctxt": 0
},
"value": ";"
}
]
}
],
"important": null
}
]
}
@ -1395,54 +1542,54 @@
{
"type": "QualifiedRule",
"span": {
"start": 537,
"end": 563,
"start": 582,
"end": 608,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 537,
"end": 538,
"start": 582,
"end": 583,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 537,
"end": 538,
"start": 582,
"end": 583,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 537,
"end": 538,
"start": 582,
"end": 583,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 537,
"end": 538,
"start": 582,
"end": 583,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 537,
"end": 538,
"start": 582,
"end": 583,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 537,
"end": 538,
"start": 582,
"end": 583,
"ctxt": 0
},
"value": "a",
@ -1459,15 +1606,15 @@
"block": {
"type": "SimpleBlock",
"span": {
"start": 539,
"end": 563,
"start": 584,
"end": 608,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 539,
"end": 540,
"start": 584,
"end": 585,
"ctxt": 0
},
"token": "LBrace"
@ -1476,15 +1623,15 @@
{
"type": "Declaration",
"span": {
"start": 541,
"end": 560,
"start": 586,
"end": 605,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 541,
"end": 546,
"start": 586,
"end": 591,
"ctxt": 0
},
"value": "color",
@ -1494,8 +1641,8 @@
{
"type": "Ident",
"span": {
"start": 548,
"end": 549,
"start": 593,
"end": 594,
"ctxt": 0
},
"value": "a",
@ -1504,8 +1651,8 @@
{
"type": "Ident",
"span": {
"start": 557,
"end": 558,
"start": 602,
"end": 603,
"ctxt": 0
},
"value": "b",
@ -1520,54 +1667,54 @@
{
"type": "QualifiedRule",
"span": {
"start": 564,
"end": 578,
"start": 609,
"end": 623,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 564,
"end": 565,
"start": 609,
"end": 610,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 564,
"end": 565,
"start": 609,
"end": 610,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 564,
"end": 565,
"start": 609,
"end": 610,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 564,
"end": 565,
"start": 609,
"end": 610,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 564,
"end": 565,
"start": 609,
"end": 610,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 564,
"end": 565,
"start": 609,
"end": 610,
"ctxt": 0
},
"value": "a",
@ -1584,15 +1731,15 @@
"block": {
"type": "SimpleBlock",
"span": {
"start": 565,
"end": 578,
"start": 610,
"end": 623,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 565,
"end": 566,
"start": 610,
"end": 611,
"ctxt": 0
},
"token": "LBrace"
@ -1601,15 +1748,15 @@
{
"type": "Declaration",
"span": {
"start": 566,
"end": 577,
"start": 611,
"end": 622,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 566,
"end": 571,
"start": 611,
"end": 616,
"ctxt": 0
},
"value": "color",
@ -1619,8 +1766,8 @@
{
"type": "Ident",
"span": {
"start": 572,
"end": 577,
"start": 617,
"end": 622,
"ctxt": 0
},
"value": "black",
@ -1635,54 +1782,54 @@
{
"type": "QualifiedRule",
"span": {
"start": 580,
"end": 613,
"start": 625,
"end": 658,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 580,
"end": 581,
"start": 625,
"end": 626,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 580,
"end": 581,
"start": 625,
"end": 626,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 580,
"end": 581,
"start": 625,
"end": 626,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 580,
"end": 581,
"start": 625,
"end": 626,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 580,
"end": 581,
"start": 625,
"end": 626,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 580,
"end": 581,
"start": 625,
"end": 626,
"ctxt": 0
},
"value": "a",
@ -1699,15 +1846,15 @@
"block": {
"type": "SimpleBlock",
"span": {
"start": 582,
"end": 613,
"start": 627,
"end": 658,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 582,
"end": 583,
"start": 627,
"end": 628,
"ctxt": 0
},
"token": "LBrace"
@ -1716,15 +1863,15 @@
{
"type": "Declaration",
"span": {
"start": 590,
"end": 602,
"start": 635,
"end": 647,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 590,
"end": 595,
"start": 635,
"end": 640,
"ctxt": 0
},
"value": "color",
@ -1734,8 +1881,8 @@
{
"type": "Ident",
"span": {
"start": 597,
"end": 602,
"start": 642,
"end": 647,
"ctxt": 0
},
"value": "black",

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/bad-url-token/double-quotes/input.css:1:1]
1 | div {
2 | background: url(image".png);

View File

@ -7,7 +7,7 @@
3 | );
`----
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/bad-url-token/invalid-escape/input.css:1:1]
1 | div {
2 | ,-> background: url(image.png\

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/bad-url-token/left-parenthesis/input.css:1:1]
1 | div {
2 | background: url(image(.png);

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/bad-url-token/single-quotes/input.css:1:1]
1 | div {
2 | background: url(image'.png);

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/bad-url-token/whitespace-in-middle/input.css:1:1]
1 | a {
2 | background-image: url( ./image.jpg a );

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/bad-url-token/whitespace/input.css:1:1]
1 | div {
2 | ,-> background: url(image.

View File

@ -0,0 +1,3 @@
a {
--var: [;
}

View File

@ -0,0 +1,165 @@
{
"type": "Stylesheet",
"span": {
"start": 1,
"end": 20,
"ctxt": 0
},
"rules": [
{
"type": "QualifiedRule",
"span": {
"start": 1,
"end": 20,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 3,
"end": 20,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 3,
"end": 4,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 9,
"end": 20,
"ctxt": 0
},
"name": {
"type": "DashedIdent",
"span": {
"start": 9,
"end": 14,
"ctxt": 0
},
"value": "var",
"raw": "--var"
},
"value": [
{
"type": "SimpleBlock",
"span": {
"start": 16,
"end": 20,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 16,
"end": 17,
"ctxt": 0
},
"token": "LBracket"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 17,
"end": 18,
"ctxt": 0
},
"token": "Semi"
},
{
"type": "PreservedToken",
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": "\n"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 19,
"end": 20,
"ctxt": 0
},
"token": "RBrace"
}
]
}
],
"important": null
}
]
}
}
]
}

View File

@ -0,0 +1,14 @@
x Unexpected end of file, but expected ']'
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | ,-> --var: [;
3 | `-> }
`----
x Unexpected end of file, but expected '}'
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | ,-> a {
2 | | --var: [;
3 | `-> }
`----

View File

@ -0,0 +1,189 @@
x Stylesheet
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | ,-> a {
2 | | --var: [;
3 | `-> }
`----
x Rule
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | ,-> a {
2 | | --var: [;
3 | `-> }
`----
x QualifiedRule
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | ,-> a {
2 | | --var: [;
3 | `-> }
`----
x SelectorList
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x ComplexSelector
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x CompoundSelector
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x TypeSelector
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x TagNameSelector
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x WqName
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x Ident
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x SimpleBlock
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | ,-> a {
2 | | --var: [;
3 | `-> }
`----
x LBrace
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
: ^
2 | --var: [;
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | ,-> --var: [;
3 | `-> }
`----
x StyleBlock
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | ,-> --var: [;
3 | `-> }
`----
x Declaration
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | ,-> --var: [;
3 | `-> }
`----
x DeclarationName
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | --var: [;
: ^^^^^
3 | }
`----
x DashedIdent
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | --var: [;
: ^^^^^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | ,-> --var: [;
3 | `-> }
`----
x SimpleBlock
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | ,-> --var: [;
3 | `-> }
`----
x LBracket
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | --var: [;
: ^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | --var: [;
: ^
3 | }
`----
x Semi
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | --var: [;
: ^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | --var: [;
: ^
3 | }
`----
x WhiteSpace { value: "\n" }
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:1:1]
1 | a {
2 | --var: [;
: ^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:2:1]
2 | --var: [;
3 | }
: ^
`----
x RBrace
,-[$DIR/tests/recovery/declaration/bad-value-1/input.css:2:1]
2 | --var: [;
3 | }
: ^
`----

View File

@ -0,0 +1,3 @@
a {
--var: (;
}

View File

@ -0,0 +1,165 @@
{
"type": "Stylesheet",
"span": {
"start": 1,
"end": 20,
"ctxt": 0
},
"rules": [
{
"type": "QualifiedRule",
"span": {
"start": 1,
"end": 20,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 3,
"end": 20,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 3,
"end": 4,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 9,
"end": 20,
"ctxt": 0
},
"name": {
"type": "DashedIdent",
"span": {
"start": 9,
"end": 14,
"ctxt": 0
},
"value": "var",
"raw": "--var"
},
"value": [
{
"type": "SimpleBlock",
"span": {
"start": 16,
"end": 20,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 16,
"end": 17,
"ctxt": 0
},
"token": "LParen"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 17,
"end": 18,
"ctxt": 0
},
"token": "Semi"
},
{
"type": "PreservedToken",
"span": {
"start": 18,
"end": 19,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": "\n"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 19,
"end": 20,
"ctxt": 0
},
"token": "RBrace"
}
]
}
],
"important": null
}
]
}
}
]
}

View File

@ -0,0 +1,14 @@
x Unexpected end of file, but expected ')'
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | ,-> --var: (;
3 | `-> }
`----
x Unexpected end of file, but expected '}'
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | ,-> a {
2 | | --var: (;
3 | `-> }
`----

View File

@ -0,0 +1,189 @@
x Stylesheet
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | ,-> a {
2 | | --var: (;
3 | `-> }
`----
x Rule
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | ,-> a {
2 | | --var: (;
3 | `-> }
`----
x QualifiedRule
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | ,-> a {
2 | | --var: (;
3 | `-> }
`----
x SelectorList
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x ComplexSelector
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x CompoundSelector
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x TypeSelector
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x TagNameSelector
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x WqName
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x Ident
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x SimpleBlock
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | ,-> a {
2 | | --var: (;
3 | `-> }
`----
x LBrace
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
: ^
2 | --var: (;
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | ,-> --var: (;
3 | `-> }
`----
x StyleBlock
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | ,-> --var: (;
3 | `-> }
`----
x Declaration
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | ,-> --var: (;
3 | `-> }
`----
x DeclarationName
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | --var: (;
: ^^^^^
3 | }
`----
x DashedIdent
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | --var: (;
: ^^^^^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | ,-> --var: (;
3 | `-> }
`----
x SimpleBlock
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | ,-> --var: (;
3 | `-> }
`----
x LParen
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | --var: (;
: ^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | --var: (;
: ^
3 | }
`----
x Semi
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | --var: (;
: ^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | --var: (;
: ^
3 | }
`----
x WhiteSpace { value: "\n" }
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:1:1]
1 | a {
2 | --var: (;
: ^
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:2:1]
2 | --var: (;
3 | }
: ^
`----
x RBrace
,-[$DIR/tests/recovery/declaration/bad-value-2/input.css:2:1]
2 | --var: (;
3 | }
: ^
`----

View File

@ -0,0 +1,14 @@
a {
value: );
value: ];
value: url(test test);
--foo: !;
--foo: );
--foo: ];
--foo: !;
value: !!;
value: ! !important;
value: ! !important unknown;
value: ! unknown;
value: ! ! !;
}

View File

@ -0,0 +1,677 @@
{
"type": "Stylesheet",
"span": {
"start": 1,
"end": 231,
"ctxt": 0
},
"rules": [
{
"type": "QualifiedRule",
"span": {
"start": 1,
"end": 230,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 3,
"end": 230,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 3,
"end": 4,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 9,
"end": 17,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 9,
"end": 14,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 16,
"end": 17,
"ctxt": 0
},
"token": "RParen"
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 23,
"end": 31,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 23,
"end": 28,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 30,
"end": 31,
"ctxt": 0
},
"token": "RBracket"
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 37,
"end": 58,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 37,
"end": 42,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 44,
"end": 58,
"ctxt": 0
},
"token": {
"BadUrl": {
"name": "url",
"raw_name": "url",
"raw_value": "test test"
}
}
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 64,
"end": 72,
"ctxt": 0
},
"name": {
"type": "DashedIdent",
"span": {
"start": 64,
"end": 69,
"ctxt": 0
},
"value": "foo",
"raw": "--foo"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 71,
"end": 72,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 78,
"end": 86,
"ctxt": 0
},
"name": {
"type": "DashedIdent",
"span": {
"start": 78,
"end": 83,
"ctxt": 0
},
"value": "foo",
"raw": "--foo"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 85,
"end": 86,
"ctxt": 0
},
"token": "RParen"
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 92,
"end": 100,
"ctxt": 0
},
"name": {
"type": "DashedIdent",
"span": {
"start": 92,
"end": 97,
"ctxt": 0
},
"value": "foo",
"raw": "--foo"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 99,
"end": 100,
"ctxt": 0
},
"token": "RBracket"
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 106,
"end": 114,
"ctxt": 0
},
"name": {
"type": "DashedIdent",
"span": {
"start": 106,
"end": 111,
"ctxt": 0
},
"value": "foo",
"raw": "--foo"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 113,
"end": 114,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 120,
"end": 129,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 120,
"end": 125,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 127,
"end": 128,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 128,
"end": 129,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 135,
"end": 154,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 135,
"end": 140,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 142,
"end": 143,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 143,
"end": 144,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
}
],
"important": {
"type": "ImportantFlag",
"span": {
"start": 144,
"end": 154,
"ctxt": 0
},
"value": {
"type": "Ident",
"span": {
"start": 145,
"end": 154,
"ctxt": 0
},
"value": "important",
"raw": "important"
}
}
},
{
"type": "Declaration",
"span": {
"start": 160,
"end": 187,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 160,
"end": 165,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 167,
"end": 168,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 168,
"end": 169,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 169,
"end": 170,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 170,
"end": 179,
"ctxt": 0
},
"token": {
"Ident": {
"value": "important",
"raw": "important"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 179,
"end": 180,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 180,
"end": 187,
"ctxt": 0
},
"token": {
"Ident": {
"value": "unknown",
"raw": "unknown"
}
}
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 193,
"end": 209,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 193,
"end": 198,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 200,
"end": 201,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 201,
"end": 202,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 202,
"end": 209,
"ctxt": 0
},
"token": {
"Ident": {
"value": "unknown",
"raw": "unknown"
}
}
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 215,
"end": 227,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 215,
"end": 220,
"ctxt": 0
},
"value": "value",
"raw": "value"
},
"value": [
{
"type": "PreservedToken",
"span": {
"start": 222,
"end": 223,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 223,
"end": 224,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 224,
"end": 225,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 225,
"end": 226,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 226,
"end": 227,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
}
],
"important": null
}
]
}
}
]
}

View File

@ -0,0 +1,128 @@
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:4:1]
4 | value: url(test test);
5 | --foo: !;
: ^
6 | --foo: );
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:7:1]
7 | --foo: ];
8 | --foo: !;
: ^
9 | value: !!;
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:8:1]
8 | --foo: !;
9 | value: !!;
: ^
10 | value: ! !important;
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:8:1]
8 | --foo: !;
9 | value: !!;
: ^
10 | value: ! !important;
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:9:1]
9 | value: !!;
10 | value: ! !important;
: ^
11 | value: ! !important unknown;
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:10:1]
10 | value: ! !important;
11 | value: ! !important unknown;
: ^
12 | value: ! unknown;
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:10:1]
10 | value: ! !important;
11 | value: ! !important unknown;
: ^
12 | value: ! unknown;
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:11:1]
11 | value: ! !important unknown;
12 | value: ! unknown;
: ^
13 | value: ! ! !;
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:12:1]
12 | value: ! unknown;
13 | value: ! ! !;
: ^
14 | }
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:12:1]
12 | value: ! unknown;
13 | value: ! ! !;
: ^
14 | }
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:12:1]
12 | value: ! unknown;
13 | value: ! ! !;
: ^
14 | }
`----
x Unexpected ')' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:1:1]
1 | a {
2 | value: );
: ^
3 | value: ];
`----
x Unexpected ')' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:5:1]
5 | --foo: !;
6 | --foo: );
: ^
7 | --foo: ];
`----
x Unexpected ']' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:2:1]
2 | value: );
3 | value: ];
: ^
4 | value: url(test test);
`----
x Unexpected ']' in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:6:1]
6 | --foo: );
7 | --foo: ];
: ^
8 | --foo: !;
`----
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/declaration/bad-value/input.css:3:1]
3 | value: ];
4 | value: url(test test);
: ^^^^^^^^^^^^^^
5 | --foo: !;
`----

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
13 | color: red;
`----
x Expected Declaration value
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/basic/input.css:6:1]
6 | .class {
7 | prop: !!;
@ -15,7 +15,7 @@
8 | color: red;
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/basic/input.css:6:1]
6 | .class {
7 | prop: !!;

View File

@ -1,13 +1,5 @@
x Expected Declaration value
,-[$DIR/tests/recovery/declaration/important-1/input.css:1:1]
1 | a {
2 | color: red !importan;
: ^
3 | }
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important-1/input.css:1:1]
1 | a {
2 | color: red !importan;

View File

@ -124,6 +124,19 @@
"value": " "
}
}
},
{
"type": "PreservedToken",
"span": {
"start": 23,
"end": 24,
"ctxt": 0
},
"token": {
"Delim": {
"value": "!"
}
}
}
],
"important": {

View File

@ -1,5 +1,13 @@
x Expected Declaration value
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important/input.css:1:1]
1 | .a {
2 | color: white !!important;
: ^
3 | }
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important/input.css:5:1]
5 | .class {
6 | color: red red red !important !important;
@ -7,7 +15,7 @@
7 | }
`----
x Expected Declaration value
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important/input.css:9:1]
9 | .class {
10 | color: red red red !important!important ;
@ -15,7 +23,7 @@
11 | }
`----
x Expected Declaration value
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important/input.css:13:1]
13 | .class {
14 | color: red red red /* test*/ !important /*test*/ !important /*test*/ ;
@ -23,7 +31,7 @@
15 | }
`----
x Expected Declaration value
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important/input.css:17:1]
17 | .class {
18 | color: red red red !important !important!important;
@ -31,18 +39,18 @@
19 | }
`----
x Expected Declaration value
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important/input.css:17:1]
17 | .class {
18 | color: red red red !important !important!important;
: ^
19 | }
`----
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/declaration/important/input.css:21:1]
21 | .class {
22 | color: red red red /* test */ ! /*test */ important /* test */ ! /* test */ important /* test */;
: ^
23 | }
`----
x Unexpected end of file
,-[$DIR/tests/recovery/declaration/important/input.css:1:1]
1 | .a {
2 | color: white !!important;
: ^
3 | }
`----

View File

@ -168,6 +168,22 @@
3 | }
`----
x ComponentValue
,-[$DIR/tests/recovery/declaration/important/input.css:1:1]
1 | .a {
2 | color: white !!important;
: ^
3 | }
`----
x Delim { value: '!' }
,-[$DIR/tests/recovery/declaration/important/input.css:1:1]
1 | .a {
2 | color: white !!important;
: ^
3 | }
`----
x ImportantFlag
,-[$DIR/tests/recovery/declaration/important/input.css:1:1]
1 | .a {

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/delim-token/bang/input.css:1:1]
1 | a {
2 | color: !!;
@ -7,7 +7,7 @@
3 | }
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/delim-token/bang/input.css:1:1]
1 | a {
2 | color: !!;

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/function/bad-comment-2/input.css:1:1]
1 | a {
2 | ,-> background: url(

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/function/bad-comment/input.css:1:1]
1 | a {
2 | ,-> background: url(

View File

@ -204,13 +204,6 @@
248 | }
`----
x Expected Declaration value
,-[$DIR/tests/recovery/hacks/input.css:179:1]
179 |
180 | .selector { property: value !ie; }
: ^
`----
x Expected Ident
,-[$DIR/tests/recovery/hacks/input.css:135:1]
135 | .selector {
@ -219,7 +212,7 @@
137 | color: red;
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/hacks/input.css:179:1]
179 |
180 | .selector { property: value !ie; }

View File

@ -14,13 +14,13 @@
"ctxt": 0
},
"prelude": {
"type": "Tokens",
"type": "ListOfComponentValues",
"span": {
"start": 0,
"end": 0,
"ctxt": 0
},
"tokens": []
"children": []
},
"block": {
"type": "SimpleBlock",
@ -29,7 +29,15 @@
"end": 5,
"ctxt": 0
},
"name": "{",
"name": {
"type": "PreservedToken",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"token": "LBrace"
},
"value": []
}
},
@ -41,13 +49,13 @@
"ctxt": 0
},
"prelude": {
"type": "Tokens",
"type": "ListOfComponentValues",
"span": {
"start": 0,
"end": 0,
"ctxt": 0
},
"tokens": []
"children": []
},
"block": {
"type": "SimpleBlock",
@ -56,7 +64,15 @@
"end": 9,
"ctxt": 0
},
"name": "{",
"name": {
"type": "PreservedToken",
"span": {
"start": 7,
"end": 8,
"ctxt": 0
},
"token": "LBrace"
},
"value": []
}
},
@ -68,13 +84,13 @@
"ctxt": 0
},
"prelude": {
"type": "Tokens",
"type": "ListOfComponentValues",
"span": {
"start": 0,
"end": 0,
"ctxt": 0
},
"tokens": []
"children": []
},
"block": {
"type": "SimpleBlock",
@ -83,7 +99,15 @@
"end": 30,
"ctxt": 0
},
"name": "{",
"name": {
"type": "PreservedToken",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",

View File

@ -0,0 +1,2 @@
x Invalid selector

View File

@ -1,11 +1,11 @@
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/value/custom-properties/exclamation/input.css:1:1]
1 | .class {--foo:!; }
: ^
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/value/custom-properties/exclamation/input.css:3:1]
3 | .class-1 {
4 | --foo:!;
@ -13,7 +13,7 @@
5 | color: red;
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/value/custom-properties/exclamation/input.css:9:1]
9 | color: red;
10 | --foo:!;
@ -21,7 +21,7 @@
11 | }
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/value/custom-properties/exclamation/input.css:13:1]
13 | .class-3 {
14 | --foo: !;
@ -29,7 +29,7 @@
15 | --foo: bar;
`----
x Unexpected '!' in <declaration-value>
x Unexpected '!' in declaration value
,-[$DIR/tests/recovery/value/custom-properties/exclamation/input.css:19:1]
19 | --foo: bar;
20 | --foo: !;

View File

@ -1,12 +1,4 @@
x Expected Declaration value
,-[$DIR/tests/recovery/value/quotes/input.css:1:1]
1 | p::before {
2 | content: "tes
: ^^^^
3 | t";
`----
x Newline in string
,-[$DIR/tests/recovery/value/quotes/input.css:1:1]
1 | p::before {
@ -23,3 +15,19 @@
: ^
4 | }
`----
x Unexpected bad string in declaration value
,-[$DIR/tests/recovery/value/quotes/input.css:1:1]
1 | p::before {
2 | content: "tes
: ^^^^
3 | t";
`----
x Unexpected bad string in declaration value
,-[$DIR/tests/recovery/value/quotes/input.css:2:1]
2 | content: "tes
3 | t";
: ^^
4 | }
`----

View File

@ -1,11 +1,4 @@
x Expected Declaration value
,-[$DIR/tests/recovery/value/string/newline/input.css:1:1]
1 | a {
2 | prop: "
: ^
`----
x Newline in string
,-[$DIR/tests/recovery/value/string/newline/input.css:1:1]
1 | a {
@ -13,6 +6,13 @@
: ^
`----
x Unexpected bad string in declaration value
,-[$DIR/tests/recovery/value/string/newline/input.css:1:1]
1 | a {
2 | prop: "
: ^
`----
x Unexpected end of file, but expected '}'
,-[$DIR/tests/recovery/value/string/newline/input.css:1:1]
1 | ,-> a {

View File

@ -1,20 +1,4 @@
x Expected Declaration value
,-[$DIR/tests/recovery/value/url/basic/input.css:2:1]
2 | --foo: "http://www.example.com/pinkish.gif";
3 | background: url(var(--foo));
: ^^^^^^^^^^^^^^
4 | background: url(image.png\999999);
`----
x Expected Declaration value
,-[$DIR/tests/recovery/value/url/basic/input.css:12:1]
12 | .foo {
13 | background: url(image.png param(var(--url)));
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14 | }
`----
x Expected ident or function
,-[$DIR/tests/recovery/value/url/basic/input.css:16:1]
16 | .style {
@ -23,6 +7,46 @@
18 | }
`----
x Unexpected ')' in declaration value
,-[$DIR/tests/recovery/value/url/basic/input.css:2:1]
2 | --foo: "http://www.example.com/pinkish.gif";
3 | background: url(var(--foo));
: ^
4 | background: url(image.png\999999);
`----
x Unexpected ')' in declaration value
,-[$DIR/tests/recovery/value/url/basic/input.css:12:1]
12 | .foo {
13 | background: url(image.png param(var(--url)));
: ^
14 | }
`----
x Unexpected ')' in declaration value
,-[$DIR/tests/recovery/value/url/basic/input.css:12:1]
12 | .foo {
13 | background: url(image.png param(var(--url)));
: ^
14 | }
`----
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/value/url/basic/input.css:2:1]
2 | --foo: "http://www.example.com/pinkish.gif";
3 | background: url(var(--foo));
: ^^^^^^^^^^^^^^
4 | background: url(image.png\999999);
`----
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/value/url/basic/input.css:12:1]
12 | .foo {
13 | background: url(image.png param(var(--url)));
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14 | }
`----
x Unexpected character in url
,-[$DIR/tests/recovery/value/url/basic/input.css:2:1]
2 | --foo: "http://www.example.com/pinkish.gif";

View File

@ -1,5 +1,5 @@
x Expected Declaration value
x Unexpected bad url in declaration value
,-[$DIR/tests/recovery/value/url/parenthesis/input.css:1:1]
1 | a {
2 | ,-> background: url(test\);