1include!(concat!(env!("OUT_DIR"), "/css_node_kind.rs"));
2include!(concat!(env!("OUT_DIR"), "/css_apply_visit_methods.rs"));
3include!(concat!(env!("OUT_DIR"), "/css_apply_queryable_visit_methods.rs"));
4include!(concat!(env!("OUT_DIR"), "/css_apply_queryable_exit_methods.rs"));
5
6use bumpalo::collections::Vec;
7use css_parse::{
8 Block, BumpBox, CommaSeparated, Comparison, ComponentValues, Cursor, Declaration, DeclarationGroup,
9 DeclarationList, DeclarationOrBad, DeclarationValue, NoBlockAllowed, NodeMetadata, NodeWithMetadata, Optionals2,
10 Optionals3, Optionals4, Optionals5, QualifiedRule, RuleList, syntax::BadDeclaration, token_macros,
11};
12
13use crate::*;
14
15macro_rules! visit_mut_trait {
16 ( $(
17 $name: ident$(<$($gen:tt),+>)?($obj: ty),
18 )+ ) => {
19 pub trait VisitMut: Sized {
20 fn visit_declaration<'a, T: DeclarationValue<'a, CssMetadata>>(&mut self, _rule: &mut Declaration<'a, T, CssMetadata>) {}
21 fn exit_declaration<'a, T: DeclarationValue<'a, CssMetadata>>(&mut self, _rule: &mut Declaration<'a, T, CssMetadata>) {}
22 fn visit_bad_declaration<'a>(&mut self, _rule: &mut BadDeclaration<'a>) {}
23 fn exit_bad_declaration<'a>(&mut self, _rule: &mut BadDeclaration<'a>) {}
24 fn visit_string(&mut self, _str: &mut token_macros::String) {}
25 fn exit_string(&mut self, _str: &mut token_macros::String) {}
26 fn visit_comparison(&mut self, _comparison: &mut Comparison) {}
27 fn exit_comparison(&mut self, _comparison: &mut Comparison) {}
28 $(
29 fn $name$(<$($gen),+>)?(&mut self, _rule: &mut $obj) {}
30 )+
31 }
32 }
33}
34apply_visit_methods!(visit_mut_trait);
35
36macro_rules! visit_trait {
37 ( $(
38 $name: ident$(<$($gen:tt),+>)?($obj: ty),
39 )+ ) => {
40 pub trait Visit: Sized {
41 fn visit_queryable_node<T: QueryableNode>(&mut self, _node: &T) {}
44
45 fn exit_queryable_node<T: QueryableNode>(&mut self, _node: &T) {}
48
49 fn visit_declaration<'a, T: DeclarationValue<'a, CssMetadata> + QueryableNode>(&mut self, _rule: &Declaration<'a, T, CssMetadata>) {}
50 fn exit_declaration<'a, T: DeclarationValue<'a, CssMetadata> + QueryableNode>(&mut self, _rule: &Declaration<'a, T, CssMetadata>) {}
51 fn visit_bad_declaration<'a>(&mut self, _rule: &BadDeclaration<'a>) {}
52 fn exit_bad_declaration<'a>(&mut self, _rule: &BadDeclaration<'a>) {}
53 fn visit_string(&mut self, _str: &token_macros::String) {}
54 fn exit_string(&mut self, _str: &token_macros::String) {}
55 fn visit_comparison(&mut self, _comparison: &Comparison) {}
56 fn exit_comparison(&mut self, _comparison: &Comparison) {}
57 $(
58 fn $name$(<$($gen),+>)?(&mut self, _rule: &$obj) {}
59 )+
60 }
61 }
62}
63apply_visit_methods!(visit_trait);
64
65pub trait VisitableMut {
66 fn accept_mut<V: VisitMut>(&mut self, v: &mut V);
67}
68
69pub trait Visitable {
70 fn accept<V: Visit>(&self, v: &mut V);
71}
72
73pub trait QueryableNode: Visitable + NodeWithMetadata<CssMetadata> + ToSpan {
79 const NODE_ID: NodeId;
81
82 fn node_id(&self) -> NodeId {
83 Self::NODE_ID
84 }
85
86 fn get_property(&self, _kind: PropertyKind) -> Option<Cursor> {
92 None
93 }
94}
95
96impl<T> VisitableMut for Option<T>
97where
98 T: VisitableMut,
99{
100 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
101 if let Some(node) = self {
102 node.accept_mut(v)
103 }
104 }
105}
106
107macro_rules! impl_optionals {
108 ($N:ident, $($T:ident),+) => {
109 impl<$($T),*> Visitable for $N<$($T),+>
110 where
111 $($T: Visitable,)+
112 {
113 #[allow(non_snake_case)]
114 #[allow(unused)]
115 fn accept<VI: Visit>(&self, v: &mut VI) {
116 let $N($($T),+) = self;
117 $($T.accept(v);)+;
118 }
119 }
120
121 impl<$($T),*> VisitableMut for $N<$($T),+>
122 where
123 $($T: VisitableMut,)+
124 {
125 #[allow(non_snake_case)]
126 #[allow(unused)]
127 fn accept_mut<VI: VisitMut>(&mut self, v: &mut VI) {
128 let $N($($T),+) = self;
129 $($T.accept_mut(v);)+;
130 }
131 }
132 };
133}
134
135impl_optionals!(Optionals2, T, U);
136impl_optionals!(Optionals3, T, U, V);
137impl_optionals!(Optionals4, T, U, V, W);
138impl_optionals!(Optionals5, T, U, V, W, X);
139
140impl Visitable for token_macros::Ident {
141 fn accept<V: Visit>(&self, _: &mut V) {}
142}
143
144impl VisitableMut for token_macros::Ident {
145 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
146}
147
148impl Visitable for token_macros::Comma {
149 fn accept<V: Visit>(&self, _: &mut V) {}
150}
151
152impl VisitableMut for token_macros::Comma {
153 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
154}
155
156impl Visitable for token_macros::LeftParen {
157 fn accept<V: Visit>(&self, _: &mut V) {}
158}
159
160impl VisitableMut for token_macros::LeftParen {
161 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
162}
163
164impl Visitable for token_macros::RightParen {
165 fn accept<V: Visit>(&self, _: &mut V) {}
166}
167
168impl VisitableMut for token_macros::RightParen {
169 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
170}
171
172impl Visitable for token_macros::Colon {
173 fn accept<V: Visit>(&self, _: &mut V) {}
174}
175
176impl VisitableMut for token_macros::Colon {
177 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
178}
179
180impl Visitable for Comparison {
181 fn accept<V: Visit>(&self, v: &mut V) {
182 v.visit_comparison(self);
183 v.exit_comparison(self);
184 }
185}
186
187impl VisitableMut for Comparison {
188 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
189 v.visit_comparison(self);
190 v.exit_comparison(self);
191 }
192}
193
194impl Visitable for token_macros::delim::Slash {
195 fn accept<V: Visit>(&self, _: &mut V) {}
196}
197
198impl VisitableMut for token_macros::delim::Slash {
199 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
200}
201
202impl Visitable for token_macros::Number {
203 fn accept<V: Visit>(&self, _: &mut V) {}
204}
205
206impl VisitableMut for token_macros::Number {
207 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
208}
209
210impl Visitable for token_macros::String {
211 fn accept<V: Visit>(&self, v: &mut V) {
212 v.visit_string(self);
213 v.exit_string(self);
214 }
215}
216
217impl VisitableMut for token_macros::String {
218 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
219 v.visit_string(self);
220 v.exit_string(self);
221 }
222}
223
224impl<T> Visitable for Option<T>
225where
226 T: Visitable,
227{
228 fn accept<V: Visit>(&self, v: &mut V) {
229 if let Some(node) = self {
230 node.accept(v)
231 }
232 }
233}
234
235impl<'a, T: VisitableMut> VisitableMut for BumpBox<'a, T> {
236 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
237 (**self).accept_mut(v)
238 }
239}
240
241impl<'a, T: Visitable> Visitable for BumpBox<'a, T> {
242 fn accept<V: Visit>(&self, v: &mut V) {
243 (**self).accept(v)
244 }
245}
246
247impl<'a, T, const MIN: usize> VisitableMut for CommaSeparated<'a, T, MIN>
248where
249 T: VisitableMut + Peek<'a> + Parse<'a> + ToCursors + ToSpan,
250{
251 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
252 for (node, _) in self {
253 node.accept_mut(v)
254 }
255 }
256}
257
258impl<'a, T, const MIN: usize> Visitable for CommaSeparated<'a, T, MIN>
259where
260 T: Visitable + Peek<'a> + Parse<'a> + ToCursors + ToSpan,
261{
262 fn accept<V: Visit>(&self, v: &mut V) {
263 for (node, _) in self {
264 node.accept(v)
265 }
266 }
267}
268
269impl<'a, T> VisitableMut for Declaration<'a, T, CssMetadata>
270where
271 T: VisitableMut + DeclarationValue<'a, CssMetadata>,
272{
273 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
274 v.visit_declaration(self);
275 self.value.accept_mut(v);
276 v.exit_declaration(self);
277 }
278}
279
280impl<'a, T> QueryableNode for Declaration<'a, T, CssMetadata>
281where
282 T: DeclarationValue<'a, CssMetadata> + QueryableNode,
283{
284 const NODE_ID: NodeId = NodeId::StyleValue;
285
286 fn node_id(&self) -> NodeId {
287 T::NODE_ID
288 }
289
290 fn get_property(&self, kind: PropertyKind) -> Option<Cursor> {
291 match kind {
292 PropertyKind::Name => Some(self.name.into()),
293 _ => None,
294 }
295 }
296}
297
298impl<'a, T> Visitable for Declaration<'a, T, CssMetadata>
299where
300 T: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
301{
302 fn accept<V: Visit>(&self, v: &mut V) {
303 v.visit_queryable_node(self);
304 v.visit_declaration::<T>(self);
305 self.value.accept(v);
306 v.exit_declaration::<T>(self);
307 v.exit_queryable_node(self);
308 }
309}
310
311impl<'a, T> VisitableMut for DeclarationList<'a, T, CssMetadata>
312where
313 T: VisitableMut + DeclarationValue<'a, CssMetadata>,
314{
315 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
316 for declaration in &mut self.declarations {
317 declaration.accept_mut(v);
318 }
319 }
320}
321
322impl<'a, T> Visitable for DeclarationList<'a, T, CssMetadata>
323where
324 T: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
325{
326 fn accept<V: Visit>(&self, v: &mut V) {
327 for declaration in &self.declarations {
328 declaration.accept(v);
329 }
330 }
331}
332
333impl<'a, T, M> VisitableMut for RuleList<'a, T, M>
334where
335 T: VisitableMut + Parse<'a> + ToCursors + ToSpan + NodeWithMetadata<M>,
336 M: NodeMetadata,
337{
338 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
339 self.rules.accept_mut(v);
340 }
341}
342
343impl<'a, T, M> Visitable for RuleList<'a, T, M>
344where
345 T: Visitable + Parse<'a> + ToCursors + ToSpan + NodeWithMetadata<M>,
346 M: NodeMetadata,
347{
348 fn accept<V: Visit>(&self, v: &mut V) {
349 self.rules.accept(v);
350 }
351}
352
353impl<'a, P, D, R> VisitableMut for QualifiedRule<'a, P, D, R, CssMetadata>
354where
355 P: VisitableMut + Peek<'a> + Parse<'a> + ToCursors + ToSpan,
356 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
357 R: VisitableMut + Parse<'a> + ToCursors + ToSpan,
358 Block<'a, D, R, CssMetadata>: Parse<'a> + ToCursors + ToSpan,
359{
360 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
361 self.prelude.accept_mut(v);
362 self.block.accept_mut(v);
363 }
364}
365
366impl<'a, P, D, R> Visitable for QualifiedRule<'a, P, D, R, CssMetadata>
367where
368 P: Visitable + Peek<'a> + Parse<'a> + ToCursors + ToSpan,
369 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
370 R: Visitable + Parse<'a> + ToCursors + ToSpan,
371 Block<'a, D, R, CssMetadata>: Parse<'a> + ToCursors + ToSpan,
372{
373 fn accept<V: Visit>(&self, v: &mut V) {
374 self.prelude.accept(v);
375 self.block.accept(v);
376 }
377}
378
379impl<'a, D, R> VisitableMut for Block<'a, D, R, CssMetadata>
380where
381 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
382 R: VisitableMut + Parse<'a> + ToCursors + ToSpan,
383{
384 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
385 for declaration in &mut self.declarations {
386 declaration.accept_mut(v);
387 }
388 for rule in &mut self.rules {
389 rule.accept_mut(v);
390 }
391 }
392}
393
394impl<'a, D, R> Visitable for Block<'a, D, R, CssMetadata>
395where
396 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
397 R: Visitable + Parse<'a> + ToCursors + ToSpan,
398{
399 fn accept<V: Visit>(&self, v: &mut V) {
400 for declaration in &self.declarations {
401 declaration.accept(v);
402 }
403 for rule in &self.rules {
404 rule.accept(v);
405 }
406 }
407}
408
409impl<'a, T> VisitableMut for Vec<'a, T>
410where
411 T: VisitableMut,
412{
413 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
414 for node in self {
415 node.accept_mut(v);
416 }
417 }
418}
419
420impl<'a, T> Visitable for Vec<'a, T>
421where
422 T: Visitable,
423{
424 fn accept<V: Visit>(&self, v: &mut V) {
425 for node in self {
426 node.accept(v)
427 }
428 }
429}
430
431impl<'a> VisitableMut for BadDeclaration<'a> {
432 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
433 v.visit_bad_declaration(self);
434 v.exit_bad_declaration(self);
435 }
436}
437
438impl<'a> Visitable for BadDeclaration<'a> {
439 fn accept<V: Visit>(&self, v: &mut V) {
440 v.visit_bad_declaration(self);
441 v.exit_bad_declaration(self);
442 }
443}
444
445impl<'a> VisitableMut for ComponentValues<'a> {
446 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
447}
448
449impl<'a> Visitable for ComponentValues<'a> {
450 fn accept<V: Visit>(&self, _: &mut V) {}
451}
452
453impl<D, M> VisitableMut for NoBlockAllowed<D, M> {
454 fn accept_mut<V: VisitMut>(&mut self, _: &mut V) {}
455}
456
457impl<D, M> Visitable for NoBlockAllowed<D, M> {
458 fn accept<V: Visit>(&self, _: &mut V) {}
459}
460
461impl<'a, D> VisitableMut for DeclarationGroup<'a, D, CssMetadata>
462where
463 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
464{
465 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
466 for declaration in &mut self.declarations {
467 declaration.accept_mut(v)
468 }
469 }
470}
471
472impl<'a, D> Visitable for DeclarationGroup<'a, D, CssMetadata>
473where
474 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
475{
476 fn accept<V: Visit>(&self, v: &mut V) {
477 for declaration in &self.declarations {
478 declaration.accept(v)
479 }
480 }
481}
482
483impl<'a, D> VisitableMut for DeclarationOrBad<'a, D, CssMetadata>
484where
485 D: VisitableMut + DeclarationValue<'a, CssMetadata>,
486{
487 fn accept_mut<V: VisitMut>(&mut self, v: &mut V) {
488 match self {
489 Self::Declaration(d) => d.accept_mut(v),
490 Self::Bad(b) => b.accept_mut(v),
491 }
492 }
493}
494
495impl<'a, D> Visitable for DeclarationOrBad<'a, D, CssMetadata>
496where
497 D: Visitable + DeclarationValue<'a, CssMetadata> + QueryableNode,
498{
499 fn accept<V: Visit>(&self, v: &mut V) {
500 match self {
501 Self::Declaration(d) => d.accept(v),
502 Self::Bad(b) => b.accept(v),
503 }
504 }
505}
506
507macro_rules! impl_tuple_mut {
508 ($($T:ident),*) => {
509 impl<$($T),*> VisitableMut for ($($T),*)
510 where
511 $($T: VisitableMut,)*
512 {
513 #[allow(non_snake_case)]
514 #[allow(unused)]
515 fn accept_mut<VI: VisitMut>(&mut self, v: &mut VI) {
516 let ($($T),*) = self;
517 $($T.accept_mut(v);)*
518 }
519 }
520 };
521}
522
523impl_tuple_mut!(T, U);
524impl_tuple_mut!(T, U, V);
525impl_tuple_mut!(T, U, V, W);
526
527macro_rules! impl_tuple {
528 ($($T:ident),*) => {
529 impl<$($T),*> Visitable for ($($T),*)
530 where
531 $($T: Visitable,)*
532 {
533 #[allow(non_snake_case)]
534 #[allow(unused)]
535 fn accept<VI: Visit>(&self, v: &mut VI) {
536 let ($($T),*) = self;
537 $($T.accept(v);)*
538 }
539 }
540 };
541}
542impl_tuple!(T, U);
543impl_tuple!(T, U, V);
544impl_tuple!(T, U, V, W);