mago_walker/
lib.rs

1#![allow(unused_variables)]
2
3use mago_ast::Program;
4use mago_ast::ast::*;
5
6/// Macro for generating a walker trait and associated functions for traversing an AST.
7///
8/// For each node type provided to the macro, this trait generates three methods:
9///
10/// - `walk_in_<node>`: Called before walking the children of the node.
11///   Override this to perform actions before traversing the node's children.
12/// - `walk_<node>`: Orchestrates the traversal of the node by calling `walk_in_<node>`,
13///   then walking its children, and finally calling `walk_out_<node>`.
14///   **It is not recommended to override this method directly.**
15/// - `walk_out_<node>`: Called after walking the children of the node.
16///   Override this to perform actions after traversing the node's children.
17///
18/// Additionally, for each node type, a standalone `walk_<node>` function is generated.
19/// This function performs the default traversal behavior and can be used within an
20/// overridden `walk_<node>` method to retain the default traversal logic.
21macro_rules! generate_ast_walker {
22    (
23        using($walker:ident, $context:ident):
24
25        $(
26            $node_type:ty as $var_name:ident => $code:block
27        )*
28    ) => {
29        /// A trait that defines a mutable walker to traverse AST nodes.
30        ///
31        /// Each method can be overridden to customize how a node is entered, walked, and exited.
32        pub trait MutWalker<C>: Sync + Send
33        {
34            $(
35                paste::paste! {
36                    #[inline(always)]
37                    fn [<walk_in_ $var_name>](&mut self, $var_name: &$node_type, context: &mut C) {
38                        // Do nothing by default
39                    }
40
41                    #[inline(always)]
42                    fn [<walk_ $var_name>](&mut self, $var_name: &$node_type, $context: &mut C) {
43                        let $walker = self;
44
45                        $walker.[<walk_in_ $var_name>]($var_name, $context);
46                        $code
47                        $walker.[<walk_out_ $var_name>]($var_name, $context);
48                    }
49
50                    #[inline(always)]
51                    fn [<walk_out_ $var_name>](&mut self, $var_name: &$node_type, context: &mut C) {
52                        // Do nothing by default
53                    }
54                }
55            )*
56        }
57
58        /// A trait that defines a walker to traverse AST nodes.
59        ///
60        /// Each method can be overridden to customize how a node is entered, walked, and exited.
61        pub trait Walker<C>: Sync + Send
62        {
63            $(
64                paste::paste! {
65                    #[inline(always)]
66                    fn [<walk_in_ $var_name>](&self, $var_name: &$node_type, context: &mut C) {
67                        // Do nothing by default
68                    }
69
70                    #[inline(always)]
71                    fn [<walk_ $var_name>](&self, $var_name: &$node_type, $context: &mut C) {
72                        let $walker = self;
73
74                        $walker.[<walk_in_ $var_name>]($var_name, $context);
75                        $code
76                        $walker.[<walk_out_ $var_name>]($var_name, $context);
77                    }
78
79                    #[inline(always)]
80                    fn [<walk_out_ $var_name>](&self, $var_name: &$node_type, context: &mut C) {
81                        // Do nothing by default
82                    }
83                }
84            )*
85        }
86
87        $(
88            paste::paste! {
89                #[inline(always)]
90                pub fn [<walk_ $var_name _mut>]<W, C>($walker: &mut W, $var_name: &$node_type, $context: &mut C)
91                    where
92                        W: MutWalker<C>
93                {
94                    $walker.[<walk_in_ $var_name>]($var_name, $context);
95                    $code
96                    $walker.[<walk_out_ $var_name>]($var_name, $context);
97                }
98
99
100                #[inline(always)]
101                pub fn [<walk_ $var_name>]<W, C>($walker: &W, $var_name: &$node_type, $context: &mut C)
102                    where
103                        W: Walker<C>
104                {
105                    $walker.[<walk_in_ $var_name>]($var_name, $context);
106                    $code
107                    $walker.[<walk_out_ $var_name>]($var_name, $context);
108                }
109            }
110        )*
111    }
112}
113
114generate_ast_walker! {
115    using(walker, context):
116
117    Program as program => {
118        for statement in program.statements.iter() {
119            walker.walk_statement(statement, context);
120        }
121    }
122
123    Statement as statement => {
124        match &statement {
125            Statement::OpeningTag(opening_tag) => walker.walk_opening_tag(opening_tag, context),
126            Statement::ClosingTag(closing_tag) => walker.walk_closing_tag(closing_tag, context),
127            Statement::Inline(inline) => walker.walk_inline(inline, context),
128            Statement::Namespace(namespace) => walker.walk_namespace(namespace, context),
129            Statement::Use(r#use) => walker.walk_use(r#use, context),
130            Statement::Class(class) => walker.walk_class(class, context),
131            Statement::Interface(interface) => walker.walk_interface(interface, context),
132            Statement::Trait(r#trait) => walker.walk_trait(r#trait, context),
133            Statement::Enum(r#enum) => walker.walk_enum(r#enum, context),
134            Statement::Block(block) => walker.walk_block(block, context),
135            Statement::Constant(constant) => walker.walk_constant(constant, context),
136            Statement::Function(function) => walker.walk_function(function, context),
137            Statement::Declare(declare) => walker.walk_declare(declare, context),
138            Statement::Goto(goto) => walker.walk_goto(goto, context),
139            Statement::Label(label) => walker.walk_label(label, context),
140            Statement::Try(r#try) => walker.walk_try(r#try, context),
141            Statement::Foreach(foreach) => walker.walk_foreach(foreach, context),
142            Statement::For(r#for) => walker.walk_for(r#for, context),
143            Statement::While(r#while) => walker.walk_while(r#while, context),
144            Statement::DoWhile(do_while) => walker.walk_do_while(do_while, context),
145            Statement::Continue(r#continue) => walker.walk_continue(r#continue, context),
146            Statement::Break(r#break) => walker.walk_break(r#break, context),
147            Statement::Switch(switch) => walker.walk_switch(switch, context),
148            Statement::If(r#if) => walker.walk_if(r#if, context),
149            Statement::Return(r#return) => walker.walk_return(r#return, context),
150            Statement::Expression(expression) => walker.walk_statement_expression(expression, context),
151            Statement::Echo(echo) => walker.walk_echo(echo, context),
152            Statement::Global(global) => walker.walk_global(global, context),
153            Statement::Static(r#static) => walker.walk_static(r#static, context),
154            Statement::HaltCompiler(halt_compiler) => walker.walk_halt_compiler(halt_compiler, context),
155            Statement::Unset(unset) => walker.walk_unset(unset, context),
156            Statement::Noop(_) => {
157                // Do nothing by default
158            },
159        }
160    }
161
162    OpeningTag as opening_tag => {
163        match opening_tag {
164            OpeningTag::Full(full_opening_tag) => walker.walk_full_opening_tag(full_opening_tag, context),
165            OpeningTag::Short(short_opening_tag) => walker.walk_short_opening_tag(short_opening_tag, context),
166            OpeningTag::Echo(echo_opening_tag) => walker.walk_echo_opening_tag(echo_opening_tag, context),
167        }
168    }
169
170    FullOpeningTag as full_opening_tag => {
171        // Do nothing by default
172    }
173
174    ShortOpeningTag as short_opening_tag => {
175        // Do nothing by default
176    }
177
178    EchoOpeningTag as echo_opening_tag => {
179        // Do nothing by default
180    }
181
182    ClosingTag as closing_tag => {
183        // Do nothing by default
184    }
185
186    Inline as inline => {
187        // Do nothing by default
188    }
189
190    Namespace as namespace => {
191        walker.walk_keyword(&namespace.namespace, context);
192        if let Some(name) = &namespace.name {
193            walker.walk_identifier(name, context);
194        }
195
196        walker.walk_namespace_body(&namespace.body, context);
197    }
198
199    NamespaceBody as namespace_body => {
200        match namespace_body {
201            NamespaceBody::Implicit(namespace_implicit_body) => walker.walk_namespace_implicit_body(namespace_implicit_body, context),
202            NamespaceBody::BraceDelimited(block) => walker.walk_block(block, context),
203        }
204    }
205
206    NamespaceImplicitBody as namespace_implicit_body => {
207        walker.walk_terminator(&namespace_implicit_body.terminator, context);
208
209        for statement in namespace_implicit_body.statements.iter() {
210            walker.walk_statement(statement, context);
211        }
212    }
213
214    Terminator as terminator => {
215        match terminator {
216            Terminator::Semicolon(_) => {
217                // Do nothing by default
218            }
219            Terminator::ClosingTag(closing_tag) => {
220                walker.walk_closing_tag(closing_tag, context);
221            }
222            Terminator::TagPair(closing_tag, opening_tag) => {
223                walker.walk_closing_tag(closing_tag, context);
224                walker.walk_opening_tag(opening_tag, context);
225            }
226        }
227    }
228
229    Use as r#use => {
230        walker.walk_keyword(&r#use.r#use, context);
231
232        walker.walk_use_items(&r#use.items, context);
233
234        walker.walk_terminator(&r#use.terminator, context);
235    }
236
237    UseItems as use_items => {
238        match use_items {
239            UseItems::Sequence(use_item_sequence) => {
240                walker.walk_use_item_sequence(use_item_sequence, context);
241            }
242            UseItems::TypedSequence(typed_use_item_sequence) => {
243                walker.walk_typed_use_item_sequence(typed_use_item_sequence, context);
244            }
245            UseItems::TypedList(typed_use_item_list) => {
246                walker.walk_typed_use_item_list(typed_use_item_list, context);
247            }
248            UseItems::MixedList(mixed_use_item_list) => {
249                walker.walk_mixed_use_item_list(mixed_use_item_list, context);
250            }
251        }
252    }
253
254    UseItemSequence as use_item_sequence => {
255        for use_item in use_item_sequence.items.iter() {
256            walker.walk_use_item(use_item, context);
257        }
258    }
259
260    UseItem as use_item => {
261        walker.walk_identifier(&use_item.name, context);
262
263        if let Some(alias) = &use_item.alias {
264            walker.walk_use_item_alias(alias, context);
265        }
266    }
267
268    UseItemAlias as use_item_alias => {
269        walker.walk_keyword(&use_item_alias.r#as, context);
270        walker.walk_local_identifier(&use_item_alias.identifier, context);
271    }
272
273    TypedUseItemSequence as typed_use_item_sequence => {
274        walker.walk_use_type(&typed_use_item_sequence.r#type, context);
275
276        for use_item in typed_use_item_sequence.items.iter() {
277            walker.walk_use_item(use_item, context);
278        }
279    }
280
281    UseType as use_type => {
282        match &use_type {
283            UseType::Function(keyword) => walker.walk_keyword(keyword, context),
284            UseType::Const(keyword) => walker.walk_keyword(keyword, context),
285        }
286    }
287
288    TypedUseItemList as typed_use_item_list => {
289        walker.walk_use_type(&typed_use_item_list.r#type, context);
290        walker.walk_identifier(&typed_use_item_list.namespace, context);
291
292        for use_item in typed_use_item_list.items.iter() {
293            walker.walk_use_item(use_item, context);
294        }
295    }
296
297    MixedUseItemList as mixed_use_item_list => {
298        walker.walk_identifier(&mixed_use_item_list.namespace, context);
299
300        for maybe_typed_use_item in mixed_use_item_list.items.iter() {
301            walker.walk_maybe_typed_use_item(maybe_typed_use_item, context);
302        }
303    }
304
305    MaybeTypedUseItem as maybe_typed_use_item => {
306        if let Some(use_type) = &maybe_typed_use_item.r#type {
307            walker.walk_use_type(use_type, context);
308        }
309
310        walker.walk_use_item(&maybe_typed_use_item.item, context);
311    }
312
313    AttributeList as attribute_list => {
314        for attribute in attribute_list.attributes.iter() {
315            walker.walk_attribute(attribute, context);
316        }
317    }
318
319    Attribute as attribute => {
320        walker.walk_identifier(&attribute.name, context);
321
322        if let Some(argument_list) = &attribute.arguments {
323            walker.walk_argument_list(argument_list, context);
324        }
325    }
326
327    ArgumentList as argument_list => {
328        for argument in argument_list.arguments.iter() {
329            walker.walk_argument(argument, context);
330        }
331    }
332
333    Argument as argument => {
334        match &argument {
335            Argument::Positional(positional_argument) => {
336                walker.walk_positional_argument(positional_argument, context);
337            }
338            Argument::Named(named_argument) => {
339                walker.walk_named_argument(named_argument, context);
340            }
341        }
342    }
343
344    PositionalArgument as positional_argument => {
345        walker.walk_expression(&positional_argument.value, context);
346    }
347
348    NamedArgument as named_argument => {
349        walker.walk_local_identifier(&named_argument.name, context);
350        walker.walk_expression(&named_argument.value, context);
351    }
352
353    Modifier as modifier => {
354        walker.walk_keyword(modifier.get_keyword(), context);
355    }
356
357    Extends as extends => {
358        walker.walk_keyword(&extends.extends, context);
359
360        for ty in extends.types.iter() {
361            walker.walk_identifier(ty, context);
362        }
363    }
364
365    Implements as implements => {
366        walker.walk_keyword(&implements.implements, context);
367
368        for ty in implements.types.iter() {
369            walker.walk_identifier(ty, context);
370        }
371    }
372
373    Class as class => {
374        for attribute_list in class.attribute_lists.iter() {
375            walker.walk_attribute_list(attribute_list, context);
376        }
377
378        for modifier in class.modifiers.iter() {
379            walker.walk_modifier(modifier, context);
380        }
381
382        walker.walk_keyword(&class.class, context);
383        walker.walk_local_identifier(&class.name, context);
384        if let Some(extends) = &class.extends {
385            walker.walk_extends(extends, context);
386        }
387
388        if let Some(implements) = &class.implements {
389            walker.walk_implements(implements, context);
390        }
391
392        for class_member in class.members.iter() {
393            walker.walk_class_like_member(class_member, context);
394        }
395    }
396
397    Interface as interface => {
398        for attribute_list in interface.attribute_lists.iter() {
399            walker.walk_attribute_list(attribute_list, context);
400        }
401
402        walker.walk_keyword(&interface.interface, context);
403        walker.walk_local_identifier(&interface.name, context);
404
405        if let Some(extends) = &interface.extends {
406            walker.walk_extends(extends, context);
407        }
408
409        for class_member in interface.members.iter() {
410            walker.walk_class_like_member(class_member, context);
411        }
412    }
413
414    Trait as r#trait => {
415        for attribute_list in r#trait.attribute_lists.iter() {
416            walker.walk_attribute_list(attribute_list, context);
417        }
418
419        walker.walk_keyword(&r#trait.r#trait, context);
420        walker.walk_local_identifier(&r#trait.name, context);
421
422        for class_member in r#trait.members.iter() {
423            walker.walk_class_like_member(class_member, context);
424        }
425    }
426
427    Enum as r#enum => {
428        for attribute_list in r#enum.attribute_lists.iter() {
429            walker.walk_attribute_list(attribute_list, context);
430        }
431
432        walker.walk_keyword(&r#enum.r#enum, context);
433        walker.walk_local_identifier(&r#enum.name, context);
434
435        if let Some(backing_type_hint) = &r#enum.backing_type_hint {
436            walker.walk_enum_backing_type_hint(backing_type_hint, context);
437        }
438
439        if let Some(implements) = &r#enum.implements {
440            walker.walk_implements(implements, context);
441        }
442
443        for class_member in r#enum.members.iter() {
444            walker.walk_class_like_member(class_member, context);
445        }
446    }
447
448    EnumBackingTypeHint as enum_backing_type_hint => {
449        walker.walk_hint(&enum_backing_type_hint.hint, context);
450    }
451
452    ClassLikeMember as class_like_member => {
453        match class_like_member {
454            ClassLikeMember::TraitUse(trait_use) => {
455                walker.walk_trait_use(trait_use, context);
456            }
457            ClassLikeMember::Constant(class_like_constant) => {
458                walker.walk_class_like_constant(class_like_constant, context);
459            }
460            ClassLikeMember::Property(property) => {
461                walker.walk_property(property, context);
462            }
463            ClassLikeMember::EnumCase(enum_case) => {
464                walker.walk_enum_case(enum_case, context);
465            }
466            ClassLikeMember::Method(method) => {
467                walker.walk_method(method, context);
468            }
469        }
470    }
471
472    TraitUse as trait_use => {
473        walker.walk_keyword(&trait_use.r#use, context);
474
475        for trait_name in trait_use.trait_names.iter() {
476            walker.walk_identifier(trait_name, context);
477        }
478
479        walker.walk_trait_use_specification(&trait_use.specification, context);
480    }
481
482    TraitUseSpecification as trait_use_specification => {
483        match trait_use_specification {
484            TraitUseSpecification::Abstract(trait_use_abstract_specification) => {
485                walker.walk_trait_use_abstract_specification(trait_use_abstract_specification, context);
486            }
487            TraitUseSpecification::Concrete(trait_use_concrete_specification) => {
488                walker.walk_trait_use_concrete_specification(trait_use_concrete_specification, context);
489            }
490        }
491    }
492
493    TraitUseAbstractSpecification as trait_use_abstract_specification => {
494        walker.walk_terminator(&trait_use_abstract_specification.0, context);
495    }
496
497    TraitUseConcreteSpecification as trait_use_concrete_specification => {
498        for adaptation in trait_use_concrete_specification.adaptations.iter() {
499            walker.walk_trait_use_adaptation(
500                adaptation,
501
502                context,
503            );
504        }
505    }
506
507    TraitUseAdaptation as trait_use_adaptation => {
508        match trait_use_adaptation {
509            TraitUseAdaptation::Precedence(trait_use_precedence_adaptation) => {
510                walker.walk_trait_use_precedence_adaptation(trait_use_precedence_adaptation, context);
511            },
512            TraitUseAdaptation::Alias(trait_use_alias_adaptation) => {
513                walker.walk_trait_use_alias_adaptation(trait_use_alias_adaptation, context);
514            },
515        }
516    }
517
518    TraitUsePrecedenceAdaptation as trait_use_precedence_adaptation => {
519        walker.walk_trait_use_absolute_method_reference(
520            &trait_use_precedence_adaptation.method_reference,
521
522            context,
523        );
524
525        walker.walk_keyword(&trait_use_precedence_adaptation.insteadof, context);
526
527        for trait_name in trait_use_precedence_adaptation.trait_names.iter() {
528            walker.walk_identifier(trait_name, context);
529        }
530
531        walker.walk_terminator(&trait_use_precedence_adaptation.terminator, context);
532    }
533
534    TraitUseAbsoluteMethodReference as trait_use_absolute_method_reference => {
535        walker.walk_identifier(&trait_use_absolute_method_reference.trait_name, context);
536        walker.walk_local_identifier(&trait_use_absolute_method_reference.method_name, context);
537    }
538
539    TraitUseAliasAdaptation as trait_use_alias_adaptation => {
540        walker.walk_trait_use_method_reference(
541            &trait_use_alias_adaptation.method_reference,
542
543            context,
544        );
545
546        walker.walk_keyword(&trait_use_alias_adaptation.r#as, context);
547
548        if let Some(modifier) = &trait_use_alias_adaptation.visibility {
549            walker.walk_modifier(modifier, context);
550        }
551
552        if let Some(alias) = &trait_use_alias_adaptation.alias {
553            walker.walk_local_identifier(alias, context);
554        }
555
556        walker.walk_terminator(&trait_use_alias_adaptation.terminator, context);
557    }
558
559    TraitUseMethodReference as trait_use_method_reference => {
560        match trait_use_method_reference {
561            TraitUseMethodReference::Identifier(local_identifier) => {
562                walker.walk_local_identifier(local_identifier, context);
563            },
564            TraitUseMethodReference::Absolute(absolute) => {
565                walker.walk_trait_use_absolute_method_reference(absolute, context);
566            },
567        }
568    }
569
570    ClassLikeConstant as class_like_constant => {
571        for attribute_list in class_like_constant.attribute_lists.iter() {
572            walker.walk_attribute_list(attribute_list, context);
573        }
574
575        for modifier in class_like_constant.modifiers.iter() {
576            walker.walk_modifier(modifier, context);
577        }
578
579        walker.walk_keyword(&class_like_constant.r#const, context);
580
581        if let Some(hint) = &class_like_constant.hint {
582            walker.walk_hint(hint, context);
583        }
584
585        for item in class_like_constant.items.iter() {
586            walker.walk_class_like_constant_item(item, context);
587        }
588
589        walker.walk_terminator(&class_like_constant.terminator, context);
590    }
591
592    ClassLikeConstantItem as class_like_constant_item => {
593        walker.walk_local_identifier(&class_like_constant_item.name, context);
594        walker.walk_expression(&class_like_constant_item.value, context);
595    }
596
597    Property as property => {
598        match property {
599            Property::Plain(plain_property) => {
600                walker.walk_plain_property(plain_property, context);
601            }
602            Property::Hooked(hooked_property) => {
603                walker.walk_hooked_property(hooked_property, context);
604            }
605        }
606    }
607
608    PlainProperty as plain_property => {
609        for attribute_list in plain_property.attribute_lists.iter() {
610            walker.walk_attribute_list(attribute_list, context);
611        }
612
613        for modifier in plain_property.modifiers.iter() {
614            walker.walk_modifier(modifier, context);
615        }
616
617        if let Some(var) = &plain_property.var {
618            walker.walk_keyword(var, context);
619        }
620
621        if let Some(hint) = &plain_property.hint {
622            walker.walk_hint(hint, context);
623        }
624
625        for item in plain_property.items.iter() {
626            walker.walk_property_item(item, context);
627        }
628
629        walker.walk_terminator(&plain_property.terminator, context);
630    }
631
632    PropertyItem as property_item => {
633        match property_item {
634            PropertyItem::Abstract(property_abstract_item) => {
635                walker.walk_property_abstract_item(property_abstract_item, context);
636            }
637            PropertyItem::Concrete(property_concrete_item) => {
638                walker.walk_property_concrete_item(property_concrete_item, context);
639            }
640        }
641    }
642
643    PropertyAbstractItem as property_abstract_item => {
644        walker.walk_direct_variable(&property_abstract_item.variable, context);
645    }
646
647    PropertyConcreteItem as property_concrete_item => {
648        walker.walk_direct_variable(&property_concrete_item.variable, context);
649        walker.walk_expression(&property_concrete_item.value, context);
650    }
651
652    HookedProperty as hooked_property => {
653        for attribute_list in hooked_property.attribute_lists.iter() {
654            walker.walk_attribute_list(attribute_list, context);
655        }
656
657        for modifier in hooked_property.modifiers.iter() {
658            walker.walk_modifier(modifier, context);
659        }
660
661        if let Some(var) = &hooked_property.var {
662            walker.walk_keyword(var, context);
663        }
664
665        if let Some(hint) = &hooked_property.hint {
666            walker.walk_hint(hint, context);
667        }
668
669        walker.walk_property_item(&hooked_property.item, context);
670        walker.walk_property_hook_list(&hooked_property.hooks, context);
671    }
672
673    PropertyHookList as property_hook_list => {
674        for hook in property_hook_list.hooks.iter() {
675            walker.walk_property_hook(hook, context);
676        }
677    }
678
679    PropertyHook as property_hook => {
680        for attribute_list in property_hook.attribute_lists.iter() {
681            walker.walk_attribute_list(attribute_list, context);
682        }
683
684        for modifier in property_hook.modifiers.iter() {
685            walker.walk_modifier(modifier, context);
686        }
687
688        walker.walk_local_identifier(&property_hook.name, context);
689        if let Some(parameters) = &property_hook.parameters {
690            walker.walk_function_like_parameter_list(parameters, context);
691        }
692
693        walker.walk_property_hook_body(&property_hook.body, context);
694    }
695
696    PropertyHookBody as property_hook_body => {
697        match property_hook_body {
698            PropertyHookBody::Abstract(property_hook_abstract_body) => {
699                walker.walk_property_hook_abstract_body(property_hook_abstract_body, context);
700            }
701            PropertyHookBody::Concrete(property_hook_concrete_body) => {
702                walker.walk_property_hook_concrete_body(property_hook_concrete_body, context);
703            }
704        }
705    }
706
707    PropertyHookAbstractBody as property_hook_abstract_body => {
708        // Do nothing by default
709    }
710
711    PropertyHookConcreteBody as property_hook_concrete_body => {
712        match property_hook_concrete_body {
713            PropertyHookConcreteBody::Block(block) => {
714                walker.walk_block(block, context);
715            }
716            PropertyHookConcreteBody::Expression(property_hook_concrete_expression_body) => {
717                walker.walk_property_hook_concrete_expression_body(property_hook_concrete_expression_body, context);
718            }
719        }
720    }
721
722    PropertyHookConcreteExpressionBody as property_hook_concrete_expression_body => {
723        walker.walk_expression(&property_hook_concrete_expression_body.expression, context);
724    }
725
726    FunctionLikeParameterList as function_like_parameter_list => {
727        for parameter in function_like_parameter_list.parameters.iter() {
728            walker.walk_function_like_parameter(parameter, context);
729        }
730    }
731
732    FunctionLikeParameter as function_like_parameter => {
733        for attribute_list in function_like_parameter.attribute_lists.iter() {
734            walker.walk_attribute_list(attribute_list, context);
735        }
736
737        for modifier in function_like_parameter.modifiers.iter() {
738            walker.walk_modifier(modifier, context);
739        }
740
741        if let Some(hint) = &function_like_parameter.hint {
742            walker.walk_hint(hint, context);
743        }
744
745        walker.walk_direct_variable(&function_like_parameter.variable, context);
746        if let Some(default_value) = &function_like_parameter.default_value {
747            walker.walk_function_like_parameter_default_value(default_value, context);
748        }
749
750        if let Some(hooks) = &function_like_parameter.hooks {
751            walker.walk_property_hook_list(hooks, context);
752        }
753    }
754
755    FunctionLikeParameterDefaultValue as function_like_parameter_default_value => {
756        walker.walk_expression(&function_like_parameter_default_value.value, context);
757    }
758
759    EnumCase as enum_case => {
760        for attribute_list in enum_case.attribute_lists.iter() {
761            walker.walk_attribute_list(attribute_list, context);
762        }
763
764        walker.walk_keyword(&enum_case.case, context);
765        walker.walk_enum_case_item(&enum_case.item, context);
766        walker.walk_terminator(&enum_case.terminator, context);
767    }
768
769    EnumCaseItem as enum_case_item => {
770        match enum_case_item {
771            EnumCaseItem::Unit(enum_case_unit_item) => {
772                walker.walk_enum_case_unit_item(enum_case_unit_item, context);
773            }
774            EnumCaseItem::Backed(enum_case_backed_item) => {
775                walker.walk_enum_case_backed_item(enum_case_backed_item, context);
776            }
777        }
778    }
779
780    EnumCaseUnitItem as enum_case_unit_item => {
781        walker.walk_local_identifier(&enum_case_unit_item.name, context);
782    }
783
784    EnumCaseBackedItem as enum_case_backed_item => {
785        walker.walk_local_identifier(&enum_case_backed_item.name, context);
786        walker.walk_expression(&enum_case_backed_item.value, context);
787    }
788
789    Method as method => {
790        for attribute_list in method.attribute_lists.iter() {
791            walker.walk_attribute_list(attribute_list, context);
792        }
793
794        for modifier in method.modifiers.iter() {
795            walker.walk_modifier(modifier, context);
796        }
797
798        walker.walk_keyword(&method.function, context);
799        walker.walk_local_identifier(&method.name, context);
800        walker.walk_function_like_parameter_list(&method.parameter_list, context);
801        if let Some(hint) = &method.return_type_hint {
802            walker.walk_function_like_return_type_hint(hint, context);
803        }
804
805        walker.walk_method_body(&method.body, context);
806    }
807
808    MethodBody as method_body => {
809        match method_body {
810            MethodBody::Abstract(method_abstract_body) => {
811                walker.walk_method_abstract_body(method_abstract_body, context);
812            }
813            MethodBody::Concrete(method_concrete_body) => {
814                walker.walk_block(method_concrete_body, context);
815            }
816        }
817    }
818
819    MethodAbstractBody as method_abstract_body => {
820        // Do nothing by default
821    }
822
823    FunctionLikeReturnTypeHint as function_like_return_type_hint => {
824        walker.walk_hint(&function_like_return_type_hint.hint, context);
825    }
826
827    Block as block => {
828        for statement in block.statements.iter() {
829            walker.walk_statement(statement, context);
830        }
831    }
832
833    Constant as constant => {
834        for attribute_list in constant.attribute_lists.iter() {
835            walker.walk_attribute_list(attribute_list, context);
836        }
837
838        walker.walk_keyword(&constant.r#const, context);
839        for item in constant.items.iter() {
840            walker.walk_constant_item(item, context);
841        }
842
843        walker.walk_terminator(&constant.terminator, context);
844    }
845
846    ConstantItem as constant_item => {
847        walker.walk_local_identifier(&constant_item.name, context);
848        walker.walk_expression(&constant_item.value, context);
849    }
850
851    Function as function => {
852        for attribute_list in function.attribute_lists.iter() {
853            walker.walk_attribute_list(attribute_list, context);
854        }
855
856        walker.walk_keyword(&function.function, context);
857        walker.walk_local_identifier(&function.name, context);
858        walker.walk_function_like_parameter_list(&function.parameter_list, context);
859        if let Some(hint) = &function.return_type_hint {
860            walker.walk_function_like_return_type_hint(hint, context);
861        }
862
863        walker.walk_block(&function.body, context);
864    }
865
866    Declare as declare => {
867        walker.walk_keyword(&declare.declare, context);
868        for item in declare.items.iter() {
869            walker.walk_declare_item(item, context);
870        }
871
872        walker.walk_declare_body(&declare.body, context);
873    }
874
875    DeclareItem as declare_item => {
876        walker.walk_local_identifier(&declare_item.name, context);
877        walker.walk_expression(&declare_item.value, context);
878    }
879
880    DeclareBody as declare_body => {
881        match declare_body {
882            DeclareBody::Statement(statement) => {
883                walker.walk_statement(statement, context);
884            }
885            DeclareBody::ColonDelimited(declare_colon_delimited_body) => {
886                walker.walk_declare_colon_delimited_body(declare_colon_delimited_body, context);
887            }
888        }
889    }
890
891    DeclareColonDelimitedBody as declare_colon_delimited_body => {
892        for statement in declare_colon_delimited_body.statements.iter() {
893            walker.walk_statement(statement, context);
894        }
895
896        walker.walk_terminator(&declare_colon_delimited_body.terminator, context);
897    }
898
899    Goto as goto => {
900        walker.walk_keyword(&goto.goto, context);
901        walker.walk_local_identifier(&goto.label, context);
902        walker.walk_terminator(&goto.terminator, context);
903    }
904
905    Label as label => {
906        walker.walk_local_identifier(&label.name, context);
907    }
908
909    Try as r#try => {
910        walker.walk_keyword(&r#try.r#try, context);
911        walker.walk_block(&r#try.block, context);
912        for catch in r#try.catch_clauses.iter() {
913            walker.walk_try_catch_clause(catch, context);
914        }
915
916        if let Some(finally) = &r#try.finally_clause {
917            walker.walk_try_finally_clause(finally, context);
918        }
919    }
920
921    TryCatchClause as try_catch_clause => {
922        walker.walk_keyword(&try_catch_clause.catch, context);
923        walker.walk_hint(&try_catch_clause.hint, context);
924        if let Some(variable) = &try_catch_clause.variable {
925            walker.walk_direct_variable(variable, context);
926        }
927
928        walker.walk_block(&try_catch_clause.block, context);
929    }
930
931    TryFinallyClause as try_finally_clause => {
932        walker.walk_keyword(&try_finally_clause.finally, context);
933        walker.walk_block(&try_finally_clause.block, context);
934    }
935
936    Foreach as foreach => {
937        walker.walk_keyword(&foreach.foreach, context);
938        walker.walk_expression(&foreach.expression, context);
939        walker.walk_keyword(&foreach.r#as, context);
940        walker.walk_foreach_target(&foreach.target, context);
941        walker.walk_foreach_body(&foreach.body, context);
942    }
943
944    ForeachTarget as foreach_target => {
945        match foreach_target {
946            ForeachTarget::Value(foreach_value_target) => {
947                walker.walk_foreach_value_target(foreach_value_target, context);
948            }
949            ForeachTarget::KeyValue(foreach_key_value_target) => {
950                walker.walk_foreach_key_value_target(foreach_key_value_target, context);
951            }
952        }
953    }
954
955    ForeachValueTarget as foreach_value_target => {
956        walker.walk_expression(&foreach_value_target.value, context);
957    }
958
959    ForeachKeyValueTarget as foreach_key_value_target => {
960        walker.walk_expression(&foreach_key_value_target.key, context);
961        walker.walk_expression(&foreach_key_value_target.value, context);
962    }
963
964    ForeachBody as foreach_body => {
965        match foreach_body {
966            ForeachBody::Statement(statement) => {
967                walker.walk_statement(statement, context);
968            }
969            ForeachBody::ColonDelimited(foreach_colon_delimited_body) => {
970                walker.walk_foreach_colon_delimited_body(foreach_colon_delimited_body, context);
971            }
972        }
973    }
974
975    ForeachColonDelimitedBody as foreach_colon_delimited_body => {
976        for statement in foreach_colon_delimited_body.statements.iter() {
977            walker.walk_statement(statement, context);
978        }
979
980        walker.walk_keyword(&foreach_colon_delimited_body.end_foreach, context);
981        walker.walk_terminator(&foreach_colon_delimited_body.terminator, context);
982    }
983
984    For as r#for => {
985        walker.walk_keyword(&r#for.r#for, context);
986
987        for initialization in r#for.initializations.iter() {
988            walker.walk_expression(initialization, context);
989        }
990
991        for condition in r#for.conditions.iter() {
992            walker.walk_expression(condition, context);
993        }
994
995        for increment in r#for.increments.iter() {
996            walker.walk_expression(increment, context);
997        }
998
999        walker.walk_for_body(&r#for.body, context);
1000    }
1001
1002    ForBody as for_body => {
1003        match for_body {
1004            ForBody::Statement(statement) => {
1005                walker.walk_statement(statement, context);
1006            }
1007            ForBody::ColonDelimited(for_colon_delimited_body) => {
1008                walker.walk_for_colon_delimited_body(for_colon_delimited_body, context);
1009            }
1010        }
1011    }
1012
1013    ForColonDelimitedBody as for_colon_delimited_body => {
1014        for statement in for_colon_delimited_body.statements.iter() {
1015            walker.walk_statement(statement, context);
1016        }
1017
1018        walker.walk_keyword(&for_colon_delimited_body.end_for, context);
1019        walker.walk_terminator(&for_colon_delimited_body.terminator, context);
1020    }
1021
1022    While as r#while => {
1023        walker.walk_keyword(&r#while.r#while, context);
1024        walker.walk_expression(&r#while.condition, context);
1025        walker.walk_while_body(&r#while.body, context);
1026    }
1027
1028    WhileBody as while_body => {
1029        match while_body {
1030            WhileBody::Statement(statement) => {
1031                walker.walk_statement(statement, context);
1032            }
1033            WhileBody::ColonDelimited(while_colon_delimited_body) => {
1034                walker.walk_while_colon_delimited_body(while_colon_delimited_body, context);
1035            }
1036        }
1037    }
1038
1039    WhileColonDelimitedBody as while_colon_delimited_body => {
1040        for statement in while_colon_delimited_body.statements.iter() {
1041            walker.walk_statement(statement, context);
1042        }
1043
1044        walker.walk_keyword(&while_colon_delimited_body.end_while, context);
1045        walker.walk_terminator(&while_colon_delimited_body.terminator, context);
1046    }
1047
1048    DoWhile as do_while => {
1049        walker.walk_keyword(&do_while.r#do, context);
1050        walker.walk_statement(&do_while.statement, context);
1051        walker.walk_keyword(&do_while.r#while, context);
1052        walker.walk_expression(&do_while.condition, context);
1053        walker.walk_terminator(&do_while.terminator, context);
1054    }
1055
1056    Continue as r#continue => {
1057        walker.walk_keyword(&r#continue.r#continue, context);
1058        if let Some(level) = &r#continue.level {
1059            walker.walk_expression(level, context);
1060        }
1061
1062        walker.walk_terminator(&r#continue.terminator, context);
1063    }
1064
1065    Break as r#break => {
1066        walker.walk_keyword(&r#break.r#break, context);
1067        if let Some(level) = &r#break.level {
1068            walker.walk_expression(level, context);
1069        }
1070
1071        walker.walk_terminator(&r#break.terminator, context);
1072    }
1073
1074    Switch as switch => {
1075        walker.walk_keyword(&switch.r#switch, context);
1076        walker.walk_expression(&switch.expression, context);
1077        walker.walk_switch_body(&switch.body, context);
1078    }
1079
1080    SwitchBody as switch_body => {
1081        match switch_body {
1082            SwitchBody::BraceDelimited(switch_brace_delimited_body) => {
1083                walker.walk_switch_brace_delimited_body(switch_brace_delimited_body, context);
1084            }
1085            SwitchBody::ColonDelimited(switch_colon_delimited_body) => {
1086                walker.walk_switch_colon_delimited_body(switch_colon_delimited_body, context);
1087            }
1088        }
1089    }
1090
1091    SwitchBraceDelimitedBody as switch_brace_delimited_body => {
1092        if let Some(terminator) = &switch_brace_delimited_body.optional_terminator {
1093            walker.walk_terminator(terminator, context);
1094        }
1095
1096        for case in switch_brace_delimited_body.cases.iter() {
1097            walker.walk_switch_case(case, context);
1098        }
1099    }
1100
1101    SwitchColonDelimitedBody as switch_colon_delimited_body => {
1102        if let Some(terminator) = &switch_colon_delimited_body.optional_terminator {
1103            walker.walk_terminator(terminator, context);
1104        }
1105
1106        for case in switch_colon_delimited_body.cases.iter() {
1107            walker.walk_switch_case(case, context);
1108        }
1109
1110        walker.walk_keyword(&switch_colon_delimited_body.end_switch, context);
1111        walker.walk_terminator(&switch_colon_delimited_body.terminator, context);
1112    }
1113
1114    SwitchCase as switch_case => {
1115        match switch_case {
1116            SwitchCase::Expression(switch_expression_case) => {
1117                walker.walk_switch_expression_case(switch_expression_case, context);
1118            }
1119            SwitchCase::Default(switch_default_case) => {
1120                walker.walk_switch_default_case(switch_default_case, context);
1121            }
1122        }
1123    }
1124
1125    SwitchExpressionCase as switch_expression_case => {
1126        walker.walk_keyword(&switch_expression_case.r#case, context);
1127        walker.walk_expression(&switch_expression_case.expression, context);
1128        walker.walk_switch_case_separator(&switch_expression_case.separator, context);
1129        for statement in switch_expression_case.statements.iter() {
1130            walker.walk_statement(statement, context);
1131        }
1132    }
1133
1134    SwitchDefaultCase as switch_default_case => {
1135        walker.walk_keyword(&switch_default_case.r#default, context);
1136        walker.walk_switch_case_separator(&switch_default_case.separator, context);
1137        for statement in switch_default_case.statements.iter() {
1138            walker.walk_statement(statement, context);
1139        }
1140    }
1141
1142    SwitchCaseSeparator as switch_case_separator => {
1143        // Do nothing by default
1144    }
1145
1146    If as r#if => {
1147        walker.walk_keyword(&r#if.r#if, context);
1148        walker.walk_expression(&r#if.condition, context);
1149        walker.walk_if_body(&r#if.body, context);
1150    }
1151
1152    IfBody as if_body => {
1153        match if_body {
1154            IfBody::Statement(statement) => {
1155                walker.walk_if_statement_body(statement, context);
1156            }
1157            IfBody::ColonDelimited(if_colon_delimited_body) => {
1158                walker.walk_if_colon_delimited_body(if_colon_delimited_body, context);
1159            }
1160        }
1161    }
1162
1163    IfStatementBody as if_statement_body => {
1164        walker.walk_statement(&if_statement_body.statement, context);
1165
1166        for else_if_clause in if_statement_body.else_if_clauses.iter() {
1167            walker.walk_if_statement_body_else_if_clause(else_if_clause, context);
1168        }
1169
1170        if let Some(else_clause) = &if_statement_body.else_clause {
1171            walker.walk_if_statement_body_else_clause(else_clause, context);
1172        }
1173    }
1174
1175    IfStatementBodyElseIfClause as if_statement_body_else_if_clause => {
1176        walker.walk_keyword(&if_statement_body_else_if_clause.r#elseif, context);
1177        walker.walk_expression(&if_statement_body_else_if_clause.condition, context);
1178        walker.walk_statement(&if_statement_body_else_if_clause.statement, context);
1179    }
1180
1181    IfStatementBodyElseClause as if_statement_body_else_clause => {
1182        walker.walk_keyword(&if_statement_body_else_clause.r#else, context);
1183        walker.walk_statement(&if_statement_body_else_clause.statement, context);
1184    }
1185
1186    IfColonDelimitedBody as if_colon_delimited_body => {
1187        for statement in if_colon_delimited_body.statements.iter() {
1188            walker.walk_statement(statement, context);
1189        }
1190
1191        for else_if_clause in if_colon_delimited_body.else_if_clauses.iter() {
1192            walker.walk_if_colon_delimited_body_else_if_clause(else_if_clause, context);
1193        }
1194
1195        if let Some(else_clause) = &if_colon_delimited_body.else_clause {
1196            walker.walk_if_colon_delimited_body_else_clause(else_clause, context);
1197        }
1198
1199        walker.walk_keyword(&if_colon_delimited_body.endif, context);
1200        walker.walk_terminator(&if_colon_delimited_body.terminator, context);
1201    }
1202
1203    IfColonDelimitedBodyElseIfClause as if_colon_delimited_body_else_if_clause => {
1204        walker.walk_keyword(&if_colon_delimited_body_else_if_clause.r#elseif, context);
1205        walker.walk_expression(&if_colon_delimited_body_else_if_clause.condition, context);
1206        for statement in if_colon_delimited_body_else_if_clause.statements.iter() {
1207            walker.walk_statement(statement, context);
1208        }
1209    }
1210
1211    IfColonDelimitedBodyElseClause as if_colon_delimited_body_else_clause => {
1212        walker.walk_keyword(&if_colon_delimited_body_else_clause.r#else, context);
1213        for statement in if_colon_delimited_body_else_clause.statements.iter() {
1214            walker.walk_statement(statement, context);
1215        }
1216    }
1217
1218    Return as r#return => {
1219        walker.walk_keyword(&r#return.r#return, context);
1220        if let Some(expression) = &r#return.value {
1221            walker.walk_expression(expression, context);
1222        }
1223
1224        walker.walk_terminator(&r#return.terminator, context);
1225    }
1226
1227    ExpressionStatement as statement_expression => {
1228        walker.walk_expression(&statement_expression.expression, context);
1229        walker.walk_terminator(&statement_expression.terminator, context);
1230    }
1231
1232    Echo as echo => {
1233        walker.walk_keyword(&echo.echo, context);
1234        for expression in echo.values.iter() {
1235            walker.walk_expression(expression, context);
1236        }
1237
1238        walker.walk_terminator(&echo.terminator, context);
1239    }
1240
1241    Global as global => {
1242        walker.walk_keyword(&global.global, context);
1243        for variable in global.variables.iter() {
1244            walker.walk_variable(variable, context);
1245        }
1246
1247        walker.walk_terminator(&global.terminator, context);
1248    }
1249
1250    Static as r#static => {
1251        walker.walk_keyword(&r#static.r#static, context);
1252        for item in r#static.items.iter() {
1253            walker.walk_static_item(item, context);
1254        }
1255
1256        walker.walk_terminator(&r#static.terminator, context);
1257    }
1258
1259    StaticItem as static_item => {
1260        match static_item {
1261            StaticItem::Abstract(static_abstract_item) => {
1262                walker.walk_static_abstract_item(static_abstract_item, context);
1263            }
1264            StaticItem::Concrete(static_concrete_item) => {
1265                walker.walk_static_concrete_item(static_concrete_item, context);
1266            }
1267        }
1268    }
1269
1270    StaticAbstractItem as static_abstract_item => {
1271        walker.walk_direct_variable(&static_abstract_item.variable, context);
1272    }
1273
1274    StaticConcreteItem as static_concrete_item => {
1275        walker.walk_direct_variable(&static_concrete_item.variable, context);
1276        walker.walk_expression(&static_concrete_item.value, context);
1277    }
1278
1279    HaltCompiler as halt_compiler => {
1280        walker.walk_keyword(&halt_compiler.halt_compiler, context);
1281    }
1282
1283    Unset as unset => {
1284        walker.walk_keyword(&unset.unset, context);
1285        for value in unset.values.iter() {
1286            walker.walk_expression(value, context);
1287        }
1288
1289        walker.walk_terminator(&unset.terminator, context);
1290    }
1291
1292    Expression as expression => {
1293        match &expression {
1294            Expression::Parenthesized(parenthesized) => walker.walk_parenthesized(parenthesized, context),
1295            Expression::Binary(expr) => walker.walk_binary(expr, context),
1296            Expression::UnaryPrefix(operation) => walker.walk_unary_prefix(operation, context),
1297            Expression::UnaryPostfix(operation) => walker.walk_unary_postfix(operation, context),
1298            Expression::Literal(literal) => walker.walk_literal_expression(literal, context),
1299            Expression::CompositeString(string) => walker.walk_composite_string(string, context),
1300            Expression::Assignment(assignment) => {
1301                walker.walk_assignment(assignment, context)
1302            }
1303            Expression::Conditional(conditional) => {
1304                walker.walk_conditional(conditional, context)
1305            }
1306            Expression::Array(array) => walker.walk_array(array, context),
1307            Expression::LegacyArray(legacy_array) => walker.walk_legacy_array(legacy_array, context),
1308            Expression::List(list) => walker.walk_list(list, context),
1309            Expression::ArrayAccess(array_access) => walker.walk_array_access(array_access, context),
1310            Expression::ArrayAppend(array_append) => walker.walk_array_append(array_append, context),
1311            Expression::AnonymousClass(anonymous_class) => {
1312                walker.walk_anonymous_class(anonymous_class, context)
1313            }
1314            Expression::Closure(closure) => walker.walk_closure(closure, context),
1315            Expression::ArrowFunction(arrow_function) => walker.walk_arrow_function(arrow_function, context),
1316            Expression::Variable(variable) => walker.walk_variable(variable, context),
1317            Expression::Identifier(identifier) => walker.walk_identifier(identifier, context),
1318            Expression::Match(r#match) => walker.walk_match(r#match, context),
1319            Expression::Yield(r#yield) => walker.walk_yield(r#yield, context),
1320            Expression::Construct(construct) => walker.walk_construct(construct, context),
1321            Expression::Throw(throw) => walker.walk_throw(throw, context),
1322            Expression::Clone(clone) => walker.walk_clone(clone, context),
1323            Expression::Call(call) => walker.walk_call(call, context),
1324            Expression::Access(access) => walker.walk_access(access, context),
1325            Expression::ConstantAccess(expr) => walker.walk_constant_access(expr, context),
1326            Expression::ClosureCreation(closure_creation) => {
1327                walker.walk_closure_creation(closure_creation, context)
1328            }
1329            Expression::Parent(keyword) => walker.walk_parent_keyword(keyword, context),
1330            Expression::Static(keyword) => walker.walk_static_keyword(keyword, context),
1331            Expression::Self_(keyword) => walker.walk_self_keyword(keyword, context),
1332            Expression::Instantiation(instantiation) => walker.walk_instantiation(instantiation, context),
1333            Expression::MagicConstant(magic_constant) => walker.walk_magic_constant(magic_constant, context),
1334        }
1335    }
1336
1337    Binary as binary => {
1338        walker.walk_expression(&binary.lhs, context);
1339        walker.walk_binary_operator(&binary.operator, context);
1340        walker.walk_expression(&binary.rhs, context);
1341    }
1342
1343    BinaryOperator as binary_operator => {
1344        match binary_operator {
1345            BinaryOperator::Instanceof(keyword)
1346            | BinaryOperator::LowAnd(keyword)
1347            | BinaryOperator::LowOr(keyword)
1348            | BinaryOperator::LowXor(keyword) => {
1349                walker.walk_keyword(keyword, context);
1350            }
1351            _ => {}
1352        }
1353    }
1354
1355    UnaryPrefix as unary_prefix => {
1356        walker.walk_unary_prefix_operator(&unary_prefix.operator, context);
1357        walker.walk_expression(&unary_prefix.operand, context);
1358    }
1359
1360    UnaryPrefixOperator as unary_prefix_operator => {
1361        // Do nothing
1362    }
1363
1364    UnaryPostfix as unary_postfix => {
1365        walker.walk_expression(&unary_postfix.operand, context);
1366        walker.walk_unary_postfix_operator(&unary_postfix.operator, context);
1367    }
1368
1369    UnaryPostfixOperator as unary_postfix_operator => {
1370        // Do nothing
1371    }
1372
1373    Parenthesized as parenthesized => {
1374        walker.walk_expression(&parenthesized.expression, context)
1375    }
1376
1377    Literal as literal_expression => {
1378        match literal_expression {
1379            Literal::String(string) => walker.walk_literal_string(string, context),
1380            Literal::Integer(integer) => walker.walk_literal_integer(integer, context),
1381            Literal::Float(float) => walker.walk_literal_float(float, context),
1382            Literal::True(keyword) => walker.walk_true_keyword(keyword, context),
1383            Literal::False(keyword) => walker.walk_false_keyword(keyword, context),
1384            Literal::Null(keyword) => walker.walk_null_keyword(keyword, context),
1385        }
1386    }
1387
1388    LiteralString as literal_string => {
1389        // Do nothing by default
1390    }
1391
1392    LiteralInteger as literal_integer => {
1393        // Do nothing by default
1394    }
1395
1396    LiteralFloat as literal_float => {
1397        // Do nothing by default
1398    }
1399
1400    Keyword as true_keyword => {
1401        // Do nothing by default
1402    }
1403
1404    Keyword as false_keyword => {
1405        // Do nothing by default
1406    }
1407
1408    Keyword as null_keyword => {
1409        // Do nothing by default
1410    }
1411
1412    CompositeString as composite_string => {
1413        match composite_string {
1414            CompositeString::ShellExecute(str) => walker.walk_shell_execute_string(str, context),
1415            CompositeString::Interpolated(str) => walker.walk_interpolated_string(str, context),
1416            CompositeString::Document(str) => walker.walk_document_string(str, context),
1417        }
1418    }
1419
1420    ShellExecuteString as shell_execute_string => {
1421        for part in shell_execute_string.parts.iter() {
1422            walker.walk_string_part(part, context);
1423        }
1424    }
1425
1426    InterpolatedString as interpolated_string => {
1427        for part in interpolated_string.parts.iter() {
1428            walker.walk_string_part(part, context);
1429        }
1430    }
1431
1432    DocumentString as document_string => {
1433        for part in document_string.parts.iter() {
1434            walker.walk_string_part(part, context);
1435        }
1436    }
1437
1438    StringPart as string_part => {
1439        match string_part {
1440            StringPart::Literal(literal) => walker.walk_literal_string_part(literal, context),
1441            StringPart::Expression(expression) => walker.walk_expression(expression, context),
1442            StringPart::BracedExpression(braced_expression_string_part) => {
1443                walker.walk_braced_expression_string_part(braced_expression_string_part, context)
1444            }
1445        };
1446    }
1447
1448    LiteralStringPart as literal_string_part => {
1449        // Do nothing
1450    }
1451
1452    BracedExpressionStringPart as braced_expression_string_part => {
1453        walker.walk_expression(&braced_expression_string_part.expression, context);
1454    }
1455
1456    Assignment as assignment => {
1457        walker.walk_expression(&assignment.lhs, context);
1458        walker.walk_assignment_operator(&assignment.operator, context);
1459        walker.walk_expression(&assignment.rhs, context);
1460    }
1461
1462    AssignmentOperator as assignment_operator => {
1463        // Do nothing
1464    }
1465
1466    Conditional as conditional => {
1467        walker.walk_expression(&conditional.condition, context);
1468        if let Some(then) = &conditional.then {
1469            walker.walk_expression(then, context);
1470        }
1471
1472        walker.walk_expression(&conditional.r#else, context);
1473    }
1474
1475    Array as array => {
1476        for element in array.elements.iter() {
1477            walker.walk_array_element(element, context);
1478        }
1479    }
1480
1481    ArrayElement as array_element => {
1482        match array_element {
1483            ArrayElement::KeyValue(key_value_array_element) => {
1484                walker.walk_key_value_array_element(key_value_array_element, context);
1485            }
1486            ArrayElement::Value(value_array_element) => {
1487                walker.walk_value_array_element(value_array_element, context);
1488            }
1489            ArrayElement::Variadic(variadic_array_element) => {
1490                walker.walk_variadic_array_element(variadic_array_element, context);
1491            }
1492            ArrayElement::Missing(missing_array_element) => {
1493                walker.walk_missing_array_element(missing_array_element, context);
1494            }
1495        }
1496    }
1497
1498    KeyValueArrayElement as key_value_array_element => {
1499        walker.walk_expression(&key_value_array_element.key, context);
1500        walker.walk_expression(&key_value_array_element.value, context);
1501    }
1502
1503    ValueArrayElement as value_array_element => {
1504        walker.walk_expression(&value_array_element.value, context);
1505    }
1506
1507    VariadicArrayElement as variadic_array_element => {
1508        walker.walk_expression(&variadic_array_element.value, context);
1509    }
1510
1511    MissingArrayElement as missing_array_element => {
1512        // Do nothing
1513    }
1514
1515    LegacyArray as legacy_array => {
1516        walker.walk_keyword(&legacy_array.array, context);
1517        for element in legacy_array.elements.iter() {
1518            walker.walk_array_element(element, context);
1519        }
1520    }
1521
1522    List as list => {
1523        walker.walk_keyword(&list.list, context);
1524
1525        for element in list.elements.iter() {
1526            walker.walk_array_element(element, context);
1527        }
1528    }
1529
1530    ArrayAccess as array_access => {
1531        walker.walk_expression(&array_access.array, context);
1532        walker.walk_expression(&array_access.index, context);
1533    }
1534
1535    ArrayAppend as array_append => {
1536        walker.walk_expression(&array_append.array, context);
1537    }
1538
1539    AnonymousClass as anonymous_class => {
1540        for attribute_list in anonymous_class.attribute_lists.iter() {
1541            walker.walk_attribute_list(attribute_list, context);
1542        }
1543
1544        for modifier in anonymous_class.modifiers.iter() {
1545            walker.walk_modifier(modifier, context);
1546        }
1547
1548        walker.walk_keyword(&anonymous_class.new, context);
1549        walker.walk_keyword(&anonymous_class.class, context);
1550        if let Some(arguments) = &anonymous_class.arguments {
1551            walker.walk_argument_list(arguments, context);
1552        }
1553
1554        if let Some(extends) = &anonymous_class.extends {
1555            walker.walk_extends(extends, context);
1556        }
1557
1558        if let Some(implements) = &anonymous_class.implements {
1559            walker.walk_implements(implements, context);
1560        }
1561
1562        for class_member in anonymous_class.members.iter() {
1563            walker.walk_class_like_member(class_member, context);
1564        }
1565    }
1566
1567    Closure as closure => {
1568        for attribute_list in closure.attribute_lists.iter() {
1569                walker.walk_attribute_list(attribute_list, context);
1570            }
1571
1572        if let Some(keyword) = &closure.r#static {
1573            walker.walk_keyword(keyword, context);
1574        }
1575
1576        walker.walk_keyword(&closure.function, context);
1577        walker.walk_function_like_parameter_list(&closure.parameter_list, context);
1578        if let Some(use_clause) = &closure.use_clause {
1579            walker.walk_closure_use_clause(use_clause, context);
1580        }
1581
1582        if let Some(return_type_hint) = &closure.return_type_hint {
1583            walker.walk_function_like_return_type_hint(return_type_hint, context);
1584        }
1585
1586        walker.walk_block(&closure.body, context);
1587    }
1588
1589    ClosureUseClause as closure_use_clause => {
1590        for variable in closure_use_clause.variables.iter() {
1591            walker.walk_closure_use_clause_variable(variable, context);
1592        }
1593    }
1594
1595    ClosureUseClauseVariable as closure_use_clause_variable => {
1596        walker.walk_direct_variable(&closure_use_clause_variable.variable, context);
1597    }
1598
1599    ArrowFunction as arrow_function => {
1600        for attribute_list in arrow_function.attribute_lists.iter() {
1601            walker.walk_attribute_list(attribute_list, context);
1602        }
1603
1604        if let Some(keyword) = &arrow_function.r#static {
1605            walker.walk_keyword(keyword, context);
1606        }
1607
1608        walker.walk_keyword(&arrow_function.r#fn, context);
1609        walker.walk_function_like_parameter_list(&arrow_function.parameter_list, context);
1610
1611        if let Some(return_type_hint) = &arrow_function.return_type_hint {
1612            walker.walk_function_like_return_type_hint(return_type_hint, context);
1613        }
1614
1615        walker.walk_expression(&arrow_function.expression, context);
1616    }
1617
1618    Variable as variable => {
1619        match variable {
1620            Variable::Direct(direct_variable) => {
1621                walker.walk_direct_variable(direct_variable, context);
1622            }
1623            Variable::Indirect(indirect_variable) => {
1624                walker.walk_indirect_variable(indirect_variable, context);
1625            }
1626            Variable::Nested(nested_variable) => {
1627                walker.walk_nested_variable(nested_variable, context);
1628            }
1629        }
1630    }
1631
1632    DirectVariable as direct_variable => {
1633        // Do nothing by default
1634    }
1635
1636    IndirectVariable as indirect_variable => {
1637        walker.walk_expression(&indirect_variable.expression, context);
1638    }
1639
1640    NestedVariable as nested_variable => {
1641        walker.walk_variable(nested_variable.variable.as_ref(), context);
1642    }
1643
1644    Identifier as identifier => {
1645        match identifier {
1646            Identifier::Local(local_identifier) => walker.walk_local_identifier(local_identifier, context),
1647            Identifier::Qualified(qualified_identifier) => walker.walk_qualified_identifier(qualified_identifier, context),
1648            Identifier::FullyQualified(fully_qualified_identifier) => walker.walk_fully_qualified_identifier(fully_qualified_identifier, context),
1649        };
1650    }
1651
1652    LocalIdentifier as local_identifier => {
1653        // Do nothing by default
1654    }
1655
1656    QualifiedIdentifier as qualified_identifier => {
1657        // Do nothing by default
1658    }
1659
1660    FullyQualifiedIdentifier as fully_qualified_identifier => {
1661        // Do nothing by default
1662    }
1663
1664    Match as r#match => {
1665        walker.walk_keyword(&r#match.r#match, context);
1666        walker.walk_expression(&r#match.expression, context);
1667        for arm in r#match.arms.iter() {
1668            walker.walk_match_arm(arm, context);
1669        }
1670    }
1671
1672    MatchArm as match_arm => {
1673        match match_arm {
1674            MatchArm::Expression(expression_match_arm) => {
1675                walker.walk_match_expression_arm(expression_match_arm, context);
1676            }
1677            MatchArm::Default(default_match_arm) => {
1678                walker.walk_match_default_arm(default_match_arm, context);
1679            }
1680        }
1681    }
1682
1683    MatchExpressionArm as match_expression_arm => {
1684        for condition in match_expression_arm.conditions.iter() {
1685            walker.walk_expression(condition, context);
1686        }
1687
1688        walker.walk_expression(&match_expression_arm.expression, context);
1689    }
1690
1691    MatchDefaultArm as match_default_arm => {
1692        walker.walk_keyword(&match_default_arm.r#default, context);
1693        walker.walk_expression(&match_default_arm.expression, context);
1694    }
1695
1696    Yield as r#yield => {
1697        match r#yield {
1698            Yield::Value(yield_value) => {
1699                walker.walk_yield_value(yield_value, context);
1700            }
1701            Yield::Pair(yield_pair) => {
1702                walker.walk_yield_pair(yield_pair, context);
1703            }
1704            Yield::From(yield_from) => {
1705                walker.walk_yield_from(yield_from, context);
1706            }
1707        }
1708    }
1709
1710    YieldValue as yield_value => {
1711        walker.walk_keyword(&yield_value.r#yield, context);
1712
1713        if let Some(value) = &yield_value.value {
1714            walker.walk_expression(value, context);
1715        }
1716    }
1717
1718    YieldPair as yield_pair => {
1719        walker.walk_keyword(&yield_pair.r#yield, context);
1720        walker.walk_expression(&yield_pair.key, context);
1721        walker.walk_expression(&yield_pair.value, context);
1722    }
1723
1724    YieldFrom as yield_from => {
1725        walker.walk_keyword(&yield_from.r#yield, context);
1726        walker.walk_keyword(&yield_from.from, context);
1727        walker.walk_expression(&yield_from.iterator, context);
1728    }
1729
1730    Construct as construct => {
1731        match construct {
1732            Construct::Isset(isset_construct) => {
1733                walker.walk_isset_construct(isset_construct, context);
1734            }
1735            Construct::Empty(empty_construct) => {
1736                walker.walk_empty_construct(empty_construct, context);
1737            }
1738            Construct::Eval(eval_construct) => {
1739                walker.walk_eval_construct(eval_construct, context);
1740            }
1741            Construct::Include(include_construct) => {
1742                walker.walk_include_construct(include_construct, context);
1743            }
1744            Construct::IncludeOnce(include_once_construct) => {
1745                walker.walk_include_once_construct(include_once_construct, context);
1746            }
1747            Construct::Require(require_construct) => {
1748                walker.walk_require_construct(require_construct, context);
1749            }
1750            Construct::RequireOnce(require_once_construct) => {
1751                walker.walk_require_once_construct(require_once_construct, context);
1752            }
1753            Construct::Print(print_construct) => {
1754                walker.walk_print_construct(print_construct, context);
1755            }
1756            Construct::Exit(exit_construct) => {
1757                walker.walk_exit_construct(exit_construct, context);
1758            }
1759            Construct::Die(die_construct) => {
1760                walker.walk_die_construct(die_construct, context);
1761            }
1762        }
1763    }
1764
1765    IssetConstruct as isset_construct => {
1766        walker.walk_keyword(&isset_construct.isset, context);
1767        for value in isset_construct.values.iter() {
1768            walker.walk_expression(value, context);
1769        }
1770    }
1771
1772    EmptyConstruct as empty_construct => {
1773        walker.walk_keyword(&empty_construct.empty, context);
1774        walker.walk_expression(&empty_construct.value, context);
1775    }
1776
1777    EvalConstruct as eval_construct => {
1778        walker.walk_keyword(&eval_construct.eval, context);
1779        walker.walk_expression(&eval_construct.value, context);
1780    }
1781
1782    IncludeConstruct as include_construct => {
1783        walker.walk_keyword(&include_construct.include, context);
1784        walker.walk_expression(&include_construct.value, context);
1785    }
1786
1787    IncludeOnceConstruct as include_once_construct => {
1788        walker.walk_keyword(&include_once_construct.include_once, context);
1789        walker.walk_expression(&include_once_construct.value, context);
1790    }
1791
1792    RequireConstruct as require_construct => {
1793        walker.walk_keyword(&require_construct.require, context);
1794        walker.walk_expression(&require_construct.value, context);
1795    }
1796
1797    RequireOnceConstruct as require_once_construct => {
1798        walker.walk_keyword(&require_once_construct.require_once, context);
1799        walker.walk_expression(&require_once_construct.value, context);
1800    }
1801
1802    PrintConstruct as print_construct => {
1803        walker.walk_keyword(&print_construct.print, context);
1804        walker.walk_expression(&print_construct.value, context);
1805    }
1806
1807    ExitConstruct as exit_construct => {
1808        walker.walk_keyword(&exit_construct.exit, context);
1809        if let Some(arguments) = &exit_construct.arguments {
1810            walker.walk_argument_list(arguments, context);
1811        }
1812    }
1813
1814    DieConstruct as die_construct => {
1815        walker.walk_keyword(&die_construct.die, context);
1816        if let Some(arguments) = &die_construct.arguments {
1817            walker.walk_argument_list(arguments, context);
1818        }
1819    }
1820
1821    Throw as r#throw => {
1822        walker.walk_keyword(&r#throw.r#throw, context);
1823        walker.walk_expression(&r#throw.exception, context);
1824    }
1825
1826    Clone as clone => {
1827        walker.walk_keyword(&clone.clone, context);
1828        walker.walk_expression(&clone.object, context);
1829    }
1830
1831    Call as call => {
1832        match call {
1833            Call::Function(function_call) => {
1834                walker.walk_function_call(function_call, context);
1835            }
1836            Call::Method(method_call) => {
1837                walker.walk_method_call(method_call, context);
1838            }
1839            Call::NullSafeMethod(null_safe_method_call) => {
1840                walker.walk_null_safe_method_call(null_safe_method_call, context);
1841            }
1842            Call::StaticMethod(static_method_call) => {
1843                walker.walk_static_method_call(static_method_call, context);
1844            }
1845        }
1846    }
1847
1848    FunctionCall as function_call => {
1849        walker.walk_expression(&function_call.function, context);
1850        walker.walk_argument_list(&function_call.argument_list, context);
1851    }
1852
1853    MethodCall as method_call => {
1854        walker.walk_expression(&method_call.object, context);
1855        walker.walk_class_like_member_selector(&method_call.method, context);
1856        walker.walk_argument_list(&method_call.argument_list, context);
1857    }
1858
1859    NullSafeMethodCall as null_safe_method_call => {
1860        walker.walk_expression(&null_safe_method_call.object, context);
1861        walker.walk_class_like_member_selector(&null_safe_method_call.method, context);
1862        walker.walk_argument_list(&null_safe_method_call.argument_list, context);
1863    }
1864
1865    StaticMethodCall as static_method_call => {
1866        walker.walk_expression(&static_method_call.class, context);
1867        walker.walk_class_like_member_selector(&static_method_call.method, context);
1868        walker.walk_argument_list(&static_method_call.argument_list, context);
1869    }
1870
1871    ClassLikeMemberSelector as class_like_member_selector => {
1872        match class_like_member_selector {
1873            ClassLikeMemberSelector::Identifier(local_identifier) => {
1874                walker.walk_local_identifier(local_identifier, context);
1875            }
1876            ClassLikeMemberSelector::Variable(variable) => {
1877                walker.walk_variable(variable, context);
1878            }
1879            ClassLikeMemberSelector::Expression(class_like_member_expression_selector) => {
1880                walker.walk_class_like_member_expression_selector(
1881                    class_like_member_expression_selector,
1882
1883                    context,
1884                );
1885            }
1886        }
1887    }
1888
1889    ClassLikeMemberExpressionSelector as class_like_member_expression_selector => {
1890        walker.walk_expression(&class_like_member_expression_selector.expression, context);
1891    }
1892
1893    ConstantAccess as constant_access => {
1894        walker.walk_identifier(&constant_access.name, context);
1895    }
1896
1897    Access as access => {
1898        match access {
1899            Access::Property(property_access) => {
1900                walker.walk_property_access(property_access, context);
1901            }
1902            Access::NullSafeProperty(null_safe_property_access) => {
1903                walker.walk_null_safe_property_access(null_safe_property_access, context);
1904            }
1905            Access::StaticProperty(static_property_access) => {
1906                walker.walk_static_property_access(static_property_access, context);
1907            }
1908            Access::ClassConstant(class_constant_access) => {
1909                walker.walk_class_constant_access(class_constant_access, context);
1910            }
1911        }
1912    }
1913
1914    PropertyAccess as property_access => {
1915        walker.walk_expression(&property_access.object, context);
1916        walker.walk_class_like_member_selector(&property_access.property, context);
1917    }
1918
1919    NullSafePropertyAccess as null_safe_property_access => {
1920        walker.walk_expression(&null_safe_property_access.object, context);
1921        walker.walk_class_like_member_selector(&null_safe_property_access.property, context);
1922    }
1923
1924    StaticPropertyAccess as static_property_access => {
1925        walker.walk_expression(&static_property_access.class, context);
1926        walker.walk_variable(&static_property_access.property, context);
1927    }
1928
1929    ClassConstantAccess as class_constant_access => {
1930        walker.walk_expression(&class_constant_access.class, context);
1931        walker.walk_class_like_constant_selector(&class_constant_access.constant, context);
1932    }
1933
1934    ClassLikeConstantSelector as class_like_constant_selector => {
1935        match class_like_constant_selector {
1936            ClassLikeConstantSelector::Identifier(local_identifier) => {
1937                walker.walk_local_identifier(local_identifier, context);
1938            }
1939            ClassLikeConstantSelector::Expression(class_like_constant_expression_selector) => {
1940                walker.walk_class_like_member_expression_selector(
1941                    class_like_constant_expression_selector,
1942
1943                    context,
1944                );
1945            }
1946        }
1947    }
1948
1949    ClosureCreation as closure_creation => {
1950        match closure_creation {
1951            ClosureCreation::Function(function_closure_creation) => {
1952                walker.walk_function_closure_creation(function_closure_creation, context);
1953            }
1954            ClosureCreation::Method(method_closure_creation) => {
1955                walker.walk_method_closure_creation(method_closure_creation, context);
1956            }
1957            ClosureCreation::StaticMethod(static_method_closure_creation) => {
1958                walker.walk_static_method_closure_creation(static_method_closure_creation, context);
1959            }
1960        }
1961    }
1962
1963    FunctionClosureCreation as function_closure_creation => {
1964        walker.walk_expression(&function_closure_creation.function, context);
1965    }
1966
1967    MethodClosureCreation as method_closure_creation => {
1968        walker.walk_expression(&method_closure_creation.object, context);
1969        walker.walk_class_like_member_selector(&method_closure_creation.method, context);
1970    }
1971
1972    StaticMethodClosureCreation as static_method_closure_creation => {
1973        walker.walk_expression(&static_method_closure_creation.class, context);
1974        walker.walk_class_like_member_selector(&static_method_closure_creation.method, context);
1975    }
1976
1977    Keyword as parent_keyword => {
1978        // Do nothing by default
1979    }
1980
1981    Keyword as static_keyword => {
1982        // Do nothing by default
1983    }
1984
1985    Keyword as self_keyword => {
1986        // Do nothing by default
1987    }
1988
1989    Instantiation as instantiation => {
1990        walker.walk_keyword(&instantiation.new, context);
1991        walker.walk_expression(&instantiation.class, context);
1992        if let Some(arguments) = &instantiation.arguments {
1993            walker.walk_argument_list(arguments, context);
1994        }
1995    }
1996
1997    MagicConstant as magic_constant => {
1998        walker.walk_local_identifier(magic_constant.value(), context);
1999    }
2000
2001    Hint as hint => {
2002        match hint {
2003            Hint::Identifier(identifier) => {
2004                walker.walk_identifier(identifier, context);
2005            }
2006            Hint::Parenthesized(parenthesized_hint) => {
2007                walker.walk_parenthesized_hint(parenthesized_hint, context);
2008            }
2009            Hint::Nullable(nullable_hint) => {
2010                walker.walk_nullable_hint(nullable_hint, context);
2011            }
2012            Hint::Union(union_hint) => {
2013                walker.walk_union_hint(union_hint, context);
2014            }
2015            Hint::Intersection(intersection_hint) => {
2016                walker.walk_intersection_hint(intersection_hint, context);
2017            }
2018            Hint::Null(keyword) |
2019            Hint::True(keyword) |
2020            Hint::False(keyword) |
2021            Hint::Array(keyword) |
2022            Hint::Callable(keyword) |
2023            Hint::Static(keyword) |
2024            Hint::Self_(keyword) |
2025            Hint::Parent(keyword) => {
2026                walker.walk_keyword(keyword, context);
2027            }
2028            Hint::Void(local_identifier) |
2029            Hint::Never(local_identifier) |
2030            Hint::Float(local_identifier) |
2031            Hint::Bool(local_identifier) |
2032            Hint::Integer(local_identifier) |
2033            Hint::String(local_identifier) |
2034            Hint::Object(local_identifier) |
2035            Hint::Mixed(local_identifier) |
2036            Hint::Iterable(local_identifier) => {
2037                walker.walk_local_identifier(local_identifier, context);
2038            }
2039        }
2040    }
2041
2042    ParenthesizedHint as parenthesized_hint => {
2043        walker.walk_hint(&parenthesized_hint.hint, context);
2044    }
2045
2046    NullableHint as nullable_hint => {
2047        walker.walk_hint(&nullable_hint.hint, context);
2048    }
2049
2050    UnionHint as union_hint => {
2051        walker.walk_hint(&union_hint.left, context);
2052        walker.walk_hint(&union_hint.right, context);
2053    }
2054
2055    IntersectionHint as intersection_hint => {
2056        walker.walk_hint(&intersection_hint.left, context);
2057        walker.walk_hint(&intersection_hint.right, context);
2058    }
2059
2060    Keyword as keyword => {
2061        // Do nothing by default
2062    }
2063}