swc_css_ast/
base.rs

1use is_macro::Is;
2use swc_atoms::Atom;
3use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
4
5use crate::{
6    AlphaValue, AnglePercentage, AtRule, CalcSum, CmykComponent, Color, ComplexSelector,
7    DashedIdent, Delimiter, Dimension, FrequencyPercentage, Hue, IdSelector, Ident, Integer,
8    KeyframeBlock, LayerName, LengthPercentage, Number, Percentage, Ratio, RelativeSelectorList,
9    SelectorList, Str, SupportsCondition, TimePercentage, TokenAndSpan, UnicodeRange, Url,
10};
11
12#[ast_node("Stylesheet")]
13#[derive(Eq, Hash, EqIgnoreSpan)]
14pub struct Stylesheet {
15    pub span: Span,
16    pub rules: Vec<Rule>,
17}
18
19#[ast_node]
20#[derive(Eq, Hash, Is, EqIgnoreSpan)]
21pub enum Rule {
22    #[tag("QualifiedRule")]
23    QualifiedRule(Box<QualifiedRule>),
24
25    #[tag("AtRule")]
26    AtRule(Box<AtRule>),
27
28    #[tag("ListOfComponentValues")]
29    ListOfComponentValues(Box<ListOfComponentValues>),
30}
31
32impl Take for Rule {
33    fn dummy() -> Self {
34        Self::QualifiedRule(Take::dummy())
35    }
36}
37
38#[ast_node("QualifiedRule")]
39#[derive(Eq, Hash, EqIgnoreSpan)]
40pub struct QualifiedRule {
41    pub span: Span,
42    pub prelude: QualifiedRulePrelude,
43    pub block: SimpleBlock,
44}
45
46impl Take for QualifiedRule {
47    fn dummy() -> Self {
48        Self {
49            span: Take::dummy(),
50            prelude: Take::dummy(),
51            block: Take::dummy(),
52        }
53    }
54}
55
56#[ast_node]
57#[derive(Eq, Hash, Is, EqIgnoreSpan)]
58pub enum QualifiedRulePrelude {
59    #[tag("SelectorList")]
60    SelectorList(SelectorList),
61    #[tag("RelativeSelectorList")]
62    RelativeSelectorList(RelativeSelectorList),
63    #[tag("ListOfComponentValues")]
64    ListOfComponentValues(ListOfComponentValues),
65}
66
67impl Take for QualifiedRulePrelude {
68    fn dummy() -> Self {
69        Self::SelectorList(Take::dummy())
70    }
71}
72
73#[ast_node]
74#[derive(Eq, Hash, Is, EqIgnoreSpan)]
75pub enum StyleBlock {
76    #[tag("AtRule")]
77    AtRule(Box<AtRule>),
78    #[tag("Declaration")]
79    Declaration(Box<Declaration>),
80    #[tag("QualifiedRule")]
81    QualifiedRule(Box<QualifiedRule>),
82    #[tag("ListOfComponentValues")]
83    ListOfComponentValues(Box<ListOfComponentValues>),
84}
85
86#[ast_node("SimpleBlock")]
87#[derive(Eq, Hash, EqIgnoreSpan)]
88pub struct SimpleBlock {
89    pub span: Span,
90    pub name: TokenAndSpan,
91    pub value: Vec<ComponentValue>,
92}
93
94impl Take for SimpleBlock {
95    fn dummy() -> Self {
96        Self {
97            span: Take::dummy(),
98            name: Take::dummy(),
99            value: Take::dummy(),
100        }
101    }
102}
103
104#[ast_node]
105#[derive(Eq, Hash, Is, EqIgnoreSpan)]
106pub enum FunctionName {
107    #[tag("Ident")]
108    Ident(Ident),
109    #[tag("DashedIdent")]
110    DashedIdent(DashedIdent),
111}
112
113impl PartialEq<str> for FunctionName {
114    fn eq(&self, other: &str) -> bool {
115        match self {
116            FunctionName::DashedIdent(v) => *v == *other,
117            FunctionName::Ident(v) => *v == *other,
118        }
119    }
120}
121
122impl PartialEq<&'_ str> for FunctionName {
123    fn eq(&self, other: &&str) -> bool {
124        match self {
125            FunctionName::DashedIdent(v) => *v == **other,
126            FunctionName::Ident(v) => *v == **other,
127        }
128    }
129}
130
131impl PartialEq<Atom> for FunctionName {
132    fn eq(&self, other: &Atom) -> bool {
133        match self {
134            FunctionName::DashedIdent(v) => v.value == *other,
135            FunctionName::Ident(v) => v.value == *other,
136        }
137    }
138}
139
140impl FunctionName {
141    pub fn as_str(&self) -> &str {
142        match self {
143            FunctionName::DashedIdent(v) => &v.value,
144            FunctionName::Ident(v) => &v.value,
145        }
146    }
147}
148
149#[ast_node("Function")]
150#[derive(Eq, Hash, EqIgnoreSpan)]
151pub struct Function {
152    /// Span starting from the `lo` of identifier and to the end of `)`.
153    pub span: Span,
154    pub name: FunctionName,
155    pub value: Vec<ComponentValue>,
156}
157
158#[ast_node("ListOfComponentValues")]
159#[derive(Eq, Hash, EqIgnoreSpan)]
160pub struct ListOfComponentValues {
161    pub span: Span,
162    pub children: Vec<ComponentValue>,
163}
164
165#[ast_node]
166#[derive(Eq, Hash, Is, EqIgnoreSpan)]
167pub enum ComponentValue {
168    // No grammar
169    #[tag("TokenAndSpan")]
170    PreservedToken(Box<TokenAndSpan>),
171    #[tag("Function")]
172    Function(Box<Function>),
173    #[tag("SimpleBlock")]
174    SimpleBlock(Box<SimpleBlock>),
175
176    #[tag("AtRule")]
177    AtRule(Box<AtRule>),
178
179    #[tag("QualifiedRule")]
180    QualifiedRule(Box<QualifiedRule>),
181
182    #[tag("ListOfComponentValues")]
183    ListOfComponentValues(Box<ListOfComponentValues>),
184
185    #[tag("KeyframeBlock")]
186    KeyframeBlock(Box<KeyframeBlock>),
187
188    // Arbitrary Contents grammar
189    #[tag("Ident")]
190    Ident(Box<Ident>),
191    #[tag("DashedIdent")]
192    DashedIdent(Box<DashedIdent>),
193    #[tag("String")]
194    Str(Box<Str>),
195    #[tag("Url")]
196    Url(Box<Url>),
197    #[tag("Integer")]
198    Integer(Box<Integer>),
199    #[tag("Number")]
200    Number(Box<Number>),
201    #[tag("Percentage")]
202    Percentage(Box<Percentage>),
203    #[tag("Dimension")]
204    Dimension(Box<Dimension>),
205    #[tag("LengthPercentage")]
206    LengthPercentage(Box<LengthPercentage>),
207    #[tag("FrequencyPercentage")]
208    FrequencyPercentage(Box<FrequencyPercentage>),
209    #[tag("AnglePercentage")]
210    AnglePercentage(Box<AnglePercentage>),
211    #[tag("TimePercentage")]
212    TimePercentage(Box<TimePercentage>),
213    #[tag("Ratio")]
214    Ratio(Box<Ratio>),
215    #[tag("UnicodeRange")]
216    UnicodeRange(Box<UnicodeRange>),
217    #[tag("Color")]
218    Color(Box<Color>),
219    #[tag("AlphaValue")]
220    AlphaValue(Box<AlphaValue>),
221    #[tag("Hue")]
222    Hue(Box<Hue>),
223    #[tag("CmykComponent")]
224    CmykComponent(Box<CmykComponent>),
225    #[tag("Delimiter")]
226    Delimiter(Box<Delimiter>),
227
228    // Special function Contents grammar
229    #[tag("CalcSum")]
230    CalcSum(Box<CalcSum>),
231    #[tag("ComplexSelector")]
232    ComplexSelector(Box<ComplexSelector>),
233    #[tag("LayerName")]
234    LayerName(Box<LayerName>),
235    #[tag("SupportsCondition")]
236    SupportsCondition(Box<SupportsCondition>),
237    #[tag("Declaration")]
238    Declaration(Box<Declaration>),
239    #[tag("IdSelector")]
240    IdSelector(Box<IdSelector>),
241}
242
243impl From<StyleBlock> for ComponentValue {
244    #[inline]
245    fn from(block: StyleBlock) -> Self {
246        match block {
247            StyleBlock::AtRule(at_rule) => ComponentValue::AtRule(at_rule),
248            StyleBlock::Declaration(declaration) => ComponentValue::Declaration(declaration),
249            StyleBlock::QualifiedRule(qualified_rule) => {
250                ComponentValue::QualifiedRule(qualified_rule)
251            }
252            StyleBlock::ListOfComponentValues(list_of_component_values) => {
253                ComponentValue::ListOfComponentValues(list_of_component_values)
254            }
255        }
256    }
257}
258
259impl From<DeclarationOrAtRule> for ComponentValue {
260    #[inline]
261    fn from(rule: DeclarationOrAtRule) -> Self {
262        match rule {
263            DeclarationOrAtRule::Declaration(declaration) => {
264                ComponentValue::Declaration(declaration)
265            }
266            DeclarationOrAtRule::AtRule(at_rule) => ComponentValue::AtRule(at_rule),
267            DeclarationOrAtRule::ListOfComponentValues(list_of_component_values) => {
268                ComponentValue::ListOfComponentValues(list_of_component_values)
269            }
270        }
271    }
272}
273
274impl From<Rule> for ComponentValue {
275    #[inline]
276    fn from(rule: Rule) -> Self {
277        match rule {
278            Rule::AtRule(at_rule) => ComponentValue::AtRule(at_rule),
279            Rule::QualifiedRule(qualified_rule) => ComponentValue::QualifiedRule(qualified_rule),
280            Rule::ListOfComponentValues(list_of_component_values) => {
281                ComponentValue::ListOfComponentValues(list_of_component_values)
282            }
283        }
284    }
285}
286
287#[ast_node]
288#[derive(Eq, Hash, Is, EqIgnoreSpan)]
289pub enum DeclarationOrAtRule {
290    #[tag("Declaration")]
291    Declaration(Box<Declaration>),
292    #[tag("AtRule")]
293    AtRule(Box<AtRule>),
294    // For recovery mode
295    #[tag("ListOfComponentValues")]
296    ListOfComponentValues(Box<ListOfComponentValues>),
297}
298
299#[ast_node("Declaration")]
300#[derive(Eq, Hash, EqIgnoreSpan)]
301pub struct Declaration {
302    pub span: Span,
303    pub name: DeclarationName,
304    pub value: Vec<ComponentValue>,
305    /// The span includes `!`
306    pub important: Option<ImportantFlag>,
307}
308
309#[ast_node]
310#[derive(Eq, Hash, Is, EqIgnoreSpan)]
311pub enum DeclarationName {
312    #[tag("Ident")]
313    Ident(Ident),
314    #[tag("DashedIdent")]
315    DashedIdent(DashedIdent),
316}
317
318impl PartialEq<str> for DeclarationName {
319    fn eq(&self, other: &str) -> bool {
320        match self {
321            DeclarationName::DashedIdent(v) => *v == *other,
322            DeclarationName::Ident(v) => *v == *other,
323        }
324    }
325}
326
327impl PartialEq<Atom> for DeclarationName {
328    fn eq(&self, other: &Atom) -> bool {
329        match self {
330            DeclarationName::DashedIdent(v) => v.value == *other,
331            DeclarationName::Ident(v) => v.value == *other,
332        }
333    }
334}
335
336#[ast_node("ImportantFlag")]
337#[derive(Eq, Hash, EqIgnoreSpan)]
338pub struct ImportantFlag {
339    pub span: Span,
340    pub value: Ident,
341}