Skip to main content

oxc_css_parser/parser/
postcss_simple_vars.rs

1use super::{
2    Parser,
3    state::{ParserState, QualifiedRuleContext},
4};
5use crate::{Parse, ast::*, config::Syntax, error::PResult, pos::Span};
6
7// postcss-simple-vars variable reference: `$` <ident>
8// https://github.com/postcss/postcss-simple-vars
9impl<'a> Parse<'a> for PostcssSimpleVar<'a> {
10    fn parse(input: &mut Parser<'a>) -> PResult<Self> {
11        debug_assert!(input.syntax == Syntax::Css);
12
13        let (name, span) = input.parse_dollar_var_ident()?;
14        Ok(PostcssSimpleVar { name, span })
15    }
16}
17
18// postcss-simple-vars declaration: `$` <ident> ':' <declaration-value>
19// (textual substitution; a trailing `!important` stays part of the value)
20impl<'a> Parse<'a> for PostcssSimpleVarDeclaration<'a> {
21    fn parse(input: &mut Parser<'a>) -> PResult<Self> {
22        debug_assert!(input.syntax == Syntax::Css);
23
24        let name = input.parse::<PostcssSimpleVar>()?;
25        let (_, colon_span) = input.cursor.expect_colon()?;
26        // `$var: value` is already a postcss declaration shape,
27        // so the typed node keeps the CSS `<any-value>` acceptance
28        // (a top-level `{}` still rejects it as a raw-prelude rule for the statement disambiguation path).
29        let (mut value, important, value_is_raw) = input
30            .with_state(ParserState {
31                qualified_rule_ctx: Some(QualifiedRuleContext::DeclarationValue),
32                in_statement: true,
33                ..input.state
34            })
35            .parse_css_any_value()?;
36        // postcss-simple-vars is textual substitution;
37        // `!important` is part of the value, not a structural declaration modifier
38        // (unlike CSS's `Declaration.important`).
39        // Keep a valid trailing annotation in the value stream;
40        // a non-`important` bang is already in the raw fallback.
41        if let Some(important) = important {
42            value.push(ComponentValue::ImportantAnnotation(important));
43        }
44
45        let end = value.last().map(|v| v.span().end).unwrap_or(colon_span.end);
46        let span = Span { start: name.span.start, end };
47
48        Ok(PostcssSimpleVarDeclaration { name, colon_span, value, value_is_raw, span })
49    }
50}