diff --git a/crates/biome_css_parser/src/syntax/scss/declaration/variable.rs b/crates/biome_css_parser/src/syntax/scss/declaration/variable.rs index 9b04bb09295f..e918a55d684f 100644 --- a/crates/biome_css_parser/src/syntax/scss/declaration/variable.rs +++ b/crates/biome_css_parser/src/syntax/scss/declaration/variable.rs @@ -2,13 +2,13 @@ use super::super::{is_at_scss_identifier, parse_scss_identifier}; use crate::parser::CssParser; use crate::syntax::parse_error::expected_scss_expression; use crate::syntax::scss::parse_scss_expression_until; -use crate::syntax::{is_at_identifier, is_nth_at_identifier, parse_regular_identifier}; +use crate::syntax::{is_nth_at_identifier, parse_regular_identifier}; use biome_css_syntax::CssSyntaxKind::{ - EOF, SCSS_DECLARATION, SCSS_NAMESPACED_IDENTIFIER, SCSS_VARIABLE_MODIFIER, + EOF, ERROR_TOKEN, SCSS_DECLARATION, SCSS_NAMESPACED_IDENTIFIER, SCSS_VARIABLE_MODIFIER, SCSS_VARIABLE_MODIFIER_LIST, }; -use biome_css_syntax::{CssSyntaxKind, T}; -use biome_parser::diagnostic::expected_token_any; +use biome_css_syntax::{CssSyntaxKind, T, TextRange}; +use biome_parser::diagnostic::{ParseDiagnostic, expected_token_any}; use biome_parser::parse_lists::ParseNodeList; use biome_parser::parse_recovery::{RecoveryError, RecoveryResult}; use biome_parser::prelude::ParsedSyntax; @@ -34,7 +34,7 @@ pub(crate) fn is_at_scss_declaration(p: &mut CssParser) -> bool { } } -/// Parses a SCSS variable declaration, including trailing `!default`/`!global`. +/// Parses a SCSS variable declaration, including trailing variable modifiers. /// /// Examples: /// ```scss @@ -56,7 +56,7 @@ pub(crate) fn parse_scss_declaration(p: &mut CssParser) -> ParsedSyntax { parse_scss_expression_until(p, token_set![T![!], T![;], T!['}']]) .or_add_diagnostic(p, expected_scss_expression); - ScssVariableModifierList.parse_list(p); + parse_scss_variable_modifiers(p); if !p.at(T!['}']) && !p.at(EOF) { if p.nth_at(1, T!['}']) { @@ -100,27 +100,68 @@ fn parse_scss_declaration_name(p: &mut CssParser) -> ParsedSyntax { } } +const SCSS_VARIABLE_MODIFIER_LIST_END_SET: TokenSet = + token_set![T![;], T!['}'], EOF]; +const SCSS_VARIABLE_MODIFIER_TOKEN_SET: TokenSet = + token_set![T![default], T![global]]; + #[inline] -fn is_at_scss_variable_modifier(p: &mut CssParser) -> bool { - p.at(T![!]) +fn parse_scss_variable_modifiers(p: &mut CssParser) { + ScssVariableModifierList.parse_list(p); + recover_scss_variable_modifier_tail(p); } -const SCSS_VARIABLE_MODIFIER_SET: TokenSet = token_set!(T![default], T![global]); +#[inline] +fn recover_scss_variable_modifier_tail(p: &mut CssParser) { + loop { + if p.at_ts(SCSS_VARIABLE_MODIFIER_LIST_END_SET) { + return; + } + + if p.at(T![!]) { + parse_scss_variable_modifier(p).ok(); + continue; + } + + if p.at(ERROR_TOKEN) { + p.bump_any(); + continue; + } + + // Recover malformed modifier separators only when they directly precede + // another modifier (`bar !global`). Otherwise leave the token for + // missing-semicolon recovery at declaration level. + if p.nth_at(1, T![!]) { + let range = p.cur_range(); + p.error( + p.err_builder("Unexpected value or character.", range) + .with_hint("Expected a variable modifier or the end of the declaration."), + ); + p.bump_any(); + continue; + } + + return; + } +} #[inline] fn parse_scss_variable_modifier(p: &mut CssParser) -> ParsedSyntax { - if !is_at_scss_variable_modifier(p) { + if !p.at(T![!]) { return Absent; } let m = p.start(); p.bump(T![!]); - if p.at_ts(SCSS_VARIABLE_MODIFIER_SET) { - p.bump_ts(SCSS_VARIABLE_MODIFIER_SET); + if p.at_ts(SCSS_VARIABLE_MODIFIER_TOKEN_SET) { + p.bump_ts(SCSS_VARIABLE_MODIFIER_TOKEN_SET); + } else if p.at(T![important]) { + p.error(important_modifier_not_allowed(p, p.cur_range())); + p.bump(T![important]); } else { p.error(expected_token_any(&[T![default], T![global]])); - if is_at_identifier(p) { + if !p.at_ts(SCSS_VARIABLE_MODIFIER_LIST_END_SET) { p.bump_any(); } } @@ -128,6 +169,13 @@ fn parse_scss_variable_modifier(p: &mut CssParser) -> ParsedSyntax { Present(m.complete(p, SCSS_VARIABLE_MODIFIER)) } +fn important_modifier_not_allowed(p: &CssParser, range: TextRange) -> ParseDiagnostic { + p.err_builder("`!important` is not valid here.", range) + .with_hint( + "SCSS variable declarations only support the `!default` and `!global` modifiers.", + ) +} + struct ScssVariableModifierList; impl ParseNodeList for ScssVariableModifierList { @@ -140,7 +188,7 @@ impl ParseNodeList for ScssVariableModifierList { } fn is_at_list_end(&self, p: &mut Self::Parser<'_>) -> bool { - !is_at_scss_variable_modifier(p) + p.at_ts(SCSS_VARIABLE_MODIFIER_LIST_END_SET) || !p.at(T![!]) } fn recover( diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/duplicate-modifier-recovery.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/duplicate-modifier-recovery.scss new file mode 100644 index 000000000000..b6eebfc16e93 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/duplicate-modifier-recovery.scss @@ -0,0 +1,4 @@ +// Duplicate modifiers with junk in between should still recover +// without targeted duplicate-modifier parser diagnostics +$dup-default-junk: 1 !default ??? !default; +$dup-global-junk: 1 !global ??? !global; diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/duplicate-modifier-recovery.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/duplicate-modifier-recovery.scss.snap new file mode 100644 index 000000000000..db59fa1ee1e3 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/duplicate-modifier-recovery.scss.snap @@ -0,0 +1,210 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +// Duplicate modifiers with junk in between should still recover +// without targeted duplicate-modifier parser diagnostics +$dup-default-junk: 1 !default ??? !default; +$dup-global-junk: 1 !global ??? !global; + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssBogus { + items: [ + ScssIdentifier { + dollar_token: DOLLAR@0..124 "$" [Comments("// Duplicate modifier ..."), Newline("\n"), Comments("// without targeted d ..."), Newline("\n")] [], + name: CssIdentifier { + value_token: IDENT@124..140 "dup-default-junk" [] [], + }, + }, + COLON@140..142 ":" [] [Whitespace(" ")], + ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@142..144 "1" [] [Whitespace(" ")], + }, + ], + }, + ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@144..145 "!" [] [], + value: DEFAULT_KW@145..153 "default" [] [Whitespace(" ")], + }, + ], + ERROR_TOKEN@153..154 "?" [] [], + ERROR_TOKEN@154..155 "?" [] [], + ERROR_TOKEN@155..157 "?" [] [Whitespace(" ")], + ScssVariableModifier { + excl_token: BANG@157..158 "!" [] [], + value: DEFAULT_KW@158..165 "default" [] [], + }, + SEMICOLON@165..166 ";" [] [], + ], + }, + CssBogus { + items: [ + ScssIdentifier { + dollar_token: DOLLAR@166..168 "$" [Newline("\n")] [], + name: CssIdentifier { + value_token: IDENT@168..183 "dup-global-junk" [] [], + }, + }, + COLON@183..185 ":" [] [Whitespace(" ")], + ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@185..187 "1" [] [Whitespace(" ")], + }, + ], + }, + ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@187..188 "!" [] [], + value: GLOBAL_KW@188..195 "global" [] [Whitespace(" ")], + }, + ], + ERROR_TOKEN@195..196 "?" [] [], + ERROR_TOKEN@196..197 "?" [] [], + ERROR_TOKEN@197..199 "?" [] [Whitespace(" ")], + ScssVariableModifier { + excl_token: BANG@199..200 "!" [] [], + value: GLOBAL_KW@200..206 "global" [] [], + }, + SEMICOLON@206..207 ";" [] [], + ], + }, + ], + eof_token: EOF@207..208 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..208 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..207 + 0: CSS_BOGUS@0..166 + 0: SCSS_IDENTIFIER@0..140 + 0: DOLLAR@0..124 "$" [Comments("// Duplicate modifier ..."), Newline("\n"), Comments("// without targeted d ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@124..140 + 0: IDENT@124..140 "dup-default-junk" [] [] + 1: COLON@140..142 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@142..144 + 0: SCSS_EXPRESSION_ITEM_LIST@142..144 + 0: CSS_NUMBER@142..144 + 0: CSS_NUMBER_LITERAL@142..144 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@144..153 + 0: SCSS_VARIABLE_MODIFIER@144..153 + 0: BANG@144..145 "!" [] [] + 1: DEFAULT_KW@145..153 "default" [] [Whitespace(" ")] + 4: ERROR_TOKEN@153..154 "?" [] [] + 5: ERROR_TOKEN@154..155 "?" [] [] + 6: ERROR_TOKEN@155..157 "?" [] [Whitespace(" ")] + 7: SCSS_VARIABLE_MODIFIER@157..165 + 0: BANG@157..158 "!" [] [] + 1: DEFAULT_KW@158..165 "default" [] [] + 8: SEMICOLON@165..166 ";" [] [] + 1: CSS_BOGUS@166..207 + 0: SCSS_IDENTIFIER@166..183 + 0: DOLLAR@166..168 "$" [Newline("\n")] [] + 1: CSS_IDENTIFIER@168..183 + 0: IDENT@168..183 "dup-global-junk" [] [] + 1: COLON@183..185 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@185..187 + 0: SCSS_EXPRESSION_ITEM_LIST@185..187 + 0: CSS_NUMBER@185..187 + 0: CSS_NUMBER_LITERAL@185..187 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@187..195 + 0: SCSS_VARIABLE_MODIFIER@187..195 + 0: BANG@187..188 "!" [] [] + 1: GLOBAL_KW@188..195 "global" [] [Whitespace(" ")] + 4: ERROR_TOKEN@195..196 "?" [] [] + 5: ERROR_TOKEN@196..197 "?" [] [] + 6: ERROR_TOKEN@197..199 "?" [] [Whitespace(" ")] + 7: SCSS_VARIABLE_MODIFIER@199..206 + 0: BANG@199..200 "!" [] [] + 1: GLOBAL_KW@200..206 "global" [] [] + 8: SEMICOLON@206..207 ";" [] [] + 2: EOF@207..208 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +duplicate-modifier-recovery.scss:3:31 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × unexpected character `?` + + 1 │ // Duplicate modifiers with junk in between should still recover + 2 │ // without targeted duplicate-modifier parser diagnostics + > 3 │ $dup-default-junk: 1 !default ??? !default; + │ ^ + 4 │ $dup-global-junk: 1 !global ??? !global; + 5 │ + +duplicate-modifier-recovery.scss:3:32 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × unexpected character `?` + + 1 │ // Duplicate modifiers with junk in between should still recover + 2 │ // without targeted duplicate-modifier parser diagnostics + > 3 │ $dup-default-junk: 1 !default ??? !default; + │ ^ + 4 │ $dup-global-junk: 1 !global ??? !global; + 5 │ + +duplicate-modifier-recovery.scss:3:33 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × unexpected character `?` + + 1 │ // Duplicate modifiers with junk in between should still recover + 2 │ // without targeted duplicate-modifier parser diagnostics + > 3 │ $dup-default-junk: 1 !default ??? !default; + │ ^ + 4 │ $dup-global-junk: 1 !global ??? !global; + 5 │ + +duplicate-modifier-recovery.scss:4:29 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × unexpected character `?` + + 2 │ // without targeted duplicate-modifier parser diagnostics + 3 │ $dup-default-junk: 1 !default ??? !default; + > 4 │ $dup-global-junk: 1 !global ??? !global; + │ ^ + 5 │ + +duplicate-modifier-recovery.scss:4:30 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × unexpected character `?` + + 2 │ // without targeted duplicate-modifier parser diagnostics + 3 │ $dup-default-junk: 1 !default ??? !default; + > 4 │ $dup-global-junk: 1 !global ??? !global; + │ ^ + 5 │ + +duplicate-modifier-recovery.scss:4:31 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × unexpected character `?` + + 2 │ // without targeted duplicate-modifier parser diagnostics + 3 │ $dup-default-junk: 1 !default ??? !default; + > 4 │ $dup-global-junk: 1 !global ??? !global; + │ ^ + 5 │ + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss index 925312f8a1ca..4330a102c2bc 100644 --- a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss @@ -1,4 +1,4 @@ -// Invalid modifier - using unknown identifier instead of !default or !global +// Invalid modifier - `!important` is not allowed on SCSS variable declarations $color: red !important; // Invalid modifier - just a random word diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss.snap index 56207c9e3ee7..b568ec4ce34d 100644 --- a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss.snap +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/invalid-modifier.scss.snap @@ -6,7 +6,7 @@ expression: snapshot ## Input ```css -// Invalid modifier - using unknown identifier instead of !default or !global +// Invalid modifier - `!important` is not allowed on SCSS variable declarations $color: red !important; // Invalid modifier - just a random word @@ -33,16 +33,16 @@ CssRoot { CssBogus { items: [ ScssIdentifier { - dollar_token: DOLLAR@0..79 "$" [Comments("// Invalid modifier - ..."), Newline("\n")] [], + dollar_token: DOLLAR@0..81 "$" [Comments("// Invalid modifier - ..."), Newline("\n")] [], name: CssIdentifier { - value_token: IDENT@79..84 "color" [] [], + value_token: IDENT@81..86 "color" [] [], }, }, - COLON@84..86 ":" [] [Whitespace(" ")], + COLON@86..88 ":" [] [Whitespace(" ")], ScssExpression { items: ScssExpressionItemList [ CssIdentifier { - value_token: IDENT@86..90 "red" [] [Whitespace(" ")], + value_token: IDENT@88..92 "red" [] [Whitespace(" ")], }, ], }, @@ -50,29 +50,29 @@ CssRoot { items: [ CssBogus { items: [ - BANG@90..91 "!" [] [], - IMPORTANT_KW@91..100 "important" [] [], + BANG@92..93 "!" [] [], + IMPORTANT_KW@93..102 "important" [] [], ], }, ], }, - SEMICOLON@100..101 ";" [] [], + SEMICOLON@102..103 ";" [] [], ], }, CssBogus { items: [ ScssIdentifier { - dollar_token: DOLLAR@101..145 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [], + dollar_token: DOLLAR@103..147 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [], name: CssIdentifier { - value_token: IDENT@145..150 "width" [] [], + value_token: IDENT@147..152 "width" [] [], }, }, - COLON@150..152 ":" [] [Whitespace(" ")], + COLON@152..154 ":" [] [Whitespace(" ")], ScssExpression { items: ScssExpressionItemList [ CssRegularDimension { - value_token: CSS_NUMBER_LITERAL@152..155 "100" [] [], - unit_token: IDENT@155..158 "px" [] [Whitespace(" ")], + value_token: CSS_NUMBER_LITERAL@154..157 "100" [] [], + unit_token: IDENT@157..160 "px" [] [Whitespace(" ")], }, ], }, @@ -80,29 +80,29 @@ CssRoot { items: [ CssBogus { items: [ - BANG@158..159 "!" [] [], - IDENT@159..165 "random" [] [], + BANG@160..161 "!" [] [], + IDENT@161..167 "random" [] [], ], }, ], }, - SEMICOLON@165..166 ";" [] [], + SEMICOLON@167..168 ";" [] [], ], }, CssBogus { items: [ ScssIdentifier { - dollar_token: DOLLAR@166..207 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [], + dollar_token: DOLLAR@168..209 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [], name: CssIdentifier { - value_token: IDENT@207..213 "height" [] [], + value_token: IDENT@209..215 "height" [] [], }, }, - COLON@213..215 ":" [] [Whitespace(" ")], + COLON@215..217 ":" [] [Whitespace(" ")], ScssExpression { items: ScssExpressionItemList [ CssRegularDimension { - value_token: CSS_NUMBER_LITERAL@215..217 "50" [] [], - unit_token: IDENT@217..220 "vh" [] [Whitespace(" ")], + value_token: CSS_NUMBER_LITERAL@217..219 "50" [] [], + unit_token: IDENT@219..222 "vh" [] [Whitespace(" ")], }, ], }, @@ -110,29 +110,29 @@ CssRoot { items: [ CssBogus { items: [ - BANG@220..221 "!" [] [], - IDENT@221..227 "defalt" [] [], + BANG@222..223 "!" [] [], + IDENT@223..229 "defalt" [] [], ], }, ], }, - SEMICOLON@227..228 ";" [] [], + SEMICOLON@229..230 ";" [] [], ], }, CssBogus { items: [ ScssIdentifier { - dollar_token: DOLLAR@228..268 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [], + dollar_token: DOLLAR@230..270 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [], name: CssIdentifier { - value_token: IDENT@268..277 "font-size" [] [], + value_token: IDENT@270..279 "font-size" [] [], }, }, - COLON@277..279 ":" [] [Whitespace(" ")], + COLON@279..281 ":" [] [Whitespace(" ")], ScssExpression { items: ScssExpressionItemList [ CssRegularDimension { - value_token: CSS_NUMBER_LITERAL@279..281 "16" [] [], - unit_token: IDENT@281..284 "px" [] [Whitespace(" ")], + value_token: CSS_NUMBER_LITERAL@281..283 "16" [] [], + unit_token: IDENT@283..286 "px" [] [Whitespace(" ")], }, ], }, @@ -140,29 +140,29 @@ CssRoot { items: [ CssBogus { items: [ - BANG@284..285 "!" [] [], - IDENT@285..290 "globl" [] [], + BANG@286..287 "!" [] [], + IDENT@287..292 "globl" [] [], ], }, ], }, - SEMICOLON@290..291 ";" [] [], + SEMICOLON@292..293 ";" [] [], ], }, CssBogus { items: [ ScssIdentifier { - dollar_token: DOLLAR@291..324 "$" [Newline("\n"), Newline("\n"), Comments("// Multiple invalid m ..."), Newline("\n")] [], + dollar_token: DOLLAR@293..326 "$" [Newline("\n"), Newline("\n"), Comments("// Multiple invalid m ..."), Newline("\n")] [], name: CssIdentifier { - value_token: IDENT@324..330 "margin" [] [], + value_token: IDENT@326..332 "margin" [] [], }, }, - COLON@330..332 ":" [] [Whitespace(" ")], + COLON@332..334 ":" [] [Whitespace(" ")], ScssExpression { items: ScssExpressionItemList [ CssRegularDimension { - value_token: CSS_NUMBER_LITERAL@332..334 "10" [] [], - unit_token: IDENT@334..337 "px" [] [Whitespace(" ")], + value_token: CSS_NUMBER_LITERAL@334..336 "10" [] [], + unit_token: IDENT@336..339 "px" [] [Whitespace(" ")], }, ], }, @@ -170,115 +170,115 @@ CssRoot { items: [ CssBogus { items: [ - BANG@337..338 "!" [] [], - IDENT@338..344 "wrong" [] [Whitespace(" ")], + BANG@339..340 "!" [] [], + IDENT@340..346 "wrong" [] [Whitespace(" ")], ], }, CssBogus { items: [ - BANG@344..345 "!" [] [], - IDENT@345..352 "invalid" [] [], + BANG@346..347 "!" [] [], + IDENT@347..354 "invalid" [] [], ], }, ], }, - SEMICOLON@352..353 ";" [] [], + SEMICOLON@354..355 ";" [] [], ], }, ], - eof_token: EOF@353..354 "" [Newline("\n")] [], + eof_token: EOF@355..356 "" [Newline("\n")] [], } ``` ## CST ``` -0: CSS_ROOT@0..354 +0: CSS_ROOT@0..356 0: (empty) - 1: CSS_ROOT_ITEM_LIST@0..353 - 0: CSS_BOGUS@0..101 - 0: SCSS_IDENTIFIER@0..84 - 0: DOLLAR@0..79 "$" [Comments("// Invalid modifier - ..."), Newline("\n")] [] - 1: CSS_IDENTIFIER@79..84 - 0: IDENT@79..84 "color" [] [] - 1: COLON@84..86 ":" [] [Whitespace(" ")] - 2: SCSS_EXPRESSION@86..90 - 0: SCSS_EXPRESSION_ITEM_LIST@86..90 - 0: CSS_IDENTIFIER@86..90 - 0: IDENT@86..90 "red" [] [Whitespace(" ")] - 3: CSS_BOGUS@90..100 - 0: CSS_BOGUS@90..100 - 0: BANG@90..91 "!" [] [] - 1: IMPORTANT_KW@91..100 "important" [] [] - 4: SEMICOLON@100..101 ";" [] [] - 1: CSS_BOGUS@101..166 - 0: SCSS_IDENTIFIER@101..150 - 0: DOLLAR@101..145 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [] - 1: CSS_IDENTIFIER@145..150 - 0: IDENT@145..150 "width" [] [] - 1: COLON@150..152 ":" [] [Whitespace(" ")] - 2: SCSS_EXPRESSION@152..158 - 0: SCSS_EXPRESSION_ITEM_LIST@152..158 - 0: CSS_REGULAR_DIMENSION@152..158 - 0: CSS_NUMBER_LITERAL@152..155 "100" [] [] - 1: IDENT@155..158 "px" [] [Whitespace(" ")] - 3: CSS_BOGUS@158..165 - 0: CSS_BOGUS@158..165 - 0: BANG@158..159 "!" [] [] - 1: IDENT@159..165 "random" [] [] - 4: SEMICOLON@165..166 ";" [] [] - 2: CSS_BOGUS@166..228 - 0: SCSS_IDENTIFIER@166..213 - 0: DOLLAR@166..207 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [] - 1: CSS_IDENTIFIER@207..213 - 0: IDENT@207..213 "height" [] [] - 1: COLON@213..215 ":" [] [Whitespace(" ")] - 2: SCSS_EXPRESSION@215..220 - 0: SCSS_EXPRESSION_ITEM_LIST@215..220 - 0: CSS_REGULAR_DIMENSION@215..220 - 0: CSS_NUMBER_LITERAL@215..217 "50" [] [] - 1: IDENT@217..220 "vh" [] [Whitespace(" ")] - 3: CSS_BOGUS@220..227 - 0: CSS_BOGUS@220..227 - 0: BANG@220..221 "!" [] [] - 1: IDENT@221..227 "defalt" [] [] - 4: SEMICOLON@227..228 ";" [] [] - 3: CSS_BOGUS@228..291 - 0: SCSS_IDENTIFIER@228..277 - 0: DOLLAR@228..268 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [] - 1: CSS_IDENTIFIER@268..277 - 0: IDENT@268..277 "font-size" [] [] - 1: COLON@277..279 ":" [] [Whitespace(" ")] - 2: SCSS_EXPRESSION@279..284 - 0: SCSS_EXPRESSION_ITEM_LIST@279..284 - 0: CSS_REGULAR_DIMENSION@279..284 - 0: CSS_NUMBER_LITERAL@279..281 "16" [] [] - 1: IDENT@281..284 "px" [] [Whitespace(" ")] - 3: CSS_BOGUS@284..290 - 0: CSS_BOGUS@284..290 - 0: BANG@284..285 "!" [] [] - 1: IDENT@285..290 "globl" [] [] - 4: SEMICOLON@290..291 ";" [] [] - 4: CSS_BOGUS@291..353 - 0: SCSS_IDENTIFIER@291..330 - 0: DOLLAR@291..324 "$" [Newline("\n"), Newline("\n"), Comments("// Multiple invalid m ..."), Newline("\n")] [] - 1: CSS_IDENTIFIER@324..330 - 0: IDENT@324..330 "margin" [] [] - 1: COLON@330..332 ":" [] [Whitespace(" ")] - 2: SCSS_EXPRESSION@332..337 - 0: SCSS_EXPRESSION_ITEM_LIST@332..337 - 0: CSS_REGULAR_DIMENSION@332..337 - 0: CSS_NUMBER_LITERAL@332..334 "10" [] [] - 1: IDENT@334..337 "px" [] [Whitespace(" ")] - 3: CSS_BOGUS@337..352 - 0: CSS_BOGUS@337..344 - 0: BANG@337..338 "!" [] [] - 1: IDENT@338..344 "wrong" [] [Whitespace(" ")] - 1: CSS_BOGUS@344..352 - 0: BANG@344..345 "!" [] [] - 1: IDENT@345..352 "invalid" [] [] - 4: SEMICOLON@352..353 ";" [] [] - 2: EOF@353..354 "" [Newline("\n")] [] + 1: CSS_ROOT_ITEM_LIST@0..355 + 0: CSS_BOGUS@0..103 + 0: SCSS_IDENTIFIER@0..86 + 0: DOLLAR@0..81 "$" [Comments("// Invalid modifier - ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@81..86 + 0: IDENT@81..86 "color" [] [] + 1: COLON@86..88 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@88..92 + 0: SCSS_EXPRESSION_ITEM_LIST@88..92 + 0: CSS_IDENTIFIER@88..92 + 0: IDENT@88..92 "red" [] [Whitespace(" ")] + 3: CSS_BOGUS@92..102 + 0: CSS_BOGUS@92..102 + 0: BANG@92..93 "!" [] [] + 1: IMPORTANT_KW@93..102 "important" [] [] + 4: SEMICOLON@102..103 ";" [] [] + 1: CSS_BOGUS@103..168 + 0: SCSS_IDENTIFIER@103..152 + 0: DOLLAR@103..147 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@147..152 + 0: IDENT@147..152 "width" [] [] + 1: COLON@152..154 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@154..160 + 0: SCSS_EXPRESSION_ITEM_LIST@154..160 + 0: CSS_REGULAR_DIMENSION@154..160 + 0: CSS_NUMBER_LITERAL@154..157 "100" [] [] + 1: IDENT@157..160 "px" [] [Whitespace(" ")] + 3: CSS_BOGUS@160..167 + 0: CSS_BOGUS@160..167 + 0: BANG@160..161 "!" [] [] + 1: IDENT@161..167 "random" [] [] + 4: SEMICOLON@167..168 ";" [] [] + 2: CSS_BOGUS@168..230 + 0: SCSS_IDENTIFIER@168..215 + 0: DOLLAR@168..209 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@209..215 + 0: IDENT@209..215 "height" [] [] + 1: COLON@215..217 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@217..222 + 0: SCSS_EXPRESSION_ITEM_LIST@217..222 + 0: CSS_REGULAR_DIMENSION@217..222 + 0: CSS_NUMBER_LITERAL@217..219 "50" [] [] + 1: IDENT@219..222 "vh" [] [Whitespace(" ")] + 3: CSS_BOGUS@222..229 + 0: CSS_BOGUS@222..229 + 0: BANG@222..223 "!" [] [] + 1: IDENT@223..229 "defalt" [] [] + 4: SEMICOLON@229..230 ";" [] [] + 3: CSS_BOGUS@230..293 + 0: SCSS_IDENTIFIER@230..279 + 0: DOLLAR@230..270 "$" [Newline("\n"), Newline("\n"), Comments("// Invalid modifier - ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@270..279 + 0: IDENT@270..279 "font-size" [] [] + 1: COLON@279..281 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@281..286 + 0: SCSS_EXPRESSION_ITEM_LIST@281..286 + 0: CSS_REGULAR_DIMENSION@281..286 + 0: CSS_NUMBER_LITERAL@281..283 "16" [] [] + 1: IDENT@283..286 "px" [] [Whitespace(" ")] + 3: CSS_BOGUS@286..292 + 0: CSS_BOGUS@286..292 + 0: BANG@286..287 "!" [] [] + 1: IDENT@287..292 "globl" [] [] + 4: SEMICOLON@292..293 ";" [] [] + 4: CSS_BOGUS@293..355 + 0: SCSS_IDENTIFIER@293..332 + 0: DOLLAR@293..326 "$" [Newline("\n"), Newline("\n"), Comments("// Multiple invalid m ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@326..332 + 0: IDENT@326..332 "margin" [] [] + 1: COLON@332..334 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@334..339 + 0: SCSS_EXPRESSION_ITEM_LIST@334..339 + 0: CSS_REGULAR_DIMENSION@334..339 + 0: CSS_NUMBER_LITERAL@334..336 "10" [] [] + 1: IDENT@336..339 "px" [] [Whitespace(" ")] + 3: CSS_BOGUS@339..354 + 0: CSS_BOGUS@339..346 + 0: BANG@339..340 "!" [] [] + 1: IDENT@340..346 "wrong" [] [Whitespace(" ")] + 1: CSS_BOGUS@346..354 + 0: BANG@346..347 "!" [] [] + 1: IDENT@347..354 "invalid" [] [] + 4: SEMICOLON@354..355 ";" [] [] + 2: EOF@355..356 "" [Newline("\n")] [] ``` @@ -287,15 +287,15 @@ CssRoot { ``` invalid-modifier.scss:2:14 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - × expected 'default', or 'global' but instead found `important` + × `!important` is not valid here. - 1 │ // Invalid modifier - using unknown identifier instead of !default or !global + 1 │ // Invalid modifier - `!important` is not allowed on SCSS variable declarations > 2 │ $color: red !important; │ ^^^^^^^^^ 3 │ 4 │ // Invalid modifier - just a random word - i Remove important + i SCSS variable declarations only support the `!default` and `!global` modifiers. invalid-modifier.scss:5:16 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-boundary-matrix.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-boundary-matrix.scss new file mode 100644 index 000000000000..e49e65404194 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-boundary-matrix.scss @@ -0,0 +1,66 @@ +a { + $v0: 1 !default + .class { color: red; } + + $v1: 1 !default + #id { color: red; } + + $v2: 1 !default + :hover { color: red; } + + $v3: 1 !default + [data-x] { color: red; } + + $v4: 1 !default + &.nested { color: red; } + + $v5: 1 !default + > .child { color: red; } + + $v6: 1 !default + + .sibling { color: red; } + + $v7: 1 !default + ~ .later { color: red; } + + $v8: 1 !default + || .column { color: red; } + + $v9: 1 !default + * { color: red; } + + $v10: 1 !default + svg|a { color: red; } + + $v11: 1 !default + a.b { color: red; } + + $v12: 1 !default + a#id { color: red; } + + $v13: 1 !default + a[attr] { color: red; } + + $v14: 1 !default + a::before { color: red; } + + $v15: 1 !default + a > .desc { color: red; } + + $v16: 1 !default + a + .adj { color: red; } + + $v17: 1 !default + a ~ .sib { color: red; } + + $v18: 1 !default + a || .col { color: red; } + + $v19: 1 !default + @media screen { + .m { color: red; } + } + + $v20: 1 !default + color: red; +} diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-boundary-matrix.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-boundary-matrix.scss.snap new file mode 100644 index 000000000000..2b5a9a55d1e7 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-boundary-matrix.scss.snap @@ -0,0 +1,2849 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +a { + $v0: 1 !default + .class { color: red; } + + $v1: 1 !default + #id { color: red; } + + $v2: 1 !default + :hover { color: red; } + + $v3: 1 !default + [data-x] { color: red; } + + $v4: 1 !default + &.nested { color: red; } + + $v5: 1 !default + > .child { color: red; } + + $v6: 1 !default + + .sibling { color: red; } + + $v7: 1 !default + ~ .later { color: red; } + + $v8: 1 !default + || .column { color: red; } + + $v9: 1 !default + * { color: red; } + + $v10: 1 !default + svg|a { color: red; } + + $v11: 1 !default + a.b { color: red; } + + $v12: 1 !default + a#id { color: red; } + + $v13: 1 !default + a[attr] { color: red; } + + $v14: 1 !default + a::before { color: red; } + + $v15: 1 !default + a > .desc { color: red; } + + $v16: 1 !default + a + .adj { color: red; } + + $v17: 1 !default + a ~ .sib { color: red; } + + $v18: 1 !default + a || .col { color: red; } + + $v19: 1 !default + @media screen { + .m { color: red; } + } + + $v20: 1 !default + color: red; +} + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@0..2 "a" [] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@2..3 "{" [] [], + items: CssDeclarationOrRuleList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@7..9 "v0" [] [], + }, + }, + colon_token: COLON@9..11 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@11..13 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@13..14 "!" [] [], + value: DEFAULT_KW@14..21 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@21..25 "." [Newline("\n"), Whitespace(" ")] [], + name: CssCustomIdentifier { + value_token: IDENT@25..31 "class" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@31..33 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@33..38 "color" [] [], + }, + colon_token: COLON@38..40 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@40..43 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@43..45 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@45..46 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@46..51 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@51..53 "v1" [] [], + }, + }, + colon_token: COLON@53..55 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@55..57 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@57..58 "!" [] [], + value: DEFAULT_KW@58..65 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssIdSelector { + hash_token: HASH@65..69 "#" [Newline("\n"), Whitespace(" ")] [], + name: CssCustomIdentifier { + value_token: IDENT@69..72 "id" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@72..74 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@74..79 "color" [] [], + }, + colon_token: COLON@79..81 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@81..84 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@84..86 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@86..87 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@87..92 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@92..94 "v2" [] [], + }, + }, + colon_token: COLON@94..96 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@96..98 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@98..99 "!" [] [], + value: DEFAULT_KW@99..106 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssPseudoClassSelector { + colon_token: COLON@106..110 ":" [Newline("\n"), Whitespace(" ")] [], + class: CssPseudoClassIdentifier { + name: CssIdentifier { + value_token: IDENT@110..116 "hover" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@116..118 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@118..123 "color" [] [], + }, + colon_token: COLON@123..125 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@125..128 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@128..130 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@130..131 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@131..136 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@136..138 "v3" [] [], + }, + }, + colon_token: COLON@138..140 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@140..142 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@142..143 "!" [] [], + value: DEFAULT_KW@143..150 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssAttributeSelector { + l_brack_token: L_BRACK@150..154 "[" [Newline("\n"), Whitespace(" ")] [], + name: CssAttributeName { + namespace: missing (optional), + name: CssIdentifier { + value_token: IDENT@154..160 "data-x" [] [], + }, + }, + matcher: missing (optional), + r_brack_token: R_BRACK@160..162 "]" [] [Whitespace(" ")], + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@162..164 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@164..169 "color" [] [], + }, + colon_token: COLON@169..171 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@171..174 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@174..176 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@176..177 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@177..182 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@182..184 "v4" [] [], + }, + }, + colon_token: COLON@184..186 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@186..188 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@188..189 "!" [] [], + value: DEFAULT_KW@189..196 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [ + CssNestedSelector { + amp_token: AMP@196..200 "&" [Newline("\n"), Whitespace(" ")] [], + }, + ], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@200..201 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@201..208 "nested" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@208..210 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@210..215 "color" [] [], + }, + colon_token: COLON@215..217 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@217..220 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@220..222 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@222..223 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@223..228 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@228..230 "v5" [] [], + }, + }, + colon_token: COLON@230..232 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@232..234 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@234..235 "!" [] [], + value: DEFAULT_KW@235..242 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: R_ANGLE@242..247 ">" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@247..248 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@248..254 "child" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@254..256 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@256..261 "color" [] [], + }, + colon_token: COLON@261..263 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@263..266 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@266..268 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@268..269 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@269..274 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@274..276 "v6" [] [], + }, + }, + colon_token: COLON@276..278 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@278..280 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@280..281 "!" [] [], + value: DEFAULT_KW@281..288 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: PLUS@288..293 "+" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@293..294 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@294..302 "sibling" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@302..304 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@304..309 "color" [] [], + }, + colon_token: COLON@309..311 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@311..314 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@314..316 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@316..317 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@317..322 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@322..324 "v7" [] [], + }, + }, + colon_token: COLON@324..326 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@326..328 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@328..329 "!" [] [], + value: DEFAULT_KW@329..336 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: TILDE@336..341 "~" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@341..342 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@342..348 "later" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@348..350 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@350..355 "color" [] [], + }, + colon_token: COLON@355..357 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@357..360 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@360..362 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@362..363 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@363..368 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@368..370 "v8" [] [], + }, + }, + colon_token: COLON@370..372 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@372..374 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@374..375 "!" [] [], + value: DEFAULT_KW@375..382 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: PIPE2@382..388 "||" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@388..389 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@389..396 "column" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@396..398 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@398..403 "color" [] [], + }, + colon_token: COLON@403..405 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@405..408 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@408..410 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@410..411 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@411..416 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@416..418 "v9" [] [], + }, + }, + colon_token: COLON@418..420 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@420..422 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@422..423 "!" [] [], + value: DEFAULT_KW@423..430 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssUniversalSelector { + namespace: missing (optional), + star_token: STAR@430..435 "*" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + sub_selectors: CssSubSelectorList [], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@435..437 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@437..442 "color" [] [], + }, + colon_token: COLON@442..444 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@444..447 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@447..449 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@449..450 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@450..455 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@455..458 "v10" [] [], + }, + }, + colon_token: COLON@458..460 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@460..462 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@462..463 "!" [] [], + value: DEFAULT_KW@463..470 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: CssNamespace { + prefix: CssNamedNamespacePrefix { + name: CssIdentifier { + value_token: IDENT@470..476 "svg" [Newline("\n"), Whitespace(" ")] [], + }, + }, + bitwise_or_token: PIPE@476..477 "|" [] [], + }, + ident: CssIdentifier { + value_token: IDENT@477..479 "a" [] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@479..481 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@481..486 "color" [] [], + }, + colon_token: COLON@486..488 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@488..491 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@491..493 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@493..494 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@494..499 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@499..502 "v11" [] [], + }, + }, + colon_token: COLON@502..504 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@504..506 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@506..507 "!" [] [], + value: DEFAULT_KW@507..514 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@514..518 "a" [Newline("\n"), Whitespace(" ")] [], + }, + }, + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@518..519 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@519..521 "b" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@521..523 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@523..528 "color" [] [], + }, + colon_token: COLON@528..530 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@530..533 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@533..535 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@535..536 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@536..541 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@541..544 "v12" [] [], + }, + }, + colon_token: COLON@544..546 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@546..548 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@548..549 "!" [] [], + value: DEFAULT_KW@549..556 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@556..560 "a" [Newline("\n"), Whitespace(" ")] [], + }, + }, + sub_selectors: CssSubSelectorList [ + CssIdSelector { + hash_token: HASH@560..561 "#" [] [], + name: CssCustomIdentifier { + value_token: IDENT@561..564 "id" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@564..566 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@566..571 "color" [] [], + }, + colon_token: COLON@571..573 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@573..576 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@576..578 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@578..579 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@579..584 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@584..587 "v13" [] [], + }, + }, + colon_token: COLON@587..589 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@589..591 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@591..592 "!" [] [], + value: DEFAULT_KW@592..599 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@599..603 "a" [Newline("\n"), Whitespace(" ")] [], + }, + }, + sub_selectors: CssSubSelectorList [ + CssAttributeSelector { + l_brack_token: L_BRACK@603..604 "[" [] [], + name: CssAttributeName { + namespace: missing (optional), + name: CssIdentifier { + value_token: IDENT@604..608 "attr" [] [], + }, + }, + matcher: missing (optional), + r_brack_token: R_BRACK@608..610 "]" [] [Whitespace(" ")], + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@610..612 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@612..617 "color" [] [], + }, + colon_token: COLON@617..619 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@619..622 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@622..624 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@624..625 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@625..630 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@630..633 "v14" [] [], + }, + }, + colon_token: COLON@633..635 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@635..637 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@637..638 "!" [] [], + value: DEFAULT_KW@638..645 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@645..649 "a" [Newline("\n"), Whitespace(" ")] [], + }, + }, + sub_selectors: CssSubSelectorList [ + CssPseudoElementSelector { + double_colon_token: COLON2@649..651 "::" [] [], + element: CssPseudoElementIdentifier { + name: CssIdentifier { + value_token: IDENT@651..658 "before" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@658..660 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@660..665 "color" [] [], + }, + colon_token: COLON@665..667 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@667..670 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@670..672 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@672..673 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@673..678 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@678..681 "v15" [] [], + }, + }, + colon_token: COLON@681..683 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@683..685 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@685..686 "!" [] [], + value: DEFAULT_KW@686..693 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssComplexSelector { + left: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@693..698 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + combinator: R_ANGLE@698..700 ">" [] [Whitespace(" ")], + right: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@700..701 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@701..706 "desc" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@706..708 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@708..713 "color" [] [], + }, + colon_token: COLON@713..715 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@715..718 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@718..720 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@720..721 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@721..726 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@726..729 "v16" [] [], + }, + }, + colon_token: COLON@729..731 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@731..733 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@733..734 "!" [] [], + value: DEFAULT_KW@734..741 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssComplexSelector { + left: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@741..746 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + combinator: PLUS@746..748 "+" [] [Whitespace(" ")], + right: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@748..749 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@749..753 "adj" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@753..755 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@755..760 "color" [] [], + }, + colon_token: COLON@760..762 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@762..765 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@765..767 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@767..768 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@768..773 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@773..776 "v17" [] [], + }, + }, + colon_token: COLON@776..778 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@778..780 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@780..781 "!" [] [], + value: DEFAULT_KW@781..788 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssComplexSelector { + left: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@788..793 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + combinator: TILDE@793..795 "~" [] [Whitespace(" ")], + right: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@795..796 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@796..800 "sib" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@800..802 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@802..807 "color" [] [], + }, + colon_token: COLON@807..809 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@809..812 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@812..814 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@814..815 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@815..820 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@820..823 "v18" [] [], + }, + }, + colon_token: COLON@823..825 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@825..827 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@827..828 "!" [] [], + value: DEFAULT_KW@828..835 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssComplexSelector { + left: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@835..840 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + combinator: PIPE2@840..843 "||" [] [Whitespace(" ")], + right: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@843..844 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@844..848 "col" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@848..850 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@850..855 "color" [] [], + }, + colon_token: COLON@855..857 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@857..860 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@860..862 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@862..863 "}" [] [], + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@863..868 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@868..871 "v19" [] [], + }, + }, + colon_token: COLON@871..873 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@873..875 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@875..876 "!" [] [], + value: DEFAULT_KW@876..883 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssAtRule { + at_token: AT@883..887 "@" [Newline("\n"), Whitespace(" ")] [], + rule: CssMediaAtRule { + declarator: CssMediaAtRuleDeclarator { + media_token: MEDIA_KW@887..893 "media" [] [Whitespace(" ")], + queries: CssMediaQueryList [ + CssMediaTypeQuery { + modifier: missing (optional), + ty: CssMediaType { + value: CssIdentifier { + value_token: IDENT@893..900 "screen" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@900..901 "{" [] [], + items: CssDeclarationOrRuleList [ + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@901..907 "." [Newline("\n"), Whitespace(" ")] [], + name: CssCustomIdentifier { + value_token: IDENT@907..909 "m" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@909..911 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@911..916 "color" [] [], + }, + colon_token: COLON@916..918 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@918..921 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@921..923 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@923..924 "}" [] [], + }, + }, + ], + r_curly_token: R_CURLY@924..928 "}" [Newline("\n"), Whitespace(" ")] [], + }, + }, + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@928..933 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@933..936 "v20" [] [], + }, + }, + colon_token: COLON@936..938 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@938..940 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@940..941 "!" [] [], + value: DEFAULT_KW@941..948 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@948..956 "color" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@956..958 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@958..961 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@961..962 ";" [] [], + }, + ], + r_curly_token: R_CURLY@962..964 "}" [Newline("\n")] [], + }, + }, + ], + eof_token: EOF@964..965 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..965 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..964 + 0: CSS_QUALIFIED_RULE@0..964 + 0: CSS_SELECTOR_LIST@0..2 + 0: CSS_COMPOUND_SELECTOR@0..2 + 0: CSS_NESTED_SELECTOR_LIST@0..0 + 1: CSS_TYPE_SELECTOR@0..2 + 0: (empty) + 1: CSS_IDENTIFIER@0..2 + 0: IDENT@0..2 "a" [] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@2..2 + 1: CSS_DECLARATION_OR_RULE_BLOCK@2..964 + 0: L_CURLY@2..3 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@3..962 + 0: SCSS_DECLARATION@3..21 + 0: SCSS_IDENTIFIER@3..9 + 0: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@7..9 + 0: IDENT@7..9 "v0" [] [] + 1: COLON@9..11 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@11..13 + 0: SCSS_EXPRESSION_ITEM_LIST@11..13 + 0: CSS_NUMBER@11..13 + 0: CSS_NUMBER_LITERAL@11..13 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@13..21 + 0: SCSS_VARIABLE_MODIFIER@13..21 + 0: BANG@13..14 "!" [] [] + 1: DEFAULT_KW@14..21 "default" [] [] + 4: (empty) + 1: CSS_NESTED_QUALIFIED_RULE@21..46 + 0: CSS_RELATIVE_SELECTOR_LIST@21..31 + 0: CSS_RELATIVE_SELECTOR@21..31 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@21..31 + 0: CSS_NESTED_SELECTOR_LIST@21..21 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@21..31 + 0: CSS_CLASS_SELECTOR@21..31 + 0: DOT@21..25 "." [Newline("\n"), Whitespace(" ")] [] + 1: CSS_CUSTOM_IDENTIFIER@25..31 + 0: IDENT@25..31 "class" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@31..46 + 0: L_CURLY@31..33 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@33..45 + 0: CSS_DECLARATION_WITH_SEMICOLON@33..45 + 0: CSS_DECLARATION@33..43 + 0: CSS_GENERIC_PROPERTY@33..43 + 0: CSS_IDENTIFIER@33..38 + 0: IDENT@33..38 "color" [] [] + 1: COLON@38..40 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@40..43 + 0: SCSS_EXPRESSION_ITEM_LIST@40..43 + 0: CSS_IDENTIFIER@40..43 + 0: IDENT@40..43 "red" [] [] + 1: (empty) + 1: SEMICOLON@43..45 ";" [] [Whitespace(" ")] + 2: R_CURLY@45..46 "}" [] [] + 2: SCSS_DECLARATION@46..65 + 0: SCSS_IDENTIFIER@46..53 + 0: DOLLAR@46..51 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@51..53 + 0: IDENT@51..53 "v1" [] [] + 1: COLON@53..55 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@55..57 + 0: SCSS_EXPRESSION_ITEM_LIST@55..57 + 0: CSS_NUMBER@55..57 + 0: CSS_NUMBER_LITERAL@55..57 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@57..65 + 0: SCSS_VARIABLE_MODIFIER@57..65 + 0: BANG@57..58 "!" [] [] + 1: DEFAULT_KW@58..65 "default" [] [] + 4: (empty) + 3: CSS_NESTED_QUALIFIED_RULE@65..87 + 0: CSS_RELATIVE_SELECTOR_LIST@65..72 + 0: CSS_RELATIVE_SELECTOR@65..72 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@65..72 + 0: CSS_NESTED_SELECTOR_LIST@65..65 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@65..72 + 0: CSS_ID_SELECTOR@65..72 + 0: HASH@65..69 "#" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_CUSTOM_IDENTIFIER@69..72 + 0: IDENT@69..72 "id" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@72..87 + 0: L_CURLY@72..74 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@74..86 + 0: CSS_DECLARATION_WITH_SEMICOLON@74..86 + 0: CSS_DECLARATION@74..84 + 0: CSS_GENERIC_PROPERTY@74..84 + 0: CSS_IDENTIFIER@74..79 + 0: IDENT@74..79 "color" [] [] + 1: COLON@79..81 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@81..84 + 0: SCSS_EXPRESSION_ITEM_LIST@81..84 + 0: CSS_IDENTIFIER@81..84 + 0: IDENT@81..84 "red" [] [] + 1: (empty) + 1: SEMICOLON@84..86 ";" [] [Whitespace(" ")] + 2: R_CURLY@86..87 "}" [] [] + 4: SCSS_DECLARATION@87..106 + 0: SCSS_IDENTIFIER@87..94 + 0: DOLLAR@87..92 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@92..94 + 0: IDENT@92..94 "v2" [] [] + 1: COLON@94..96 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@96..98 + 0: SCSS_EXPRESSION_ITEM_LIST@96..98 + 0: CSS_NUMBER@96..98 + 0: CSS_NUMBER_LITERAL@96..98 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@98..106 + 0: SCSS_VARIABLE_MODIFIER@98..106 + 0: BANG@98..99 "!" [] [] + 1: DEFAULT_KW@99..106 "default" [] [] + 4: (empty) + 5: CSS_NESTED_QUALIFIED_RULE@106..131 + 0: CSS_RELATIVE_SELECTOR_LIST@106..116 + 0: CSS_RELATIVE_SELECTOR@106..116 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@106..116 + 0: CSS_NESTED_SELECTOR_LIST@106..106 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@106..116 + 0: CSS_PSEUDO_CLASS_SELECTOR@106..116 + 0: COLON@106..110 ":" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_PSEUDO_CLASS_IDENTIFIER@110..116 + 0: CSS_IDENTIFIER@110..116 + 0: IDENT@110..116 "hover" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@116..131 + 0: L_CURLY@116..118 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@118..130 + 0: CSS_DECLARATION_WITH_SEMICOLON@118..130 + 0: CSS_DECLARATION@118..128 + 0: CSS_GENERIC_PROPERTY@118..128 + 0: CSS_IDENTIFIER@118..123 + 0: IDENT@118..123 "color" [] [] + 1: COLON@123..125 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@125..128 + 0: SCSS_EXPRESSION_ITEM_LIST@125..128 + 0: CSS_IDENTIFIER@125..128 + 0: IDENT@125..128 "red" [] [] + 1: (empty) + 1: SEMICOLON@128..130 ";" [] [Whitespace(" ")] + 2: R_CURLY@130..131 "}" [] [] + 6: SCSS_DECLARATION@131..150 + 0: SCSS_IDENTIFIER@131..138 + 0: DOLLAR@131..136 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@136..138 + 0: IDENT@136..138 "v3" [] [] + 1: COLON@138..140 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@140..142 + 0: SCSS_EXPRESSION_ITEM_LIST@140..142 + 0: CSS_NUMBER@140..142 + 0: CSS_NUMBER_LITERAL@140..142 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@142..150 + 0: SCSS_VARIABLE_MODIFIER@142..150 + 0: BANG@142..143 "!" [] [] + 1: DEFAULT_KW@143..150 "default" [] [] + 4: (empty) + 7: CSS_NESTED_QUALIFIED_RULE@150..177 + 0: CSS_RELATIVE_SELECTOR_LIST@150..162 + 0: CSS_RELATIVE_SELECTOR@150..162 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@150..162 + 0: CSS_NESTED_SELECTOR_LIST@150..150 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@150..162 + 0: CSS_ATTRIBUTE_SELECTOR@150..162 + 0: L_BRACK@150..154 "[" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_ATTRIBUTE_NAME@154..160 + 0: (empty) + 1: CSS_IDENTIFIER@154..160 + 0: IDENT@154..160 "data-x" [] [] + 2: (empty) + 3: R_BRACK@160..162 "]" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@162..177 + 0: L_CURLY@162..164 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@164..176 + 0: CSS_DECLARATION_WITH_SEMICOLON@164..176 + 0: CSS_DECLARATION@164..174 + 0: CSS_GENERIC_PROPERTY@164..174 + 0: CSS_IDENTIFIER@164..169 + 0: IDENT@164..169 "color" [] [] + 1: COLON@169..171 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@171..174 + 0: SCSS_EXPRESSION_ITEM_LIST@171..174 + 0: CSS_IDENTIFIER@171..174 + 0: IDENT@171..174 "red" [] [] + 1: (empty) + 1: SEMICOLON@174..176 ";" [] [Whitespace(" ")] + 2: R_CURLY@176..177 "}" [] [] + 8: SCSS_DECLARATION@177..196 + 0: SCSS_IDENTIFIER@177..184 + 0: DOLLAR@177..182 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@182..184 + 0: IDENT@182..184 "v4" [] [] + 1: COLON@184..186 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@186..188 + 0: SCSS_EXPRESSION_ITEM_LIST@186..188 + 0: CSS_NUMBER@186..188 + 0: CSS_NUMBER_LITERAL@186..188 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@188..196 + 0: SCSS_VARIABLE_MODIFIER@188..196 + 0: BANG@188..189 "!" [] [] + 1: DEFAULT_KW@189..196 "default" [] [] + 4: (empty) + 9: CSS_NESTED_QUALIFIED_RULE@196..223 + 0: CSS_RELATIVE_SELECTOR_LIST@196..208 + 0: CSS_RELATIVE_SELECTOR@196..208 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@196..208 + 0: CSS_NESTED_SELECTOR_LIST@196..200 + 0: CSS_NESTED_SELECTOR@196..200 + 0: AMP@196..200 "&" [Newline("\n"), Whitespace(" ")] [] + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@200..208 + 0: CSS_CLASS_SELECTOR@200..208 + 0: DOT@200..201 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@201..208 + 0: IDENT@201..208 "nested" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@208..223 + 0: L_CURLY@208..210 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@210..222 + 0: CSS_DECLARATION_WITH_SEMICOLON@210..222 + 0: CSS_DECLARATION@210..220 + 0: CSS_GENERIC_PROPERTY@210..220 + 0: CSS_IDENTIFIER@210..215 + 0: IDENT@210..215 "color" [] [] + 1: COLON@215..217 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@217..220 + 0: SCSS_EXPRESSION_ITEM_LIST@217..220 + 0: CSS_IDENTIFIER@217..220 + 0: IDENT@217..220 "red" [] [] + 1: (empty) + 1: SEMICOLON@220..222 ";" [] [Whitespace(" ")] + 2: R_CURLY@222..223 "}" [] [] + 10: SCSS_DECLARATION@223..242 + 0: SCSS_IDENTIFIER@223..230 + 0: DOLLAR@223..228 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@228..230 + 0: IDENT@228..230 "v5" [] [] + 1: COLON@230..232 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@232..234 + 0: SCSS_EXPRESSION_ITEM_LIST@232..234 + 0: CSS_NUMBER@232..234 + 0: CSS_NUMBER_LITERAL@232..234 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@234..242 + 0: SCSS_VARIABLE_MODIFIER@234..242 + 0: BANG@234..235 "!" [] [] + 1: DEFAULT_KW@235..242 "default" [] [] + 4: (empty) + 11: CSS_NESTED_QUALIFIED_RULE@242..269 + 0: CSS_RELATIVE_SELECTOR_LIST@242..254 + 0: CSS_RELATIVE_SELECTOR@242..254 + 0: R_ANGLE@242..247 ">" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: CSS_COMPOUND_SELECTOR@247..254 + 0: CSS_NESTED_SELECTOR_LIST@247..247 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@247..254 + 0: CSS_CLASS_SELECTOR@247..254 + 0: DOT@247..248 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@248..254 + 0: IDENT@248..254 "child" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@254..269 + 0: L_CURLY@254..256 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@256..268 + 0: CSS_DECLARATION_WITH_SEMICOLON@256..268 + 0: CSS_DECLARATION@256..266 + 0: CSS_GENERIC_PROPERTY@256..266 + 0: CSS_IDENTIFIER@256..261 + 0: IDENT@256..261 "color" [] [] + 1: COLON@261..263 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@263..266 + 0: SCSS_EXPRESSION_ITEM_LIST@263..266 + 0: CSS_IDENTIFIER@263..266 + 0: IDENT@263..266 "red" [] [] + 1: (empty) + 1: SEMICOLON@266..268 ";" [] [Whitespace(" ")] + 2: R_CURLY@268..269 "}" [] [] + 12: SCSS_DECLARATION@269..288 + 0: SCSS_IDENTIFIER@269..276 + 0: DOLLAR@269..274 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@274..276 + 0: IDENT@274..276 "v6" [] [] + 1: COLON@276..278 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@278..280 + 0: SCSS_EXPRESSION_ITEM_LIST@278..280 + 0: CSS_NUMBER@278..280 + 0: CSS_NUMBER_LITERAL@278..280 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@280..288 + 0: SCSS_VARIABLE_MODIFIER@280..288 + 0: BANG@280..281 "!" [] [] + 1: DEFAULT_KW@281..288 "default" [] [] + 4: (empty) + 13: CSS_NESTED_QUALIFIED_RULE@288..317 + 0: CSS_RELATIVE_SELECTOR_LIST@288..302 + 0: CSS_RELATIVE_SELECTOR@288..302 + 0: PLUS@288..293 "+" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: CSS_COMPOUND_SELECTOR@293..302 + 0: CSS_NESTED_SELECTOR_LIST@293..293 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@293..302 + 0: CSS_CLASS_SELECTOR@293..302 + 0: DOT@293..294 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@294..302 + 0: IDENT@294..302 "sibling" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@302..317 + 0: L_CURLY@302..304 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@304..316 + 0: CSS_DECLARATION_WITH_SEMICOLON@304..316 + 0: CSS_DECLARATION@304..314 + 0: CSS_GENERIC_PROPERTY@304..314 + 0: CSS_IDENTIFIER@304..309 + 0: IDENT@304..309 "color" [] [] + 1: COLON@309..311 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@311..314 + 0: SCSS_EXPRESSION_ITEM_LIST@311..314 + 0: CSS_IDENTIFIER@311..314 + 0: IDENT@311..314 "red" [] [] + 1: (empty) + 1: SEMICOLON@314..316 ";" [] [Whitespace(" ")] + 2: R_CURLY@316..317 "}" [] [] + 14: SCSS_DECLARATION@317..336 + 0: SCSS_IDENTIFIER@317..324 + 0: DOLLAR@317..322 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@322..324 + 0: IDENT@322..324 "v7" [] [] + 1: COLON@324..326 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@326..328 + 0: SCSS_EXPRESSION_ITEM_LIST@326..328 + 0: CSS_NUMBER@326..328 + 0: CSS_NUMBER_LITERAL@326..328 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@328..336 + 0: SCSS_VARIABLE_MODIFIER@328..336 + 0: BANG@328..329 "!" [] [] + 1: DEFAULT_KW@329..336 "default" [] [] + 4: (empty) + 15: CSS_NESTED_QUALIFIED_RULE@336..363 + 0: CSS_RELATIVE_SELECTOR_LIST@336..348 + 0: CSS_RELATIVE_SELECTOR@336..348 + 0: TILDE@336..341 "~" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: CSS_COMPOUND_SELECTOR@341..348 + 0: CSS_NESTED_SELECTOR_LIST@341..341 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@341..348 + 0: CSS_CLASS_SELECTOR@341..348 + 0: DOT@341..342 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@342..348 + 0: IDENT@342..348 "later" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@348..363 + 0: L_CURLY@348..350 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@350..362 + 0: CSS_DECLARATION_WITH_SEMICOLON@350..362 + 0: CSS_DECLARATION@350..360 + 0: CSS_GENERIC_PROPERTY@350..360 + 0: CSS_IDENTIFIER@350..355 + 0: IDENT@350..355 "color" [] [] + 1: COLON@355..357 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@357..360 + 0: SCSS_EXPRESSION_ITEM_LIST@357..360 + 0: CSS_IDENTIFIER@357..360 + 0: IDENT@357..360 "red" [] [] + 1: (empty) + 1: SEMICOLON@360..362 ";" [] [Whitespace(" ")] + 2: R_CURLY@362..363 "}" [] [] + 16: SCSS_DECLARATION@363..382 + 0: SCSS_IDENTIFIER@363..370 + 0: DOLLAR@363..368 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@368..370 + 0: IDENT@368..370 "v8" [] [] + 1: COLON@370..372 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@372..374 + 0: SCSS_EXPRESSION_ITEM_LIST@372..374 + 0: CSS_NUMBER@372..374 + 0: CSS_NUMBER_LITERAL@372..374 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@374..382 + 0: SCSS_VARIABLE_MODIFIER@374..382 + 0: BANG@374..375 "!" [] [] + 1: DEFAULT_KW@375..382 "default" [] [] + 4: (empty) + 17: CSS_NESTED_QUALIFIED_RULE@382..411 + 0: CSS_RELATIVE_SELECTOR_LIST@382..396 + 0: CSS_RELATIVE_SELECTOR@382..396 + 0: PIPE2@382..388 "||" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: CSS_COMPOUND_SELECTOR@388..396 + 0: CSS_NESTED_SELECTOR_LIST@388..388 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@388..396 + 0: CSS_CLASS_SELECTOR@388..396 + 0: DOT@388..389 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@389..396 + 0: IDENT@389..396 "column" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@396..411 + 0: L_CURLY@396..398 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@398..410 + 0: CSS_DECLARATION_WITH_SEMICOLON@398..410 + 0: CSS_DECLARATION@398..408 + 0: CSS_GENERIC_PROPERTY@398..408 + 0: CSS_IDENTIFIER@398..403 + 0: IDENT@398..403 "color" [] [] + 1: COLON@403..405 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@405..408 + 0: SCSS_EXPRESSION_ITEM_LIST@405..408 + 0: CSS_IDENTIFIER@405..408 + 0: IDENT@405..408 "red" [] [] + 1: (empty) + 1: SEMICOLON@408..410 ";" [] [Whitespace(" ")] + 2: R_CURLY@410..411 "}" [] [] + 18: SCSS_DECLARATION@411..430 + 0: SCSS_IDENTIFIER@411..418 + 0: DOLLAR@411..416 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@416..418 + 0: IDENT@416..418 "v9" [] [] + 1: COLON@418..420 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@420..422 + 0: SCSS_EXPRESSION_ITEM_LIST@420..422 + 0: CSS_NUMBER@420..422 + 0: CSS_NUMBER_LITERAL@420..422 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@422..430 + 0: SCSS_VARIABLE_MODIFIER@422..430 + 0: BANG@422..423 "!" [] [] + 1: DEFAULT_KW@423..430 "default" [] [] + 4: (empty) + 19: CSS_NESTED_QUALIFIED_RULE@430..450 + 0: CSS_RELATIVE_SELECTOR_LIST@430..435 + 0: CSS_RELATIVE_SELECTOR@430..435 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@430..435 + 0: CSS_NESTED_SELECTOR_LIST@430..430 + 1: CSS_UNIVERSAL_SELECTOR@430..435 + 0: (empty) + 1: STAR@430..435 "*" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@435..435 + 1: CSS_DECLARATION_OR_RULE_BLOCK@435..450 + 0: L_CURLY@435..437 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@437..449 + 0: CSS_DECLARATION_WITH_SEMICOLON@437..449 + 0: CSS_DECLARATION@437..447 + 0: CSS_GENERIC_PROPERTY@437..447 + 0: CSS_IDENTIFIER@437..442 + 0: IDENT@437..442 "color" [] [] + 1: COLON@442..444 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@444..447 + 0: SCSS_EXPRESSION_ITEM_LIST@444..447 + 0: CSS_IDENTIFIER@444..447 + 0: IDENT@444..447 "red" [] [] + 1: (empty) + 1: SEMICOLON@447..449 ";" [] [Whitespace(" ")] + 2: R_CURLY@449..450 "}" [] [] + 20: SCSS_DECLARATION@450..470 + 0: SCSS_IDENTIFIER@450..458 + 0: DOLLAR@450..455 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@455..458 + 0: IDENT@455..458 "v10" [] [] + 1: COLON@458..460 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@460..462 + 0: SCSS_EXPRESSION_ITEM_LIST@460..462 + 0: CSS_NUMBER@460..462 + 0: CSS_NUMBER_LITERAL@460..462 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@462..470 + 0: SCSS_VARIABLE_MODIFIER@462..470 + 0: BANG@462..463 "!" [] [] + 1: DEFAULT_KW@463..470 "default" [] [] + 4: (empty) + 21: CSS_NESTED_QUALIFIED_RULE@470..494 + 0: CSS_RELATIVE_SELECTOR_LIST@470..479 + 0: CSS_RELATIVE_SELECTOR@470..479 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@470..479 + 0: CSS_NESTED_SELECTOR_LIST@470..470 + 1: CSS_TYPE_SELECTOR@470..479 + 0: CSS_NAMESPACE@470..477 + 0: CSS_NAMED_NAMESPACE_PREFIX@470..476 + 0: CSS_IDENTIFIER@470..476 + 0: IDENT@470..476 "svg" [Newline("\n"), Whitespace(" ")] [] + 1: PIPE@476..477 "|" [] [] + 1: CSS_IDENTIFIER@477..479 + 0: IDENT@477..479 "a" [] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@479..479 + 1: CSS_DECLARATION_OR_RULE_BLOCK@479..494 + 0: L_CURLY@479..481 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@481..493 + 0: CSS_DECLARATION_WITH_SEMICOLON@481..493 + 0: CSS_DECLARATION@481..491 + 0: CSS_GENERIC_PROPERTY@481..491 + 0: CSS_IDENTIFIER@481..486 + 0: IDENT@481..486 "color" [] [] + 1: COLON@486..488 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@488..491 + 0: SCSS_EXPRESSION_ITEM_LIST@488..491 + 0: CSS_IDENTIFIER@488..491 + 0: IDENT@488..491 "red" [] [] + 1: (empty) + 1: SEMICOLON@491..493 ";" [] [Whitespace(" ")] + 2: R_CURLY@493..494 "}" [] [] + 22: SCSS_DECLARATION@494..514 + 0: SCSS_IDENTIFIER@494..502 + 0: DOLLAR@494..499 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@499..502 + 0: IDENT@499..502 "v11" [] [] + 1: COLON@502..504 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@504..506 + 0: SCSS_EXPRESSION_ITEM_LIST@504..506 + 0: CSS_NUMBER@504..506 + 0: CSS_NUMBER_LITERAL@504..506 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@506..514 + 0: SCSS_VARIABLE_MODIFIER@506..514 + 0: BANG@506..507 "!" [] [] + 1: DEFAULT_KW@507..514 "default" [] [] + 4: (empty) + 23: CSS_NESTED_QUALIFIED_RULE@514..536 + 0: CSS_RELATIVE_SELECTOR_LIST@514..521 + 0: CSS_RELATIVE_SELECTOR@514..521 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@514..521 + 0: CSS_NESTED_SELECTOR_LIST@514..514 + 1: CSS_TYPE_SELECTOR@514..518 + 0: (empty) + 1: CSS_IDENTIFIER@514..518 + 0: IDENT@514..518 "a" [Newline("\n"), Whitespace(" ")] [] + 2: CSS_SUB_SELECTOR_LIST@518..521 + 0: CSS_CLASS_SELECTOR@518..521 + 0: DOT@518..519 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@519..521 + 0: IDENT@519..521 "b" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@521..536 + 0: L_CURLY@521..523 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@523..535 + 0: CSS_DECLARATION_WITH_SEMICOLON@523..535 + 0: CSS_DECLARATION@523..533 + 0: CSS_GENERIC_PROPERTY@523..533 + 0: CSS_IDENTIFIER@523..528 + 0: IDENT@523..528 "color" [] [] + 1: COLON@528..530 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@530..533 + 0: SCSS_EXPRESSION_ITEM_LIST@530..533 + 0: CSS_IDENTIFIER@530..533 + 0: IDENT@530..533 "red" [] [] + 1: (empty) + 1: SEMICOLON@533..535 ";" [] [Whitespace(" ")] + 2: R_CURLY@535..536 "}" [] [] + 24: SCSS_DECLARATION@536..556 + 0: SCSS_IDENTIFIER@536..544 + 0: DOLLAR@536..541 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@541..544 + 0: IDENT@541..544 "v12" [] [] + 1: COLON@544..546 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@546..548 + 0: SCSS_EXPRESSION_ITEM_LIST@546..548 + 0: CSS_NUMBER@546..548 + 0: CSS_NUMBER_LITERAL@546..548 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@548..556 + 0: SCSS_VARIABLE_MODIFIER@548..556 + 0: BANG@548..549 "!" [] [] + 1: DEFAULT_KW@549..556 "default" [] [] + 4: (empty) + 25: CSS_NESTED_QUALIFIED_RULE@556..579 + 0: CSS_RELATIVE_SELECTOR_LIST@556..564 + 0: CSS_RELATIVE_SELECTOR@556..564 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@556..564 + 0: CSS_NESTED_SELECTOR_LIST@556..556 + 1: CSS_TYPE_SELECTOR@556..560 + 0: (empty) + 1: CSS_IDENTIFIER@556..560 + 0: IDENT@556..560 "a" [Newline("\n"), Whitespace(" ")] [] + 2: CSS_SUB_SELECTOR_LIST@560..564 + 0: CSS_ID_SELECTOR@560..564 + 0: HASH@560..561 "#" [] [] + 1: CSS_CUSTOM_IDENTIFIER@561..564 + 0: IDENT@561..564 "id" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@564..579 + 0: L_CURLY@564..566 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@566..578 + 0: CSS_DECLARATION_WITH_SEMICOLON@566..578 + 0: CSS_DECLARATION@566..576 + 0: CSS_GENERIC_PROPERTY@566..576 + 0: CSS_IDENTIFIER@566..571 + 0: IDENT@566..571 "color" [] [] + 1: COLON@571..573 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@573..576 + 0: SCSS_EXPRESSION_ITEM_LIST@573..576 + 0: CSS_IDENTIFIER@573..576 + 0: IDENT@573..576 "red" [] [] + 1: (empty) + 1: SEMICOLON@576..578 ";" [] [Whitespace(" ")] + 2: R_CURLY@578..579 "}" [] [] + 26: SCSS_DECLARATION@579..599 + 0: SCSS_IDENTIFIER@579..587 + 0: DOLLAR@579..584 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@584..587 + 0: IDENT@584..587 "v13" [] [] + 1: COLON@587..589 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@589..591 + 0: SCSS_EXPRESSION_ITEM_LIST@589..591 + 0: CSS_NUMBER@589..591 + 0: CSS_NUMBER_LITERAL@589..591 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@591..599 + 0: SCSS_VARIABLE_MODIFIER@591..599 + 0: BANG@591..592 "!" [] [] + 1: DEFAULT_KW@592..599 "default" [] [] + 4: (empty) + 27: CSS_NESTED_QUALIFIED_RULE@599..625 + 0: CSS_RELATIVE_SELECTOR_LIST@599..610 + 0: CSS_RELATIVE_SELECTOR@599..610 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@599..610 + 0: CSS_NESTED_SELECTOR_LIST@599..599 + 1: CSS_TYPE_SELECTOR@599..603 + 0: (empty) + 1: CSS_IDENTIFIER@599..603 + 0: IDENT@599..603 "a" [Newline("\n"), Whitespace(" ")] [] + 2: CSS_SUB_SELECTOR_LIST@603..610 + 0: CSS_ATTRIBUTE_SELECTOR@603..610 + 0: L_BRACK@603..604 "[" [] [] + 1: CSS_ATTRIBUTE_NAME@604..608 + 0: (empty) + 1: CSS_IDENTIFIER@604..608 + 0: IDENT@604..608 "attr" [] [] + 2: (empty) + 3: R_BRACK@608..610 "]" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@610..625 + 0: L_CURLY@610..612 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@612..624 + 0: CSS_DECLARATION_WITH_SEMICOLON@612..624 + 0: CSS_DECLARATION@612..622 + 0: CSS_GENERIC_PROPERTY@612..622 + 0: CSS_IDENTIFIER@612..617 + 0: IDENT@612..617 "color" [] [] + 1: COLON@617..619 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@619..622 + 0: SCSS_EXPRESSION_ITEM_LIST@619..622 + 0: CSS_IDENTIFIER@619..622 + 0: IDENT@619..622 "red" [] [] + 1: (empty) + 1: SEMICOLON@622..624 ";" [] [Whitespace(" ")] + 2: R_CURLY@624..625 "}" [] [] + 28: SCSS_DECLARATION@625..645 + 0: SCSS_IDENTIFIER@625..633 + 0: DOLLAR@625..630 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@630..633 + 0: IDENT@630..633 "v14" [] [] + 1: COLON@633..635 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@635..637 + 0: SCSS_EXPRESSION_ITEM_LIST@635..637 + 0: CSS_NUMBER@635..637 + 0: CSS_NUMBER_LITERAL@635..637 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@637..645 + 0: SCSS_VARIABLE_MODIFIER@637..645 + 0: BANG@637..638 "!" [] [] + 1: DEFAULT_KW@638..645 "default" [] [] + 4: (empty) + 29: CSS_NESTED_QUALIFIED_RULE@645..673 + 0: CSS_RELATIVE_SELECTOR_LIST@645..658 + 0: CSS_RELATIVE_SELECTOR@645..658 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@645..658 + 0: CSS_NESTED_SELECTOR_LIST@645..645 + 1: CSS_TYPE_SELECTOR@645..649 + 0: (empty) + 1: CSS_IDENTIFIER@645..649 + 0: IDENT@645..649 "a" [Newline("\n"), Whitespace(" ")] [] + 2: CSS_SUB_SELECTOR_LIST@649..658 + 0: CSS_PSEUDO_ELEMENT_SELECTOR@649..658 + 0: COLON2@649..651 "::" [] [] + 1: CSS_PSEUDO_ELEMENT_IDENTIFIER@651..658 + 0: CSS_IDENTIFIER@651..658 + 0: IDENT@651..658 "before" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@658..673 + 0: L_CURLY@658..660 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@660..672 + 0: CSS_DECLARATION_WITH_SEMICOLON@660..672 + 0: CSS_DECLARATION@660..670 + 0: CSS_GENERIC_PROPERTY@660..670 + 0: CSS_IDENTIFIER@660..665 + 0: IDENT@660..665 "color" [] [] + 1: COLON@665..667 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@667..670 + 0: SCSS_EXPRESSION_ITEM_LIST@667..670 + 0: CSS_IDENTIFIER@667..670 + 0: IDENT@667..670 "red" [] [] + 1: (empty) + 1: SEMICOLON@670..672 ";" [] [Whitespace(" ")] + 2: R_CURLY@672..673 "}" [] [] + 30: SCSS_DECLARATION@673..693 + 0: SCSS_IDENTIFIER@673..681 + 0: DOLLAR@673..678 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@678..681 + 0: IDENT@678..681 "v15" [] [] + 1: COLON@681..683 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@683..685 + 0: SCSS_EXPRESSION_ITEM_LIST@683..685 + 0: CSS_NUMBER@683..685 + 0: CSS_NUMBER_LITERAL@683..685 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@685..693 + 0: SCSS_VARIABLE_MODIFIER@685..693 + 0: BANG@685..686 "!" [] [] + 1: DEFAULT_KW@686..693 "default" [] [] + 4: (empty) + 31: CSS_NESTED_QUALIFIED_RULE@693..721 + 0: CSS_RELATIVE_SELECTOR_LIST@693..706 + 0: CSS_RELATIVE_SELECTOR@693..706 + 0: (empty) + 1: CSS_COMPLEX_SELECTOR@693..706 + 0: CSS_COMPOUND_SELECTOR@693..698 + 0: CSS_NESTED_SELECTOR_LIST@693..693 + 1: CSS_TYPE_SELECTOR@693..698 + 0: (empty) + 1: CSS_IDENTIFIER@693..698 + 0: IDENT@693..698 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@698..698 + 1: R_ANGLE@698..700 ">" [] [Whitespace(" ")] + 2: CSS_COMPOUND_SELECTOR@700..706 + 0: CSS_NESTED_SELECTOR_LIST@700..700 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@700..706 + 0: CSS_CLASS_SELECTOR@700..706 + 0: DOT@700..701 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@701..706 + 0: IDENT@701..706 "desc" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@706..721 + 0: L_CURLY@706..708 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@708..720 + 0: CSS_DECLARATION_WITH_SEMICOLON@708..720 + 0: CSS_DECLARATION@708..718 + 0: CSS_GENERIC_PROPERTY@708..718 + 0: CSS_IDENTIFIER@708..713 + 0: IDENT@708..713 "color" [] [] + 1: COLON@713..715 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@715..718 + 0: SCSS_EXPRESSION_ITEM_LIST@715..718 + 0: CSS_IDENTIFIER@715..718 + 0: IDENT@715..718 "red" [] [] + 1: (empty) + 1: SEMICOLON@718..720 ";" [] [Whitespace(" ")] + 2: R_CURLY@720..721 "}" [] [] + 32: SCSS_DECLARATION@721..741 + 0: SCSS_IDENTIFIER@721..729 + 0: DOLLAR@721..726 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@726..729 + 0: IDENT@726..729 "v16" [] [] + 1: COLON@729..731 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@731..733 + 0: SCSS_EXPRESSION_ITEM_LIST@731..733 + 0: CSS_NUMBER@731..733 + 0: CSS_NUMBER_LITERAL@731..733 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@733..741 + 0: SCSS_VARIABLE_MODIFIER@733..741 + 0: BANG@733..734 "!" [] [] + 1: DEFAULT_KW@734..741 "default" [] [] + 4: (empty) + 33: CSS_NESTED_QUALIFIED_RULE@741..768 + 0: CSS_RELATIVE_SELECTOR_LIST@741..753 + 0: CSS_RELATIVE_SELECTOR@741..753 + 0: (empty) + 1: CSS_COMPLEX_SELECTOR@741..753 + 0: CSS_COMPOUND_SELECTOR@741..746 + 0: CSS_NESTED_SELECTOR_LIST@741..741 + 1: CSS_TYPE_SELECTOR@741..746 + 0: (empty) + 1: CSS_IDENTIFIER@741..746 + 0: IDENT@741..746 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@746..746 + 1: PLUS@746..748 "+" [] [Whitespace(" ")] + 2: CSS_COMPOUND_SELECTOR@748..753 + 0: CSS_NESTED_SELECTOR_LIST@748..748 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@748..753 + 0: CSS_CLASS_SELECTOR@748..753 + 0: DOT@748..749 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@749..753 + 0: IDENT@749..753 "adj" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@753..768 + 0: L_CURLY@753..755 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@755..767 + 0: CSS_DECLARATION_WITH_SEMICOLON@755..767 + 0: CSS_DECLARATION@755..765 + 0: CSS_GENERIC_PROPERTY@755..765 + 0: CSS_IDENTIFIER@755..760 + 0: IDENT@755..760 "color" [] [] + 1: COLON@760..762 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@762..765 + 0: SCSS_EXPRESSION_ITEM_LIST@762..765 + 0: CSS_IDENTIFIER@762..765 + 0: IDENT@762..765 "red" [] [] + 1: (empty) + 1: SEMICOLON@765..767 ";" [] [Whitespace(" ")] + 2: R_CURLY@767..768 "}" [] [] + 34: SCSS_DECLARATION@768..788 + 0: SCSS_IDENTIFIER@768..776 + 0: DOLLAR@768..773 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@773..776 + 0: IDENT@773..776 "v17" [] [] + 1: COLON@776..778 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@778..780 + 0: SCSS_EXPRESSION_ITEM_LIST@778..780 + 0: CSS_NUMBER@778..780 + 0: CSS_NUMBER_LITERAL@778..780 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@780..788 + 0: SCSS_VARIABLE_MODIFIER@780..788 + 0: BANG@780..781 "!" [] [] + 1: DEFAULT_KW@781..788 "default" [] [] + 4: (empty) + 35: CSS_NESTED_QUALIFIED_RULE@788..815 + 0: CSS_RELATIVE_SELECTOR_LIST@788..800 + 0: CSS_RELATIVE_SELECTOR@788..800 + 0: (empty) + 1: CSS_COMPLEX_SELECTOR@788..800 + 0: CSS_COMPOUND_SELECTOR@788..793 + 0: CSS_NESTED_SELECTOR_LIST@788..788 + 1: CSS_TYPE_SELECTOR@788..793 + 0: (empty) + 1: CSS_IDENTIFIER@788..793 + 0: IDENT@788..793 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@793..793 + 1: TILDE@793..795 "~" [] [Whitespace(" ")] + 2: CSS_COMPOUND_SELECTOR@795..800 + 0: CSS_NESTED_SELECTOR_LIST@795..795 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@795..800 + 0: CSS_CLASS_SELECTOR@795..800 + 0: DOT@795..796 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@796..800 + 0: IDENT@796..800 "sib" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@800..815 + 0: L_CURLY@800..802 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@802..814 + 0: CSS_DECLARATION_WITH_SEMICOLON@802..814 + 0: CSS_DECLARATION@802..812 + 0: CSS_GENERIC_PROPERTY@802..812 + 0: CSS_IDENTIFIER@802..807 + 0: IDENT@802..807 "color" [] [] + 1: COLON@807..809 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@809..812 + 0: SCSS_EXPRESSION_ITEM_LIST@809..812 + 0: CSS_IDENTIFIER@809..812 + 0: IDENT@809..812 "red" [] [] + 1: (empty) + 1: SEMICOLON@812..814 ";" [] [Whitespace(" ")] + 2: R_CURLY@814..815 "}" [] [] + 36: SCSS_DECLARATION@815..835 + 0: SCSS_IDENTIFIER@815..823 + 0: DOLLAR@815..820 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@820..823 + 0: IDENT@820..823 "v18" [] [] + 1: COLON@823..825 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@825..827 + 0: SCSS_EXPRESSION_ITEM_LIST@825..827 + 0: CSS_NUMBER@825..827 + 0: CSS_NUMBER_LITERAL@825..827 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@827..835 + 0: SCSS_VARIABLE_MODIFIER@827..835 + 0: BANG@827..828 "!" [] [] + 1: DEFAULT_KW@828..835 "default" [] [] + 4: (empty) + 37: CSS_NESTED_QUALIFIED_RULE@835..863 + 0: CSS_RELATIVE_SELECTOR_LIST@835..848 + 0: CSS_RELATIVE_SELECTOR@835..848 + 0: (empty) + 1: CSS_COMPLEX_SELECTOR@835..848 + 0: CSS_COMPOUND_SELECTOR@835..840 + 0: CSS_NESTED_SELECTOR_LIST@835..835 + 1: CSS_TYPE_SELECTOR@835..840 + 0: (empty) + 1: CSS_IDENTIFIER@835..840 + 0: IDENT@835..840 "a" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@840..840 + 1: PIPE2@840..843 "||" [] [Whitespace(" ")] + 2: CSS_COMPOUND_SELECTOR@843..848 + 0: CSS_NESTED_SELECTOR_LIST@843..843 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@843..848 + 0: CSS_CLASS_SELECTOR@843..848 + 0: DOT@843..844 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@844..848 + 0: IDENT@844..848 "col" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@848..863 + 0: L_CURLY@848..850 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@850..862 + 0: CSS_DECLARATION_WITH_SEMICOLON@850..862 + 0: CSS_DECLARATION@850..860 + 0: CSS_GENERIC_PROPERTY@850..860 + 0: CSS_IDENTIFIER@850..855 + 0: IDENT@850..855 "color" [] [] + 1: COLON@855..857 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@857..860 + 0: SCSS_EXPRESSION_ITEM_LIST@857..860 + 0: CSS_IDENTIFIER@857..860 + 0: IDENT@857..860 "red" [] [] + 1: (empty) + 1: SEMICOLON@860..862 ";" [] [Whitespace(" ")] + 2: R_CURLY@862..863 "}" [] [] + 38: SCSS_DECLARATION@863..883 + 0: SCSS_IDENTIFIER@863..871 + 0: DOLLAR@863..868 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@868..871 + 0: IDENT@868..871 "v19" [] [] + 1: COLON@871..873 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@873..875 + 0: SCSS_EXPRESSION_ITEM_LIST@873..875 + 0: CSS_NUMBER@873..875 + 0: CSS_NUMBER_LITERAL@873..875 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@875..883 + 0: SCSS_VARIABLE_MODIFIER@875..883 + 0: BANG@875..876 "!" [] [] + 1: DEFAULT_KW@876..883 "default" [] [] + 4: (empty) + 39: CSS_AT_RULE@883..928 + 0: AT@883..887 "@" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_MEDIA_AT_RULE@887..928 + 0: CSS_MEDIA_AT_RULE_DECLARATOR@887..900 + 0: MEDIA_KW@887..893 "media" [] [Whitespace(" ")] + 1: CSS_MEDIA_QUERY_LIST@893..900 + 0: CSS_MEDIA_TYPE_QUERY@893..900 + 0: (empty) + 1: CSS_MEDIA_TYPE@893..900 + 0: CSS_IDENTIFIER@893..900 + 0: IDENT@893..900 "screen" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@900..928 + 0: L_CURLY@900..901 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@901..924 + 0: CSS_NESTED_QUALIFIED_RULE@901..924 + 0: CSS_RELATIVE_SELECTOR_LIST@901..909 + 0: CSS_RELATIVE_SELECTOR@901..909 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@901..909 + 0: CSS_NESTED_SELECTOR_LIST@901..901 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@901..909 + 0: CSS_CLASS_SELECTOR@901..909 + 0: DOT@901..907 "." [Newline("\n"), Whitespace(" ")] [] + 1: CSS_CUSTOM_IDENTIFIER@907..909 + 0: IDENT@907..909 "m" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@909..924 + 0: L_CURLY@909..911 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@911..923 + 0: CSS_DECLARATION_WITH_SEMICOLON@911..923 + 0: CSS_DECLARATION@911..921 + 0: CSS_GENERIC_PROPERTY@911..921 + 0: CSS_IDENTIFIER@911..916 + 0: IDENT@911..916 "color" [] [] + 1: COLON@916..918 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@918..921 + 0: SCSS_EXPRESSION_ITEM_LIST@918..921 + 0: CSS_IDENTIFIER@918..921 + 0: IDENT@918..921 "red" [] [] + 1: (empty) + 1: SEMICOLON@921..923 ";" [] [Whitespace(" ")] + 2: R_CURLY@923..924 "}" [] [] + 2: R_CURLY@924..928 "}" [Newline("\n"), Whitespace(" ")] [] + 40: SCSS_DECLARATION@928..948 + 0: SCSS_IDENTIFIER@928..936 + 0: DOLLAR@928..933 "$" [Newline("\n"), Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@933..936 + 0: IDENT@933..936 "v20" [] [] + 1: COLON@936..938 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@938..940 + 0: SCSS_EXPRESSION_ITEM_LIST@938..940 + 0: CSS_NUMBER@938..940 + 0: CSS_NUMBER_LITERAL@938..940 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@940..948 + 0: SCSS_VARIABLE_MODIFIER@940..948 + 0: BANG@940..941 "!" [] [] + 1: DEFAULT_KW@941..948 "default" [] [] + 4: (empty) + 41: CSS_DECLARATION_WITH_SEMICOLON@948..962 + 0: CSS_DECLARATION@948..961 + 0: CSS_GENERIC_PROPERTY@948..961 + 0: CSS_IDENTIFIER@948..956 + 0: IDENT@948..956 "color" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@956..958 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@958..961 + 0: SCSS_EXPRESSION_ITEM_LIST@958..961 + 0: CSS_IDENTIFIER@958..961 + 0: IDENT@958..961 "red" [] [] + 1: (empty) + 1: SEMICOLON@961..962 ";" [] [] + 2: R_CURLY@962..964 "}" [Newline("\n")] [] + 2: EOF@964..965 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +missing-semicolon-boundary-matrix.scss:3:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `.` + + 1 │ a { + 2 │ $v0: 1 !default + > 3 │ .class { color: red; } + │ ^ + 4 │ + 5 │ $v1: 1 !default + + i Remove . + +missing-semicolon-boundary-matrix.scss:6:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `#` + + 5 │ $v1: 1 !default + > 6 │ #id { color: red; } + │ ^ + 7 │ + 8 │ $v2: 1 !default + + i Remove # + +missing-semicolon-boundary-matrix.scss:9:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `:` + + 8 │ $v2: 1 !default + > 9 │ :hover { color: red; } + │ ^ + 10 │ + 11 │ $v3: 1 !default + + i Remove : + +missing-semicolon-boundary-matrix.scss:12:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `[` + + 11 │ $v3: 1 !default + > 12 │ [data-x] { color: red; } + │ ^ + 13 │ + 14 │ $v4: 1 !default + + i Remove [ + +missing-semicolon-boundary-matrix.scss:15:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `&` + + 14 │ $v4: 1 !default + > 15 │ &.nested { color: red; } + │ ^ + 16 │ + 17 │ $v5: 1 !default + + i Remove & + +missing-semicolon-boundary-matrix.scss:18:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `>` + + 17 │ $v5: 1 !default + > 18 │ > .child { color: red; } + │ ^ + 19 │ + 20 │ $v6: 1 !default + + i Remove > + +missing-semicolon-boundary-matrix.scss:21:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `+` + + 20 │ $v6: 1 !default + > 21 │ + .sibling { color: red; } + │ ^ + 22 │ + 23 │ $v7: 1 !default + + i Remove + + +missing-semicolon-boundary-matrix.scss:24:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `~` + + 23 │ $v7: 1 !default + > 24 │ ~ .later { color: red; } + │ ^ + 25 │ + 26 │ $v8: 1 !default + + i Remove ~ + +missing-semicolon-boundary-matrix.scss:27:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `||` + + 26 │ $v8: 1 !default + > 27 │ || .column { color: red; } + │ ^^ + 28 │ + 29 │ $v9: 1 !default + + i Remove || + +missing-semicolon-boundary-matrix.scss:30:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `*` + + 29 │ $v9: 1 !default + > 30 │ * { color: red; } + │ ^ + 31 │ + 32 │ $v10: 1 !default + + i Remove * + +missing-semicolon-boundary-matrix.scss:33:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `svg` + + 32 │ $v10: 1 !default + > 33 │ svg|a { color: red; } + │ ^^^ + 34 │ + 35 │ $v11: 1 !default + + i Remove svg + +missing-semicolon-boundary-matrix.scss:36:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 35 │ $v11: 1 !default + > 36 │ a.b { color: red; } + │ ^ + 37 │ + 38 │ $v12: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:39:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 38 │ $v12: 1 !default + > 39 │ a#id { color: red; } + │ ^ + 40 │ + 41 │ $v13: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:42:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 41 │ $v13: 1 !default + > 42 │ a[attr] { color: red; } + │ ^ + 43 │ + 44 │ $v14: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:45:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 44 │ $v14: 1 !default + > 45 │ a::before { color: red; } + │ ^ + 46 │ + 47 │ $v15: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:48:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 47 │ $v15: 1 !default + > 48 │ a > .desc { color: red; } + │ ^ + 49 │ + 50 │ $v16: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:51:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 50 │ $v16: 1 !default + > 51 │ a + .adj { color: red; } + │ ^ + 52 │ + 53 │ $v17: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:54:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 53 │ $v17: 1 !default + > 54 │ a ~ .sib { color: red; } + │ ^ + 55 │ + 56 │ $v18: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:57:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 56 │ $v18: 1 !default + > 57 │ a || .col { color: red; } + │ ^ + 58 │ + 59 │ $v19: 1 !default + + i Remove a + +missing-semicolon-boundary-matrix.scss:60:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `@` + + 59 │ $v19: 1 !default + > 60 │ @media screen { + │ ^ + 61 │ .m { color: red; } + 62 │ } + + i Remove @ + +missing-semicolon-boundary-matrix.scss:65:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `color` + + 64 │ $v20: 1 !default + > 65 │ color: red; + │ ^^^^^ + 66 │ } + 67 │ + + i Remove color + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-namespace-selector-recovery.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-namespace-selector-recovery.scss new file mode 100644 index 000000000000..5158fb0dce7d --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-namespace-selector-recovery.scss @@ -0,0 +1,5 @@ +a { + $x: 1 !default + svg|a { color: red; } + width: 1px; +} diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-namespace-selector-recovery.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-namespace-selector-recovery.scss.snap new file mode 100644 index 000000000000..ed54978d8403 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-namespace-selector-recovery.scss.snap @@ -0,0 +1,239 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +a { + $x: 1 !default + svg|a { color: red; } + width: 1px; +} + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@0..2 "a" [] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@2..3 "{" [] [], + items: CssDeclarationOrRuleList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@7..8 "x" [] [], + }, + }, + colon_token: COLON@8..10 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@12..13 "!" [] [], + value: DEFAULT_KW@13..20 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: CssNamespace { + prefix: CssNamedNamespacePrefix { + name: CssIdentifier { + value_token: IDENT@20..26 "svg" [Newline("\n"), Whitespace(" ")] [], + }, + }, + bitwise_or_token: PIPE@26..27 "|" [] [], + }, + ident: CssIdentifier { + value_token: IDENT@27..29 "a" [] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@29..31 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@31..36 "color" [] [], + }, + colon_token: COLON@36..38 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@38..41 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@41..43 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@43..44 "}" [] [], + }, + }, + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@44..52 "width" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@52..54 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssRegularDimension { + value_token: CSS_NUMBER_LITERAL@54..55 "1" [] [], + unit_token: IDENT@55..57 "px" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@57..58 ";" [] [], + }, + ], + r_curly_token: R_CURLY@58..60 "}" [Newline("\n")] [], + }, + }, + ], + eof_token: EOF@60..61 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..61 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..60 + 0: CSS_QUALIFIED_RULE@0..60 + 0: CSS_SELECTOR_LIST@0..2 + 0: CSS_COMPOUND_SELECTOR@0..2 + 0: CSS_NESTED_SELECTOR_LIST@0..0 + 1: CSS_TYPE_SELECTOR@0..2 + 0: (empty) + 1: CSS_IDENTIFIER@0..2 + 0: IDENT@0..2 "a" [] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@2..2 + 1: CSS_DECLARATION_OR_RULE_BLOCK@2..60 + 0: L_CURLY@2..3 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@3..58 + 0: SCSS_DECLARATION@3..20 + 0: SCSS_IDENTIFIER@3..8 + 0: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@7..8 + 0: IDENT@7..8 "x" [] [] + 1: COLON@8..10 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@10..12 + 0: SCSS_EXPRESSION_ITEM_LIST@10..12 + 0: CSS_NUMBER@10..12 + 0: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@12..20 + 0: SCSS_VARIABLE_MODIFIER@12..20 + 0: BANG@12..13 "!" [] [] + 1: DEFAULT_KW@13..20 "default" [] [] + 4: (empty) + 1: CSS_NESTED_QUALIFIED_RULE@20..44 + 0: CSS_RELATIVE_SELECTOR_LIST@20..29 + 0: CSS_RELATIVE_SELECTOR@20..29 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@20..29 + 0: CSS_NESTED_SELECTOR_LIST@20..20 + 1: CSS_TYPE_SELECTOR@20..29 + 0: CSS_NAMESPACE@20..27 + 0: CSS_NAMED_NAMESPACE_PREFIX@20..26 + 0: CSS_IDENTIFIER@20..26 + 0: IDENT@20..26 "svg" [Newline("\n"), Whitespace(" ")] [] + 1: PIPE@26..27 "|" [] [] + 1: CSS_IDENTIFIER@27..29 + 0: IDENT@27..29 "a" [] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@29..29 + 1: CSS_DECLARATION_OR_RULE_BLOCK@29..44 + 0: L_CURLY@29..31 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@31..43 + 0: CSS_DECLARATION_WITH_SEMICOLON@31..43 + 0: CSS_DECLARATION@31..41 + 0: CSS_GENERIC_PROPERTY@31..41 + 0: CSS_IDENTIFIER@31..36 + 0: IDENT@31..36 "color" [] [] + 1: COLON@36..38 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@38..41 + 0: SCSS_EXPRESSION_ITEM_LIST@38..41 + 0: CSS_IDENTIFIER@38..41 + 0: IDENT@38..41 "red" [] [] + 1: (empty) + 1: SEMICOLON@41..43 ";" [] [Whitespace(" ")] + 2: R_CURLY@43..44 "}" [] [] + 2: CSS_DECLARATION_WITH_SEMICOLON@44..58 + 0: CSS_DECLARATION@44..57 + 0: CSS_GENERIC_PROPERTY@44..57 + 0: CSS_IDENTIFIER@44..52 + 0: IDENT@44..52 "width" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@52..54 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@54..57 + 0: SCSS_EXPRESSION_ITEM_LIST@54..57 + 0: CSS_REGULAR_DIMENSION@54..57 + 0: CSS_NUMBER_LITERAL@54..55 "1" [] [] + 1: IDENT@55..57 "px" [] [] + 1: (empty) + 1: SEMICOLON@57..58 ";" [] [] + 2: R_CURLY@58..60 "}" [Newline("\n")] [] + 2: EOF@60..61 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +missing-semicolon-namespace-selector-recovery.scss:3:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `svg` + + 1 │ a { + 2 │ $x: 1 !default + > 3 │ svg|a { color: red; } + │ ^^^ + 4 │ width: 1px; + 5 │ } + + i Remove svg + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-recovery.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-recovery.scss new file mode 100644 index 000000000000..1f3bd215a7ce --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-recovery.scss @@ -0,0 +1,5 @@ +a { + $x: 1 !default + color: red; + width: 1px; +} diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-recovery.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-recovery.scss.snap new file mode 100644 index 000000000000..582eb190f756 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-recovery.scss.snap @@ -0,0 +1,190 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +a { + $x: 1 !default + color: red; + width: 1px; +} + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@0..2 "a" [] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@2..3 "{" [] [], + items: CssDeclarationOrRuleList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@7..8 "x" [] [], + }, + }, + colon_token: COLON@8..10 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@12..13 "!" [] [], + value: DEFAULT_KW@13..20 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@20..28 "color" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@28..30 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@30..33 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@33..34 ";" [] [], + }, + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@34..42 "width" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@42..44 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssRegularDimension { + value_token: CSS_NUMBER_LITERAL@44..45 "1" [] [], + unit_token: IDENT@45..47 "px" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@47..48 ";" [] [], + }, + ], + r_curly_token: R_CURLY@48..50 "}" [Newline("\n")] [], + }, + }, + ], + eof_token: EOF@50..51 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..51 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..50 + 0: CSS_QUALIFIED_RULE@0..50 + 0: CSS_SELECTOR_LIST@0..2 + 0: CSS_COMPOUND_SELECTOR@0..2 + 0: CSS_NESTED_SELECTOR_LIST@0..0 + 1: CSS_TYPE_SELECTOR@0..2 + 0: (empty) + 1: CSS_IDENTIFIER@0..2 + 0: IDENT@0..2 "a" [] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@2..2 + 1: CSS_DECLARATION_OR_RULE_BLOCK@2..50 + 0: L_CURLY@2..3 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@3..48 + 0: SCSS_DECLARATION@3..20 + 0: SCSS_IDENTIFIER@3..8 + 0: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@7..8 + 0: IDENT@7..8 "x" [] [] + 1: COLON@8..10 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@10..12 + 0: SCSS_EXPRESSION_ITEM_LIST@10..12 + 0: CSS_NUMBER@10..12 + 0: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@12..20 + 0: SCSS_VARIABLE_MODIFIER@12..20 + 0: BANG@12..13 "!" [] [] + 1: DEFAULT_KW@13..20 "default" [] [] + 4: (empty) + 1: CSS_DECLARATION_WITH_SEMICOLON@20..34 + 0: CSS_DECLARATION@20..33 + 0: CSS_GENERIC_PROPERTY@20..33 + 0: CSS_IDENTIFIER@20..28 + 0: IDENT@20..28 "color" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@28..30 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@30..33 + 0: SCSS_EXPRESSION_ITEM_LIST@30..33 + 0: CSS_IDENTIFIER@30..33 + 0: IDENT@30..33 "red" [] [] + 1: (empty) + 1: SEMICOLON@33..34 ";" [] [] + 2: CSS_DECLARATION_WITH_SEMICOLON@34..48 + 0: CSS_DECLARATION@34..47 + 0: CSS_GENERIC_PROPERTY@34..47 + 0: CSS_IDENTIFIER@34..42 + 0: IDENT@34..42 "width" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@42..44 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@44..47 + 0: SCSS_EXPRESSION_ITEM_LIST@44..47 + 0: CSS_REGULAR_DIMENSION@44..47 + 0: CSS_NUMBER_LITERAL@44..45 "1" [] [] + 1: IDENT@45..47 "px" [] [] + 1: (empty) + 1: SEMICOLON@47..48 ";" [] [] + 2: R_CURLY@48..50 "}" [Newline("\n")] [] + 2: EOF@50..51 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +missing-semicolon-recovery.scss:3:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `color` + + 1 │ a { + 2 │ $x: 1 !default + > 3 │ color: red; + │ ^^^^^ + 4 │ width: 1px; + 5 │ } + + i Remove color + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-relative-selector-recovery.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-relative-selector-recovery.scss new file mode 100644 index 000000000000..4ca95ec21174 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-relative-selector-recovery.scss @@ -0,0 +1,5 @@ +a { + $x: 1 !default + > .b { color: red; } + * { color: blue; } +} diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-relative-selector-recovery.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-relative-selector-recovery.scss.snap new file mode 100644 index 000000000000..ce6823eb8e0e --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-relative-selector-recovery.scss.snap @@ -0,0 +1,264 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +a { + $x: 1 !default + > .b { color: red; } + * { color: blue; } +} + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@0..2 "a" [] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@2..3 "{" [] [], + items: CssDeclarationOrRuleList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@7..8 "x" [] [], + }, + }, + colon_token: COLON@8..10 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@12..13 "!" [] [], + value: DEFAULT_KW@13..20 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: R_ANGLE@20..25 ">" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@25..26 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@26..28 "b" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@28..30 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@30..35 "color" [] [], + }, + colon_token: COLON@35..37 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@37..40 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@40..42 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@42..43 "}" [] [], + }, + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssUniversalSelector { + namespace: missing (optional), + star_token: STAR@43..48 "*" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + sub_selectors: CssSubSelectorList [], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@48..50 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@50..55 "color" [] [], + }, + colon_token: COLON@55..57 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@57..61 "blue" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@61..63 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@63..64 "}" [] [], + }, + }, + ], + r_curly_token: R_CURLY@64..66 "}" [Newline("\n")] [], + }, + }, + ], + eof_token: EOF@66..67 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..67 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..66 + 0: CSS_QUALIFIED_RULE@0..66 + 0: CSS_SELECTOR_LIST@0..2 + 0: CSS_COMPOUND_SELECTOR@0..2 + 0: CSS_NESTED_SELECTOR_LIST@0..0 + 1: CSS_TYPE_SELECTOR@0..2 + 0: (empty) + 1: CSS_IDENTIFIER@0..2 + 0: IDENT@0..2 "a" [] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@2..2 + 1: CSS_DECLARATION_OR_RULE_BLOCK@2..66 + 0: L_CURLY@2..3 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@3..64 + 0: SCSS_DECLARATION@3..20 + 0: SCSS_IDENTIFIER@3..8 + 0: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@7..8 + 0: IDENT@7..8 "x" [] [] + 1: COLON@8..10 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@10..12 + 0: SCSS_EXPRESSION_ITEM_LIST@10..12 + 0: CSS_NUMBER@10..12 + 0: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@12..20 + 0: SCSS_VARIABLE_MODIFIER@12..20 + 0: BANG@12..13 "!" [] [] + 1: DEFAULT_KW@13..20 "default" [] [] + 4: (empty) + 1: CSS_NESTED_QUALIFIED_RULE@20..43 + 0: CSS_RELATIVE_SELECTOR_LIST@20..28 + 0: CSS_RELATIVE_SELECTOR@20..28 + 0: R_ANGLE@20..25 ">" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: CSS_COMPOUND_SELECTOR@25..28 + 0: CSS_NESTED_SELECTOR_LIST@25..25 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@25..28 + 0: CSS_CLASS_SELECTOR@25..28 + 0: DOT@25..26 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@26..28 + 0: IDENT@26..28 "b" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@28..43 + 0: L_CURLY@28..30 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@30..42 + 0: CSS_DECLARATION_WITH_SEMICOLON@30..42 + 0: CSS_DECLARATION@30..40 + 0: CSS_GENERIC_PROPERTY@30..40 + 0: CSS_IDENTIFIER@30..35 + 0: IDENT@30..35 "color" [] [] + 1: COLON@35..37 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@37..40 + 0: SCSS_EXPRESSION_ITEM_LIST@37..40 + 0: CSS_IDENTIFIER@37..40 + 0: IDENT@37..40 "red" [] [] + 1: (empty) + 1: SEMICOLON@40..42 ";" [] [Whitespace(" ")] + 2: R_CURLY@42..43 "}" [] [] + 2: CSS_NESTED_QUALIFIED_RULE@43..64 + 0: CSS_RELATIVE_SELECTOR_LIST@43..48 + 0: CSS_RELATIVE_SELECTOR@43..48 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@43..48 + 0: CSS_NESTED_SELECTOR_LIST@43..43 + 1: CSS_UNIVERSAL_SELECTOR@43..48 + 0: (empty) + 1: STAR@43..48 "*" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@48..48 + 1: CSS_DECLARATION_OR_RULE_BLOCK@48..64 + 0: L_CURLY@48..50 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@50..63 + 0: CSS_DECLARATION_WITH_SEMICOLON@50..63 + 0: CSS_DECLARATION@50..61 + 0: CSS_GENERIC_PROPERTY@50..61 + 0: CSS_IDENTIFIER@50..55 + 0: IDENT@50..55 "color" [] [] + 1: COLON@55..57 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@57..61 + 0: SCSS_EXPRESSION_ITEM_LIST@57..61 + 0: CSS_IDENTIFIER@57..61 + 0: IDENT@57..61 "blue" [] [] + 1: (empty) + 1: SEMICOLON@61..63 ";" [] [Whitespace(" ")] + 2: R_CURLY@63..64 "}" [] [] + 2: R_CURLY@64..66 "}" [Newline("\n")] [] + 2: EOF@66..67 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +missing-semicolon-relative-selector-recovery.scss:3:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `>` + + 1 │ a { + 2 │ $x: 1 !default + > 3 │ > .b { color: red; } + │ ^ + 4 │ * { color: blue; } + 5 │ } + + i Remove > + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-selector-recovery.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-selector-recovery.scss new file mode 100644 index 000000000000..16290eb1ee35 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-selector-recovery.scss @@ -0,0 +1,5 @@ +a { + $x: 1 !default + a.b { color: red; } + width: 1px; +} diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-selector-recovery.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-selector-recovery.scss.snap new file mode 100644 index 000000000000..480249dcb387 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-semicolon-selector-recovery.scss.snap @@ -0,0 +1,239 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +a { + $x: 1 !default + a.b { color: red; } + width: 1px; +} + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@0..2 "a" [] [Whitespace(" ")], + }, + }, + sub_selectors: CssSubSelectorList [], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@2..3 "{" [] [], + items: CssDeclarationOrRuleList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@7..8 "x" [] [], + }, + }, + colon_token: COLON@8..10 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@12..13 "!" [] [], + value: DEFAULT_KW@13..20 "default" [] [], + }, + ], + semicolon_token: missing (optional), + }, + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@20..24 "a" [Newline("\n"), Whitespace(" ")] [], + }, + }, + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@24..25 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@25..27 "b" [] [Whitespace(" ")], + }, + }, + ], + }, + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@27..29 "{" [] [Whitespace(" ")], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@29..34 "color" [] [], + }, + colon_token: COLON@34..36 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@36..39 "red" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@39..41 ";" [] [Whitespace(" ")], + }, + ], + r_curly_token: R_CURLY@41..42 "}" [] [], + }, + }, + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@42..50 "width" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@50..52 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssRegularDimension { + value_token: CSS_NUMBER_LITERAL@52..53 "1" [] [], + unit_token: IDENT@53..55 "px" [] [], + }, + ], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@55..56 ";" [] [], + }, + ], + r_curly_token: R_CURLY@56..58 "}" [Newline("\n")] [], + }, + }, + ], + eof_token: EOF@58..59 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..59 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..58 + 0: CSS_QUALIFIED_RULE@0..58 + 0: CSS_SELECTOR_LIST@0..2 + 0: CSS_COMPOUND_SELECTOR@0..2 + 0: CSS_NESTED_SELECTOR_LIST@0..0 + 1: CSS_TYPE_SELECTOR@0..2 + 0: (empty) + 1: CSS_IDENTIFIER@0..2 + 0: IDENT@0..2 "a" [] [Whitespace(" ")] + 2: CSS_SUB_SELECTOR_LIST@2..2 + 1: CSS_DECLARATION_OR_RULE_BLOCK@2..58 + 0: L_CURLY@2..3 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@3..56 + 0: SCSS_DECLARATION@3..20 + 0: SCSS_IDENTIFIER@3..8 + 0: DOLLAR@3..7 "$" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@7..8 + 0: IDENT@7..8 "x" [] [] + 1: COLON@8..10 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@10..12 + 0: SCSS_EXPRESSION_ITEM_LIST@10..12 + 0: CSS_NUMBER@10..12 + 0: CSS_NUMBER_LITERAL@10..12 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@12..20 + 0: SCSS_VARIABLE_MODIFIER@12..20 + 0: BANG@12..13 "!" [] [] + 1: DEFAULT_KW@13..20 "default" [] [] + 4: (empty) + 1: CSS_NESTED_QUALIFIED_RULE@20..42 + 0: CSS_RELATIVE_SELECTOR_LIST@20..27 + 0: CSS_RELATIVE_SELECTOR@20..27 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@20..27 + 0: CSS_NESTED_SELECTOR_LIST@20..20 + 1: CSS_TYPE_SELECTOR@20..24 + 0: (empty) + 1: CSS_IDENTIFIER@20..24 + 0: IDENT@20..24 "a" [Newline("\n"), Whitespace(" ")] [] + 2: CSS_SUB_SELECTOR_LIST@24..27 + 0: CSS_CLASS_SELECTOR@24..27 + 0: DOT@24..25 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@25..27 + 0: IDENT@25..27 "b" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@27..42 + 0: L_CURLY@27..29 "{" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_LIST@29..41 + 0: CSS_DECLARATION_WITH_SEMICOLON@29..41 + 0: CSS_DECLARATION@29..39 + 0: CSS_GENERIC_PROPERTY@29..39 + 0: CSS_IDENTIFIER@29..34 + 0: IDENT@29..34 "color" [] [] + 1: COLON@34..36 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@36..39 + 0: SCSS_EXPRESSION_ITEM_LIST@36..39 + 0: CSS_IDENTIFIER@36..39 + 0: IDENT@36..39 "red" [] [] + 1: (empty) + 1: SEMICOLON@39..41 ";" [] [Whitespace(" ")] + 2: R_CURLY@41..42 "}" [] [] + 2: CSS_DECLARATION_WITH_SEMICOLON@42..56 + 0: CSS_DECLARATION@42..55 + 0: CSS_GENERIC_PROPERTY@42..55 + 0: CSS_IDENTIFIER@42..50 + 0: IDENT@42..50 "width" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@50..52 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@52..55 + 0: SCSS_EXPRESSION_ITEM_LIST@52..55 + 0: CSS_REGULAR_DIMENSION@52..55 + 0: CSS_NUMBER_LITERAL@52..53 "1" [] [] + 1: IDENT@53..55 "px" [] [] + 1: (empty) + 1: SEMICOLON@55..56 ";" [] [] + 2: R_CURLY@56..58 "}" [Newline("\n")] [] + 2: EOF@58..59 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +missing-semicolon-selector-recovery.scss:3:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `;` but instead found `a` + + 1 │ a { + 2 │ $x: 1 !default + > 3 │ a.b { color: red; } + │ ^ + 4 │ width: 1px; + 5 │ } + + i Remove a + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-value.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-value.scss new file mode 100644 index 000000000000..6b2675917b4a --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-value.scss @@ -0,0 +1,18 @@ +.missing-values { + $x: ; + color: ; +} + +/* Missing value before closing brace */ +.missing-before-brace { + color:} + +/* Missing value before closing brace on the next line */ +.missing-before-brace-newline { + color: +} + +/* Missing value before !important */ +.missing-before-important { + color: !important; +} diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-value.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-value.scss.snap new file mode 100644 index 000000000000..2a865cc25fec --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/missing-value.scss.snap @@ -0,0 +1,428 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +assertion_line: 208 +expression: snapshot +--- + +## Input + +```css +.missing-values { + $x: ; + color: ; +} + +/* Missing value before closing brace */ +.missing-before-brace { + color:} + +/* Missing value before closing brace on the next line */ +.missing-before-brace-newline { + color: +} + +/* Missing value before !important */ +.missing-before-important { + color: !important; +} + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@0..1 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@1..16 "missing-values" [] [Whitespace(" ")], + }, + }, + ], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@16..17 "{" [] [], + items: CssDeclarationOrRuleList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@17..21 "$" [Newline("\n"), Whitespace(" ")] [], + name: CssIdentifier { + value_token: IDENT@21..22 "x" [] [], + }, + }, + colon_token: COLON@22..24 ":" [] [Whitespace(" ")], + value: missing (required), + modifiers: ScssVariableModifierList [], + semicolon_token: SEMICOLON@24..25 ";" [] [], + }, + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@25..33 "color" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@33..35 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [], + }, + }, + important: missing (optional), + }, + semicolon_token: SEMICOLON@35..36 ";" [] [], + }, + ], + r_curly_token: R_CURLY@36..38 "}" [Newline("\n")] [], + }, + }, + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@38..82 "." [Newline("\n"), Newline("\n"), Comments("/* Missing value befo ..."), Newline("\n")] [], + name: CssCustomIdentifier { + value_token: IDENT@82..103 "missing-before-brace" [] [Whitespace(" ")], + }, + }, + ], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@103..104 "{" [] [], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@104..112 "color" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@112..113 ":" [] [], + value: ScssExpression { + items: ScssExpressionItemList [], + }, + }, + important: missing (optional), + }, + semicolon_token: missing (optional), + }, + ], + r_curly_token: R_CURLY@113..114 "}" [] [], + }, + }, + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@114..175 "." [Newline("\n"), Newline("\n"), Comments("/* Missing value befo ..."), Newline("\n")] [], + name: CssCustomIdentifier { + value_token: IDENT@175..204 "missing-before-brace-newline" [] [Whitespace(" ")], + }, + }, + ], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@204..205 "{" [] [], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@205..213 "color" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@213..214 ":" [] [], + value: ScssExpression { + items: ScssExpressionItemList [], + }, + }, + important: missing (optional), + }, + semicolon_token: missing (optional), + }, + ], + r_curly_token: R_CURLY@214..216 "}" [Newline("\n")] [], + }, + }, + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@216..257 "." [Newline("\n"), Newline("\n"), Comments("/* Missing value befo ..."), Newline("\n")] [], + name: CssCustomIdentifier { + value_token: IDENT@257..282 "missing-before-important" [] [Whitespace(" ")], + }, + }, + ], + }, + ], + block: CssDeclarationOrRuleBlock { + l_curly_token: L_CURLY@282..283 "{" [] [], + items: CssDeclarationOrRuleList [ + CssDeclarationWithSemicolon { + declaration: CssDeclaration { + property: CssGenericProperty { + name: CssIdentifier { + value_token: IDENT@283..291 "color" [Newline("\n"), Whitespace(" ")] [], + }, + colon_token: COLON@291..293 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [], + }, + }, + important: CssDeclarationImportant { + excl_token: BANG@293..294 "!" [] [], + important_token: IMPORTANT_KW@294..303 "important" [] [], + }, + }, + semicolon_token: SEMICOLON@303..304 ";" [] [], + }, + ], + r_curly_token: R_CURLY@304..306 "}" [Newline("\n")] [], + }, + }, + ], + eof_token: EOF@306..307 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..307 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..306 + 0: CSS_QUALIFIED_RULE@0..38 + 0: CSS_SELECTOR_LIST@0..16 + 0: CSS_COMPOUND_SELECTOR@0..16 + 0: CSS_NESTED_SELECTOR_LIST@0..0 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@0..16 + 0: CSS_CLASS_SELECTOR@0..16 + 0: DOT@0..1 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@1..16 + 0: IDENT@1..16 "missing-values" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@16..38 + 0: L_CURLY@16..17 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@17..36 + 0: SCSS_DECLARATION@17..25 + 0: SCSS_IDENTIFIER@17..22 + 0: DOLLAR@17..21 "$" [Newline("\n"), Whitespace(" ")] [] + 1: CSS_IDENTIFIER@21..22 + 0: IDENT@21..22 "x" [] [] + 1: COLON@22..24 ":" [] [Whitespace(" ")] + 2: (empty) + 3: SCSS_VARIABLE_MODIFIER_LIST@24..24 + 4: SEMICOLON@24..25 ";" [] [] + 1: CSS_DECLARATION_WITH_SEMICOLON@25..36 + 0: CSS_DECLARATION@25..35 + 0: CSS_GENERIC_PROPERTY@25..35 + 0: CSS_IDENTIFIER@25..33 + 0: IDENT@25..33 "color" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@33..35 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@35..35 + 0: SCSS_EXPRESSION_ITEM_LIST@35..35 + 1: (empty) + 1: SEMICOLON@35..36 ";" [] [] + 2: R_CURLY@36..38 "}" [Newline("\n")] [] + 1: CSS_QUALIFIED_RULE@38..114 + 0: CSS_SELECTOR_LIST@38..103 + 0: CSS_COMPOUND_SELECTOR@38..103 + 0: CSS_NESTED_SELECTOR_LIST@38..38 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@38..103 + 0: CSS_CLASS_SELECTOR@38..103 + 0: DOT@38..82 "." [Newline("\n"), Newline("\n"), Comments("/* Missing value befo ..."), Newline("\n")] [] + 1: CSS_CUSTOM_IDENTIFIER@82..103 + 0: IDENT@82..103 "missing-before-brace" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@103..114 + 0: L_CURLY@103..104 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@104..113 + 0: CSS_DECLARATION_WITH_SEMICOLON@104..113 + 0: CSS_DECLARATION@104..113 + 0: CSS_GENERIC_PROPERTY@104..113 + 0: CSS_IDENTIFIER@104..112 + 0: IDENT@104..112 "color" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@112..113 ":" [] [] + 2: SCSS_EXPRESSION@113..113 + 0: SCSS_EXPRESSION_ITEM_LIST@113..113 + 1: (empty) + 1: (empty) + 2: R_CURLY@113..114 "}" [] [] + 2: CSS_QUALIFIED_RULE@114..216 + 0: CSS_SELECTOR_LIST@114..204 + 0: CSS_COMPOUND_SELECTOR@114..204 + 0: CSS_NESTED_SELECTOR_LIST@114..114 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@114..204 + 0: CSS_CLASS_SELECTOR@114..204 + 0: DOT@114..175 "." [Newline("\n"), Newline("\n"), Comments("/* Missing value befo ..."), Newline("\n")] [] + 1: CSS_CUSTOM_IDENTIFIER@175..204 + 0: IDENT@175..204 "missing-before-brace-newline" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@204..216 + 0: L_CURLY@204..205 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@205..214 + 0: CSS_DECLARATION_WITH_SEMICOLON@205..214 + 0: CSS_DECLARATION@205..214 + 0: CSS_GENERIC_PROPERTY@205..214 + 0: CSS_IDENTIFIER@205..213 + 0: IDENT@205..213 "color" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@213..214 ":" [] [] + 2: SCSS_EXPRESSION@214..214 + 0: SCSS_EXPRESSION_ITEM_LIST@214..214 + 1: (empty) + 1: (empty) + 2: R_CURLY@214..216 "}" [Newline("\n")] [] + 3: CSS_QUALIFIED_RULE@216..306 + 0: CSS_SELECTOR_LIST@216..282 + 0: CSS_COMPOUND_SELECTOR@216..282 + 0: CSS_NESTED_SELECTOR_LIST@216..216 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@216..282 + 0: CSS_CLASS_SELECTOR@216..282 + 0: DOT@216..257 "." [Newline("\n"), Newline("\n"), Comments("/* Missing value befo ..."), Newline("\n")] [] + 1: CSS_CUSTOM_IDENTIFIER@257..282 + 0: IDENT@257..282 "missing-before-important" [] [Whitespace(" ")] + 1: CSS_DECLARATION_OR_RULE_BLOCK@282..306 + 0: L_CURLY@282..283 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@283..304 + 0: CSS_DECLARATION_WITH_SEMICOLON@283..304 + 0: CSS_DECLARATION@283..303 + 0: CSS_GENERIC_PROPERTY@283..293 + 0: CSS_IDENTIFIER@283..291 + 0: IDENT@283..291 "color" [Newline("\n"), Whitespace(" ")] [] + 1: COLON@291..293 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@293..293 + 0: SCSS_EXPRESSION_ITEM_LIST@293..293 + 1: CSS_DECLARATION_IMPORTANT@293..303 + 0: BANG@293..294 "!" [] [] + 1: IMPORTANT_KW@294..303 "important" [] [] + 1: SEMICOLON@303..304 ";" [] [] + 2: R_CURLY@304..306 "}" [Newline("\n")] [] + 2: EOF@306..307 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +missing-value.scss:2:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Expected a SCSS expression but instead found ';'. + + 1 │ .missing-values { + > 2 │ $x: ; + │ ^ + 3 │ color: ; + 4 │ } + + i Expected a SCSS expression here. + + 1 │ .missing-values { + > 2 │ $x: ; + │ ^ + 3 │ color: ; + 4 │ } + +missing-value.scss:3:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected value or character. + + 1 │ .missing-values { + 2 │ $x: ; + > 3 │ color: ; + │ ^ + 4 │ } + 5 │ + + i Expected one of: + + - identifier + - string + - number + - dimension + - ratio + - custom property + - function + +missing-value.scss:8:9 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected value or character. + + 6 │ /* Missing value before closing brace */ + 7 │ .missing-before-brace { + > 8 │ color:} + │ ^ + 9 │ + 10 │ /* Missing value before closing brace on the next line */ + + i Expected one of: + + - identifier + - string + - number + - dimension + - ratio + - custom property + - function + +missing-value.scss:13:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected value or character. + + 11 │ .missing-before-brace-newline { + 12 │ color: + > 13 │ } + │ ^ + 14 │ + 15 │ /* Missing value before !important */ + + i Expected one of: + + - identifier + - string + - number + - dimension + - ratio + - custom property + - function + +missing-value.scss:17:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected value or character. + + 15 │ /* Missing value before !important */ + 16 │ .missing-before-important { + > 17 │ color: !important; + │ ^ + 18 │ } + 19 │ + + i Expected one of: + + - identifier + - string + - number + - dimension + - ratio + - custom property + - function + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/modifier-recovery.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/modifier-recovery.scss new file mode 100644 index 000000000000..844129d6d596 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/modifier-recovery.scss @@ -0,0 +1,8 @@ +// Unexpected token between modifiers should still allow following modifiers +$color: red foo !global; + +// Unexpected token between modifiers should not stop parsing later modifiers +$gap: 1 !default bar !global; + +// !important should report an invalid modifier diagnostic and allow later modifiers +$size: 2 !important !global; diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/modifier-recovery.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/modifier-recovery.scss.snap new file mode 100644 index 000000000000..174194b3c199 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/modifier-recovery.scss.snap @@ -0,0 +1,211 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +// Unexpected token between modifiers should still allow following modifiers +$color: red foo !global; + +// Unexpected token between modifiers should not stop parsing later modifiers +$gap: 1 !default bar !global; + +// !important should report an invalid modifier diagnostic and allow later modifiers +$size: 2 !important !global; + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@0..78 "$" [Comments("// Unexpected token b ..."), Newline("\n")] [], + name: CssIdentifier { + value_token: IDENT@78..83 "color" [] [], + }, + }, + colon_token: COLON@83..85 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssIdentifier { + value_token: IDENT@85..89 "red" [] [Whitespace(" ")], + }, + CssIdentifier { + value_token: IDENT@89..93 "foo" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@93..94 "!" [] [], + value: GLOBAL_KW@94..100 "global" [] [], + }, + ], + semicolon_token: SEMICOLON@100..101 ";" [] [], + }, + CssBogus { + items: [ + ScssIdentifier { + dollar_token: DOLLAR@101..182 "$" [Newline("\n"), Newline("\n"), Comments("// Unexpected token b ..."), Newline("\n")] [], + name: CssIdentifier { + value_token: IDENT@182..185 "gap" [] [], + }, + }, + COLON@185..187 ":" [] [Whitespace(" ")], + ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@187..189 "1" [] [Whitespace(" ")], + }, + ], + }, + ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@189..190 "!" [] [], + value: DEFAULT_KW@190..198 "default" [] [Whitespace(" ")], + }, + ], + IDENT@198..202 "bar" [] [Whitespace(" ")], + ScssVariableModifier { + excl_token: BANG@202..203 "!" [] [], + value: GLOBAL_KW@203..209 "global" [] [], + }, + SEMICOLON@209..210 ";" [] [], + ], + }, + CssBogus { + items: [ + ScssIdentifier { + dollar_token: DOLLAR@210..298 "$" [Newline("\n"), Newline("\n"), Comments("// !important should ..."), Newline("\n")] [], + name: CssIdentifier { + value_token: IDENT@298..302 "size" [] [], + }, + }, + COLON@302..304 ":" [] [Whitespace(" ")], + ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@304..306 "2" [] [Whitespace(" ")], + }, + ], + }, + CssBogus { + items: [ + CssBogus { + items: [ + BANG@306..307 "!" [] [], + IMPORTANT_KW@307..317 "important" [] [Whitespace(" ")], + ], + }, + ScssVariableModifier { + excl_token: BANG@317..318 "!" [] [], + value: GLOBAL_KW@318..324 "global" [] [], + }, + ], + }, + SEMICOLON@324..325 ";" [] [], + ], + }, + ], + eof_token: EOF@325..326 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..326 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..325 + 0: SCSS_DECLARATION@0..101 + 0: SCSS_IDENTIFIER@0..83 + 0: DOLLAR@0..78 "$" [Comments("// Unexpected token b ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@78..83 + 0: IDENT@78..83 "color" [] [] + 1: COLON@83..85 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@85..93 + 0: SCSS_EXPRESSION_ITEM_LIST@85..93 + 0: CSS_IDENTIFIER@85..89 + 0: IDENT@85..89 "red" [] [Whitespace(" ")] + 1: CSS_IDENTIFIER@89..93 + 0: IDENT@89..93 "foo" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@93..100 + 0: SCSS_VARIABLE_MODIFIER@93..100 + 0: BANG@93..94 "!" [] [] + 1: GLOBAL_KW@94..100 "global" [] [] + 4: SEMICOLON@100..101 ";" [] [] + 1: CSS_BOGUS@101..210 + 0: SCSS_IDENTIFIER@101..185 + 0: DOLLAR@101..182 "$" [Newline("\n"), Newline("\n"), Comments("// Unexpected token b ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@182..185 + 0: IDENT@182..185 "gap" [] [] + 1: COLON@185..187 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@187..189 + 0: SCSS_EXPRESSION_ITEM_LIST@187..189 + 0: CSS_NUMBER@187..189 + 0: CSS_NUMBER_LITERAL@187..189 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@189..198 + 0: SCSS_VARIABLE_MODIFIER@189..198 + 0: BANG@189..190 "!" [] [] + 1: DEFAULT_KW@190..198 "default" [] [Whitespace(" ")] + 4: IDENT@198..202 "bar" [] [Whitespace(" ")] + 5: SCSS_VARIABLE_MODIFIER@202..209 + 0: BANG@202..203 "!" [] [] + 1: GLOBAL_KW@203..209 "global" [] [] + 6: SEMICOLON@209..210 ";" [] [] + 2: CSS_BOGUS@210..325 + 0: SCSS_IDENTIFIER@210..302 + 0: DOLLAR@210..298 "$" [Newline("\n"), Newline("\n"), Comments("// !important should ..."), Newline("\n")] [] + 1: CSS_IDENTIFIER@298..302 + 0: IDENT@298..302 "size" [] [] + 1: COLON@302..304 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@304..306 + 0: SCSS_EXPRESSION_ITEM_LIST@304..306 + 0: CSS_NUMBER@304..306 + 0: CSS_NUMBER_LITERAL@304..306 "2" [] [Whitespace(" ")] + 3: CSS_BOGUS@306..324 + 0: CSS_BOGUS@306..317 + 0: BANG@306..307 "!" [] [] + 1: IMPORTANT_KW@307..317 "important" [] [Whitespace(" ")] + 1: SCSS_VARIABLE_MODIFIER@317..324 + 0: BANG@317..318 "!" [] [] + 1: GLOBAL_KW@318..324 "global" [] [] + 4: SEMICOLON@324..325 ";" [] [] + 2: EOF@325..326 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +modifier-recovery.scss:5:18 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected value or character. + + 4 │ // Unexpected token between modifiers should not stop parsing later modifiers + > 5 │ $gap: 1 !default bar !global; + │ ^^^ + 6 │ + 7 │ // !important should report an invalid modifier diagnostic and allow later modifiers + + i Expected a variable modifier or the end of the declaration. + +modifier-recovery.scss:8:11 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × `!important` is not valid here. + + 7 │ // !important should report an invalid modifier diagnostic and allow later modifiers + > 8 │ $size: 2 !important !global; + │ ^^^^^^^^^ + 9 │ + + i SCSS variable declarations only support the `!default` and `!global` modifiers. + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/namespaced-missing-identifier.scss b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/namespaced-missing-identifier.scss new file mode 100644 index 000000000000..ae8b66435897 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/namespaced-missing-identifier.scss @@ -0,0 +1,3 @@ +.bad { + mod.$: 1; +} diff --git a/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/namespaced-missing-identifier.scss.snap b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/namespaced-missing-identifier.scss.snap new file mode 100644 index 000000000000..35808d7197f1 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/error/scss/declaration/namespaced-missing-identifier.scss.snap @@ -0,0 +1,267 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +assertion_line: 208 +expression: snapshot +--- +## Input + +```css +.bad { + mod.$: 1; +} + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + CssQualifiedRule { + prelude: CssSelectorList [ + CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@0..1 "." [] [], + name: CssCustomIdentifier { + value_token: IDENT@1..5 "bad" [] [Whitespace(" ")], + }, + }, + ], + }, + ], + block: CssBogusBlock { + items: [ + L_CURLY@5..6 "{" [] [], + CssDeclarationOrRuleList [ + CssNestedQualifiedRule { + prelude: CssRelativeSelectorList [ + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: CssTypeSelector { + namespace: missing (optional), + ident: CssIdentifier { + value_token: IDENT@6..12 "mod" [Newline("\n"), Whitespace(" ")] [], + }, + }, + sub_selectors: CssSubSelectorList [ + CssClassSelector { + dot_token: DOT@12..13 "." [] [], + name: missing (required), + }, + ], + }, + }, + missing separator, + CssBogusSelector { + items: [ + DOLLAR@13..14 "$" [] [], + ], + }, + missing separator, + CssRelativeSelector { + combinator: missing (optional), + selector: CssCompoundSelector { + nesting_selectors: CssNestedSelectorList [], + simple_selector: missing (optional), + sub_selectors: CssSubSelectorList [ + CssBogusSubSelector { + items: [ + COLON@14..16 ":" [] [Whitespace(" ")], + ], + }, + ], + }, + }, + missing separator, + CssBogusSelector { + items: [ + CSS_NUMBER_LITERAL@16..17 "1" [] [], + SEMICOLON@17..18 ";" [] [], + R_CURLY@18..20 "}" [Newline("\n")] [], + ], + }, + ], + block: CssBogusBlock { + items: [], + }, + }, + ], + ], + }, + }, + ], + eof_token: EOF@20..21 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..21 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..20 + 0: CSS_QUALIFIED_RULE@0..20 + 0: CSS_SELECTOR_LIST@0..5 + 0: CSS_COMPOUND_SELECTOR@0..5 + 0: CSS_NESTED_SELECTOR_LIST@0..0 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@0..5 + 0: CSS_CLASS_SELECTOR@0..5 + 0: DOT@0..1 "." [] [] + 1: CSS_CUSTOM_IDENTIFIER@1..5 + 0: IDENT@1..5 "bad" [] [Whitespace(" ")] + 1: CSS_BOGUS_BLOCK@5..20 + 0: L_CURLY@5..6 "{" [] [] + 1: CSS_DECLARATION_OR_RULE_LIST@6..20 + 0: CSS_NESTED_QUALIFIED_RULE@6..20 + 0: CSS_RELATIVE_SELECTOR_LIST@6..20 + 0: CSS_RELATIVE_SELECTOR@6..13 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@6..13 + 0: CSS_NESTED_SELECTOR_LIST@6..6 + 1: CSS_TYPE_SELECTOR@6..12 + 0: (empty) + 1: CSS_IDENTIFIER@6..12 + 0: IDENT@6..12 "mod" [Newline("\n"), Whitespace(" ")] [] + 2: CSS_SUB_SELECTOR_LIST@12..13 + 0: CSS_CLASS_SELECTOR@12..13 + 0: DOT@12..13 "." [] [] + 1: (empty) + 1: (empty) + 2: CSS_BOGUS_SELECTOR@13..14 + 0: DOLLAR@13..14 "$" [] [] + 3: (empty) + 4: CSS_RELATIVE_SELECTOR@14..16 + 0: (empty) + 1: CSS_COMPOUND_SELECTOR@14..16 + 0: CSS_NESTED_SELECTOR_LIST@14..14 + 1: (empty) + 2: CSS_SUB_SELECTOR_LIST@14..16 + 0: CSS_BOGUS_SUB_SELECTOR@14..16 + 0: COLON@14..16 ":" [] [Whitespace(" ")] + 5: (empty) + 6: CSS_BOGUS_SELECTOR@16..20 + 0: CSS_NUMBER_LITERAL@16..17 "1" [] [] + 1: SEMICOLON@17..18 ";" [] [] + 2: R_CURLY@18..20 "}" [Newline("\n")] [] + 1: CSS_BOGUS_BLOCK@20..20 + 2: EOF@20..21 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +namespaced-missing-identifier.scss:2:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Expected an identifier but instead found '$'. + + 1 │ .bad { + > 2 │ mod.$: 1; + │ ^ + 3 │ } + 4 │ + + i Expected an identifier here. + + 1 │ .bad { + > 2 │ mod.$: 1; + │ ^ + 3 │ } + 4 │ + +namespaced-missing-identifier.scss:2:8 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `,` but instead found `:` + + 1 │ .bad { + > 2 │ mod.$: 1; + │ ^ + 3 │ } + 4 │ + + i Remove : + +namespaced-missing-identifier.scss:2:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected value or character. + + 1 │ .bad { + > 2 │ mod.$: 1; + │ ^ + 3 │ } + 4 │ + + i Expected one of: + + - hover + - focus + - active + - first-child + - last-child + - nth-child + - nth-last-child + - first-of-type + - last-of-type + - nth-of-type + - nth-last-of-type + - only-child + - only-of-type + - checked + - disabled + - enabled + - required + - optional + - valid + - invalid + - in-range + - out-of-range + - read-only + - read-write + - placeholder-shown + - default + - checked + - indeterminate + - blank + - empty + - root + - target + - lang + - not + - is + - where + - fullscreen + - link + - visited + - any-link + - local-link + - scope + - state + - current + - past + - future + +namespaced-missing-identifier.scss:4:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `{` but instead the file ends + + 2 │ mod.$: 1; + 3 │ } + > 4 │ + │ + + i the file ends here + + 2 │ mod.$: 1; + 3 │ } + > 4 │ + │ + +``` diff --git a/crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/duplicate-modifier.scss b/crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/duplicate-modifier.scss new file mode 100644 index 000000000000..45c06576abb0 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/duplicate-modifier.scss @@ -0,0 +1,3 @@ +$dup-default: 1 !default !default; +$dup-global: 1 !global !global; +$dup-mixed: 1 !default !global !default; diff --git a/crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/duplicate-modifier.scss.snap b/crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/duplicate-modifier.scss.snap new file mode 100644 index 000000000000..817fafa97535 --- /dev/null +++ b/crates/biome_css_parser/tests/css_test_suite/ok/scss/declaration/duplicate-modifier.scss.snap @@ -0,0 +1,178 @@ +--- +source: crates/biome_css_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```css +$dup-default: 1 !default !default; +$dup-global: 1 !global !global; +$dup-mixed: 1 !default !global !default; + +``` + + +## AST + +``` +CssRoot { + bom_token: missing (optional), + items: CssRootItemList [ + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@0..1 "$" [] [], + name: CssIdentifier { + value_token: IDENT@1..12 "dup-default" [] [], + }, + }, + colon_token: COLON@12..14 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@14..16 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@16..17 "!" [] [], + value: DEFAULT_KW@17..25 "default" [] [Whitespace(" ")], + }, + ScssVariableModifier { + excl_token: BANG@25..26 "!" [] [], + value: DEFAULT_KW@26..33 "default" [] [], + }, + ], + semicolon_token: SEMICOLON@33..34 ";" [] [], + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@34..36 "$" [Newline("\n")] [], + name: CssIdentifier { + value_token: IDENT@36..46 "dup-global" [] [], + }, + }, + colon_token: COLON@46..48 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@48..50 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@50..51 "!" [] [], + value: GLOBAL_KW@51..58 "global" [] [Whitespace(" ")], + }, + ScssVariableModifier { + excl_token: BANG@58..59 "!" [] [], + value: GLOBAL_KW@59..65 "global" [] [], + }, + ], + semicolon_token: SEMICOLON@65..66 ";" [] [], + }, + ScssDeclaration { + name: ScssIdentifier { + dollar_token: DOLLAR@66..68 "$" [Newline("\n")] [], + name: CssIdentifier { + value_token: IDENT@68..77 "dup-mixed" [] [], + }, + }, + colon_token: COLON@77..79 ":" [] [Whitespace(" ")], + value: ScssExpression { + items: ScssExpressionItemList [ + CssNumber { + value_token: CSS_NUMBER_LITERAL@79..81 "1" [] [Whitespace(" ")], + }, + ], + }, + modifiers: ScssVariableModifierList [ + ScssVariableModifier { + excl_token: BANG@81..82 "!" [] [], + value: DEFAULT_KW@82..90 "default" [] [Whitespace(" ")], + }, + ScssVariableModifier { + excl_token: BANG@90..91 "!" [] [], + value: GLOBAL_KW@91..98 "global" [] [Whitespace(" ")], + }, + ScssVariableModifier { + excl_token: BANG@98..99 "!" [] [], + value: DEFAULT_KW@99..106 "default" [] [], + }, + ], + semicolon_token: SEMICOLON@106..107 ";" [] [], + }, + ], + eof_token: EOF@107..108 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: CSS_ROOT@0..108 + 0: (empty) + 1: CSS_ROOT_ITEM_LIST@0..107 + 0: SCSS_DECLARATION@0..34 + 0: SCSS_IDENTIFIER@0..12 + 0: DOLLAR@0..1 "$" [] [] + 1: CSS_IDENTIFIER@1..12 + 0: IDENT@1..12 "dup-default" [] [] + 1: COLON@12..14 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@14..16 + 0: SCSS_EXPRESSION_ITEM_LIST@14..16 + 0: CSS_NUMBER@14..16 + 0: CSS_NUMBER_LITERAL@14..16 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@16..33 + 0: SCSS_VARIABLE_MODIFIER@16..25 + 0: BANG@16..17 "!" [] [] + 1: DEFAULT_KW@17..25 "default" [] [Whitespace(" ")] + 1: SCSS_VARIABLE_MODIFIER@25..33 + 0: BANG@25..26 "!" [] [] + 1: DEFAULT_KW@26..33 "default" [] [] + 4: SEMICOLON@33..34 ";" [] [] + 1: SCSS_DECLARATION@34..66 + 0: SCSS_IDENTIFIER@34..46 + 0: DOLLAR@34..36 "$" [Newline("\n")] [] + 1: CSS_IDENTIFIER@36..46 + 0: IDENT@36..46 "dup-global" [] [] + 1: COLON@46..48 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@48..50 + 0: SCSS_EXPRESSION_ITEM_LIST@48..50 + 0: CSS_NUMBER@48..50 + 0: CSS_NUMBER_LITERAL@48..50 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@50..65 + 0: SCSS_VARIABLE_MODIFIER@50..58 + 0: BANG@50..51 "!" [] [] + 1: GLOBAL_KW@51..58 "global" [] [Whitespace(" ")] + 1: SCSS_VARIABLE_MODIFIER@58..65 + 0: BANG@58..59 "!" [] [] + 1: GLOBAL_KW@59..65 "global" [] [] + 4: SEMICOLON@65..66 ";" [] [] + 2: SCSS_DECLARATION@66..107 + 0: SCSS_IDENTIFIER@66..77 + 0: DOLLAR@66..68 "$" [Newline("\n")] [] + 1: CSS_IDENTIFIER@68..77 + 0: IDENT@68..77 "dup-mixed" [] [] + 1: COLON@77..79 ":" [] [Whitespace(" ")] + 2: SCSS_EXPRESSION@79..81 + 0: SCSS_EXPRESSION_ITEM_LIST@79..81 + 0: CSS_NUMBER@79..81 + 0: CSS_NUMBER_LITERAL@79..81 "1" [] [Whitespace(" ")] + 3: SCSS_VARIABLE_MODIFIER_LIST@81..106 + 0: SCSS_VARIABLE_MODIFIER@81..90 + 0: BANG@81..82 "!" [] [] + 1: DEFAULT_KW@82..90 "default" [] [Whitespace(" ")] + 1: SCSS_VARIABLE_MODIFIER@90..98 + 0: BANG@90..91 "!" [] [] + 1: GLOBAL_KW@91..98 "global" [] [Whitespace(" ")] + 2: SCSS_VARIABLE_MODIFIER@98..106 + 0: BANG@98..99 "!" [] [] + 1: DEFAULT_KW@99..106 "default" [] [] + 4: SEMICOLON@106..107 ";" [] [] + 2: EOF@107..108 "" [Newline("\n")] [] + +``` +