boa_ast/
visitor.rs

1//! ECMAScript Abstract Syntax Tree visitors.
2//!
3//! This module contains visitors which can be used to inspect or modify AST nodes. This allows for
4//! fine-grained manipulation of ASTs for analysis, rewriting, or instrumentation.
5
6use std::ops::ControlFlow;
7
8use crate::{
9    Module, ModuleItem, ModuleItemList, Script, StatementList, StatementListItem,
10    declaration::{
11        Binding, Declaration, ExportDeclaration, ExportSpecifier, ImportDeclaration, ImportKind,
12        ImportSpecifier, LexicalDeclaration, ModuleSpecifier, ReExportKind, VarDeclaration,
13        Variable, VariableList,
14    },
15    expression::{
16        Await, Call, Expression, Identifier, ImportCall, ImportMeta, New, NewTarget, Optional,
17        OptionalOperation, OptionalOperationKind, Parenthesized, RegExpLiteral, Spread, SuperCall,
18        TaggedTemplate, This, Yield,
19        access::{
20            PrivatePropertyAccess, PropertyAccess, PropertyAccessField, SimplePropertyAccess,
21            SuperPropertyAccess,
22        },
23        literal::{
24            ArrayLiteral, Literal, ObjectLiteral, ObjectMethodDefinition, PropertyDefinition,
25            TemplateElement, TemplateLiteral,
26        },
27        operator::{
28            Binary, BinaryInPrivate, Conditional, Unary, Update,
29            assign::{Assign, AssignTarget},
30        },
31    },
32    function::{
33        ArrowFunction, AsyncArrowFunction, AsyncFunctionDeclaration, AsyncFunctionExpression,
34        AsyncGeneratorDeclaration, AsyncGeneratorExpression, ClassDeclaration, ClassElement,
35        ClassExpression, FormalParameter, FormalParameterList, FunctionBody, FunctionDeclaration,
36        FunctionExpression, GeneratorDeclaration, GeneratorExpression, PrivateName,
37    },
38    pattern::{ArrayPattern, ArrayPatternElement, ObjectPattern, ObjectPatternElement, Pattern},
39    property::PropertyName,
40    statement::{
41        Block, Case, Catch, Finally, If, Labelled, LabelledItem, Return, Statement, Switch, Throw,
42        Try, With,
43        iteration::{
44            Break, Continue, DoWhileLoop, ForInLoop, ForLoop, ForLoopInitializer, ForOfLoop,
45            IterableLoopInitializer, WhileLoop,
46        },
47    },
48};
49use boa_interner::Sym;
50
51/// Creates the default visit function implementation for a particular type
52macro_rules! define_visit {
53    ($fn_name:ident, $type_name:ident) => {
54        #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor")]
55        fn $fn_name(&mut self, node: &'ast $type_name) -> ControlFlow<Self::BreakTy> {
56            node.visit_with(self)
57        }
58    };
59}
60
61/// Creates the default mutable visit function implementation for a particular type
62macro_rules! define_visit_mut {
63    ($fn_name:ident, $type_name:ident) => {
64        #[doc = concat!("Visits a `", stringify!($type_name), "` with this visitor, mutably")]
65        fn $fn_name(&mut self, node: &'ast mut $type_name) -> ControlFlow<Self::BreakTy> {
66            node.visit_with_mut(self)
67        }
68    };
69}
70
71/// Generates the `NodeRef` and `NodeMutRef` enums from a list of variants.
72macro_rules! node_ref {
73    (
74        $(
75            $Variant:ident
76        ),*
77        $(,)?
78    ) => {
79        /// A reference to a node visitable by a [`Visitor`].
80        #[derive(Debug, Clone, Copy)]
81        #[allow(missing_docs)]
82        pub enum NodeRef<'a> {
83            $(
84                $Variant(&'a $Variant)
85            ),*
86        }
87
88        $(
89            impl<'a> From<&'a $Variant> for NodeRef<'a> {
90                fn from(node: &'a $Variant) -> NodeRef<'a> {
91                    Self::$Variant(node)
92                }
93            }
94        )*
95
96        /// A mutable reference to a node visitable by a [`VisitorMut`].
97        #[derive(Debug)]
98        #[allow(missing_docs)]
99        pub enum NodeRefMut<'a> {
100            $(
101                $Variant(&'a mut $Variant)
102            ),*
103        }
104
105        $(
106            impl<'a> From<&'a mut $Variant> for NodeRefMut<'a> {
107                fn from(node: &'a mut $Variant) -> NodeRefMut<'a> {
108                    Self::$Variant(node)
109                }
110            }
111        )*
112    }
113}
114
115node_ref! {
116    Script,
117    Module,
118    FunctionBody,
119    StatementList,
120    StatementListItem,
121    Statement,
122    Declaration,
123    FunctionExpression,
124    FunctionDeclaration,
125    GeneratorExpression,
126    GeneratorDeclaration,
127    AsyncFunctionExpression,
128    AsyncFunctionDeclaration,
129    AsyncGeneratorExpression,
130    AsyncGeneratorDeclaration,
131    ClassExpression,
132    ClassDeclaration,
133    LexicalDeclaration,
134    Block,
135    VarDeclaration,
136    Expression,
137    If,
138    DoWhileLoop,
139    WhileLoop,
140    ForLoop,
141    ForInLoop,
142    ForOfLoop,
143    Switch,
144    Continue,
145    Break,
146    Return,
147    Labelled,
148    With,
149    Throw,
150    Try,
151    This,
152    NewTarget,
153    ImportMeta,
154    Identifier,
155    FormalParameterList,
156    ClassElement,
157    PrivateName,
158    VariableList,
159    Variable,
160    Binding,
161    Pattern,
162    Literal,
163    RegExpLiteral,
164    ArrayLiteral,
165    ObjectLiteral,
166    Spread,
167    ArrowFunction,
168    AsyncArrowFunction,
169    TemplateLiteral,
170    PropertyAccess,
171    New,
172    Call,
173    SuperCall,
174    ImportCall,
175    Optional,
176    TaggedTemplate,
177    Assign,
178    Unary,
179    Update,
180    Binary,
181    BinaryInPrivate,
182    Conditional,
183    Await,
184    Yield,
185    Parenthesized,
186    ForLoopInitializer,
187    IterableLoopInitializer,
188    Case,
189    Sym,
190    LabelledItem,
191    Catch,
192    Finally,
193    FormalParameter,
194    PropertyName,
195    ObjectMethodDefinition,
196    ObjectPattern,
197    ArrayPattern,
198    PropertyDefinition,
199    TemplateElement,
200    SimplePropertyAccess,
201    PrivatePropertyAccess,
202    SuperPropertyAccess,
203    OptionalOperation,
204    AssignTarget,
205    ObjectPatternElement,
206    ArrayPatternElement,
207    PropertyAccessField,
208    OptionalOperationKind,
209    ModuleItemList,
210    ModuleItem,
211    ModuleSpecifier,
212    ImportKind,
213    ImportDeclaration,
214    ImportSpecifier,
215    ReExportKind,
216    ExportDeclaration,
217    ExportSpecifier
218}
219
220/// Represents an AST visitor.
221///
222/// This implementation is based largely on [chalk](https://github.com/rust-lang/chalk/blob/23d39c90ceb9242fbd4c43e9368e813e7c2179f7/chalk-ir/src/visit.rs)'s
223/// visitor pattern.
224pub trait Visitor<'ast>: Sized {
225    /// Type which will be propagated from the visitor if completing early.
226    type BreakTy;
227
228    define_visit!(visit_script, Script);
229    define_visit!(visit_module, Module);
230    define_visit!(visit_function_body, FunctionBody);
231    define_visit!(visit_statement_list, StatementList);
232    define_visit!(visit_statement_list_item, StatementListItem);
233    define_visit!(visit_statement, Statement);
234    define_visit!(visit_declaration, Declaration);
235    define_visit!(visit_function_expression, FunctionExpression);
236    define_visit!(visit_function_declaration, FunctionDeclaration);
237    define_visit!(visit_generator_expression, GeneratorExpression);
238    define_visit!(visit_generator_declaration, GeneratorDeclaration);
239    define_visit!(visit_async_function_expression, AsyncFunctionExpression);
240    define_visit!(visit_async_function_declaration, AsyncFunctionDeclaration);
241    define_visit!(visit_async_generator_expression, AsyncGeneratorExpression);
242    define_visit!(visit_async_generator_declaration, AsyncGeneratorDeclaration);
243    define_visit!(visit_class_expression, ClassExpression);
244    define_visit!(visit_class_declaration, ClassDeclaration);
245    define_visit!(visit_lexical_declaration, LexicalDeclaration);
246    define_visit!(visit_block, Block);
247    define_visit!(visit_var_declaration, VarDeclaration);
248    define_visit!(visit_expression, Expression);
249    define_visit!(visit_if, If);
250    define_visit!(visit_do_while_loop, DoWhileLoop);
251    define_visit!(visit_while_loop, WhileLoop);
252    define_visit!(visit_for_loop, ForLoop);
253    define_visit!(visit_for_in_loop, ForInLoop);
254    define_visit!(visit_for_of_loop, ForOfLoop);
255    define_visit!(visit_switch, Switch);
256    define_visit!(visit_continue, Continue);
257    define_visit!(visit_break, Break);
258    define_visit!(visit_return, Return);
259    define_visit!(visit_labelled, Labelled);
260    define_visit!(visit_throw, Throw);
261    define_visit!(visit_try, Try);
262    define_visit!(visit_with, With);
263    define_visit!(visit_this, This);
264    define_visit!(visit_identifier, Identifier);
265    define_visit!(visit_formal_parameter_list, FormalParameterList);
266    define_visit!(visit_class_element, ClassElement);
267    define_visit!(visit_private_name, PrivateName);
268    define_visit!(visit_variable_list, VariableList);
269    define_visit!(visit_variable, Variable);
270    define_visit!(visit_binding, Binding);
271    define_visit!(visit_pattern, Pattern);
272    define_visit!(visit_literal, Literal);
273    define_visit!(visit_reg_exp_literal, RegExpLiteral);
274    define_visit!(visit_array_literal, ArrayLiteral);
275    define_visit!(visit_object_literal, ObjectLiteral);
276    define_visit!(visit_spread, Spread);
277    define_visit!(visit_arrow_function, ArrowFunction);
278    define_visit!(visit_async_arrow_function, AsyncArrowFunction);
279    define_visit!(visit_template_literal, TemplateLiteral);
280    define_visit!(visit_property_access, PropertyAccess);
281    define_visit!(visit_new, New);
282    define_visit!(visit_call, Call);
283    define_visit!(visit_super_call, SuperCall);
284    define_visit!(visit_import_call, ImportCall);
285    define_visit!(visit_optional, Optional);
286    define_visit!(visit_tagged_template, TaggedTemplate);
287    define_visit!(visit_assign, Assign);
288    define_visit!(visit_unary, Unary);
289    define_visit!(visit_update, Update);
290    define_visit!(visit_binary, Binary);
291    define_visit!(visit_binary_in_private, BinaryInPrivate);
292    define_visit!(visit_conditional, Conditional);
293    define_visit!(visit_await, Await);
294    define_visit!(visit_yield, Yield);
295    define_visit!(visit_parenthesized, Parenthesized);
296    define_visit!(visit_new_target, NewTarget);
297    define_visit!(visit_import_meta, ImportMeta);
298    define_visit!(visit_for_loop_initializer, ForLoopInitializer);
299    define_visit!(visit_iterable_loop_initializer, IterableLoopInitializer);
300    define_visit!(visit_case, Case);
301    define_visit!(visit_sym, Sym);
302    define_visit!(visit_labelled_item, LabelledItem);
303    define_visit!(visit_catch, Catch);
304    define_visit!(visit_finally, Finally);
305    define_visit!(visit_formal_parameter, FormalParameter);
306    define_visit!(visit_property_name, PropertyName);
307    define_visit!(visit_object_method_definition, ObjectMethodDefinition);
308    define_visit!(visit_object_pattern, ObjectPattern);
309    define_visit!(visit_array_pattern, ArrayPattern);
310    define_visit!(visit_property_definition, PropertyDefinition);
311    define_visit!(visit_template_element, TemplateElement);
312    define_visit!(visit_simple_property_access, SimplePropertyAccess);
313    define_visit!(visit_private_property_access, PrivatePropertyAccess);
314    define_visit!(visit_super_property_access, SuperPropertyAccess);
315    define_visit!(visit_optional_operation, OptionalOperation);
316    define_visit!(visit_assign_target, AssignTarget);
317    define_visit!(visit_object_pattern_element, ObjectPatternElement);
318    define_visit!(visit_array_pattern_element, ArrayPatternElement);
319    define_visit!(visit_property_access_field, PropertyAccessField);
320    define_visit!(visit_optional_operation_kind, OptionalOperationKind);
321    define_visit!(visit_module_item_list, ModuleItemList);
322    define_visit!(visit_module_item, ModuleItem);
323    define_visit!(visit_module_specifier, ModuleSpecifier);
324    define_visit!(visit_import_kind, ImportKind);
325    define_visit!(visit_import_declaration, ImportDeclaration);
326    define_visit!(visit_import_specifier, ImportSpecifier);
327    define_visit!(visit_re_export_kind, ReExportKind);
328    define_visit!(visit_export_declaration, ExportDeclaration);
329    define_visit!(visit_export_specifier, ExportSpecifier);
330
331    /// Generic entry point for a node that is visitable by a `Visitor`.
332    ///
333    /// This is usually used for generic functions that need to visit an unnamed AST node.
334    fn visit<N: Into<NodeRef<'ast>>>(&mut self, node: N) -> ControlFlow<Self::BreakTy> {
335        let node = node.into();
336        match node {
337            NodeRef::Script(n) => self.visit_script(n),
338            NodeRef::Module(n) => self.visit_module(n),
339            NodeRef::FunctionBody(n) => self.visit_function_body(n),
340            NodeRef::StatementList(n) => self.visit_statement_list(n),
341            NodeRef::StatementListItem(n) => self.visit_statement_list_item(n),
342            NodeRef::Statement(n) => self.visit_statement(n),
343            NodeRef::Declaration(n) => self.visit_declaration(n),
344            NodeRef::FunctionExpression(n) => self.visit_function_expression(n),
345            NodeRef::FunctionDeclaration(n) => self.visit_function_declaration(n),
346            NodeRef::GeneratorExpression(n) => self.visit_generator_expression(n),
347            NodeRef::GeneratorDeclaration(n) => self.visit_generator_declaration(n),
348            NodeRef::AsyncFunctionExpression(n) => self.visit_async_function_expression(n),
349            NodeRef::AsyncFunctionDeclaration(n) => self.visit_async_function_declaration(n),
350            NodeRef::AsyncGeneratorExpression(n) => self.visit_async_generator_expression(n),
351            NodeRef::AsyncGeneratorDeclaration(n) => self.visit_async_generator_declaration(n),
352            NodeRef::ClassExpression(n) => self.visit_class_expression(n),
353            NodeRef::ClassDeclaration(n) => self.visit_class_declaration(n),
354            NodeRef::LexicalDeclaration(n) => self.visit_lexical_declaration(n),
355            NodeRef::Block(n) => self.visit_block(n),
356            NodeRef::VarDeclaration(n) => self.visit_var_declaration(n),
357            NodeRef::Expression(n) => self.visit_expression(n),
358            NodeRef::If(n) => self.visit_if(n),
359            NodeRef::DoWhileLoop(n) => self.visit_do_while_loop(n),
360            NodeRef::WhileLoop(n) => self.visit_while_loop(n),
361            NodeRef::ForLoop(n) => self.visit_for_loop(n),
362            NodeRef::ForInLoop(n) => self.visit_for_in_loop(n),
363            NodeRef::ForOfLoop(n) => self.visit_for_of_loop(n),
364            NodeRef::Switch(n) => self.visit_switch(n),
365            NodeRef::Continue(n) => self.visit_continue(n),
366            NodeRef::Break(n) => self.visit_break(n),
367            NodeRef::Return(n) => self.visit_return(n),
368            NodeRef::Labelled(n) => self.visit_labelled(n),
369            NodeRef::With(n) => self.visit_with(n),
370            NodeRef::Throw(n) => self.visit_throw(n),
371            NodeRef::Try(n) => self.visit_try(n),
372            NodeRef::This(n) => self.visit_this(n),
373            NodeRef::NewTarget(n) => self.visit_new_target(n),
374            NodeRef::ImportMeta(n) => self.visit_import_meta(n),
375            NodeRef::Identifier(n) => self.visit_identifier(n),
376            NodeRef::FormalParameterList(n) => self.visit_formal_parameter_list(n),
377            NodeRef::ClassElement(n) => self.visit_class_element(n),
378            NodeRef::PrivateName(n) => self.visit_private_name(n),
379            NodeRef::VariableList(n) => self.visit_variable_list(n),
380            NodeRef::Variable(n) => self.visit_variable(n),
381            NodeRef::Binding(n) => self.visit_binding(n),
382            NodeRef::Pattern(n) => self.visit_pattern(n),
383            NodeRef::Literal(n) => self.visit_literal(n),
384            NodeRef::RegExpLiteral(n) => self.visit_reg_exp_literal(n),
385            NodeRef::ArrayLiteral(n) => self.visit_array_literal(n),
386            NodeRef::ObjectLiteral(n) => self.visit_object_literal(n),
387            NodeRef::Spread(n) => self.visit_spread(n),
388            NodeRef::ArrowFunction(n) => self.visit_arrow_function(n),
389            NodeRef::AsyncArrowFunction(n) => self.visit_async_arrow_function(n),
390            NodeRef::TemplateLiteral(n) => self.visit_template_literal(n),
391            NodeRef::PropertyAccess(n) => self.visit_property_access(n),
392            NodeRef::New(n) => self.visit_new(n),
393            NodeRef::Call(n) => self.visit_call(n),
394            NodeRef::SuperCall(n) => self.visit_super_call(n),
395            NodeRef::ImportCall(n) => self.visit_import_call(n),
396            NodeRef::Optional(n) => self.visit_optional(n),
397            NodeRef::TaggedTemplate(n) => self.visit_tagged_template(n),
398            NodeRef::Assign(n) => self.visit_assign(n),
399            NodeRef::Unary(n) => self.visit_unary(n),
400            NodeRef::Update(n) => self.visit_update(n),
401            NodeRef::Binary(n) => self.visit_binary(n),
402            NodeRef::BinaryInPrivate(n) => self.visit_binary_in_private(n),
403            NodeRef::Conditional(n) => self.visit_conditional(n),
404            NodeRef::Await(n) => self.visit_await(n),
405            NodeRef::Yield(n) => self.visit_yield(n),
406            NodeRef::Parenthesized(n) => self.visit_parenthesized(n),
407            NodeRef::ForLoopInitializer(n) => self.visit_for_loop_initializer(n),
408            NodeRef::IterableLoopInitializer(n) => self.visit_iterable_loop_initializer(n),
409            NodeRef::Case(n) => self.visit_case(n),
410            NodeRef::Sym(n) => self.visit_sym(n),
411            NodeRef::LabelledItem(n) => self.visit_labelled_item(n),
412            NodeRef::Catch(n) => self.visit_catch(n),
413            NodeRef::Finally(n) => self.visit_finally(n),
414            NodeRef::FormalParameter(n) => self.visit_formal_parameter(n),
415            NodeRef::PropertyName(n) => self.visit_property_name(n),
416            NodeRef::ObjectMethodDefinition(n) => self.visit_object_method_definition(n),
417            NodeRef::ObjectPattern(n) => self.visit_object_pattern(n),
418            NodeRef::ArrayPattern(n) => self.visit_array_pattern(n),
419            NodeRef::PropertyDefinition(n) => self.visit_property_definition(n),
420            NodeRef::TemplateElement(n) => self.visit_template_element(n),
421            NodeRef::SimplePropertyAccess(n) => self.visit_simple_property_access(n),
422            NodeRef::PrivatePropertyAccess(n) => self.visit_private_property_access(n),
423            NodeRef::SuperPropertyAccess(n) => self.visit_super_property_access(n),
424            NodeRef::OptionalOperation(n) => self.visit_optional_operation(n),
425            NodeRef::AssignTarget(n) => self.visit_assign_target(n),
426            NodeRef::ObjectPatternElement(n) => self.visit_object_pattern_element(n),
427            NodeRef::ArrayPatternElement(n) => self.visit_array_pattern_element(n),
428            NodeRef::PropertyAccessField(n) => self.visit_property_access_field(n),
429            NodeRef::OptionalOperationKind(n) => self.visit_optional_operation_kind(n),
430            NodeRef::ModuleItemList(n) => self.visit_module_item_list(n),
431            NodeRef::ModuleItem(n) => self.visit_module_item(n),
432            NodeRef::ModuleSpecifier(n) => self.visit_module_specifier(n),
433            NodeRef::ImportKind(n) => self.visit_import_kind(n),
434            NodeRef::ImportDeclaration(n) => self.visit_import_declaration(n),
435            NodeRef::ImportSpecifier(n) => self.visit_import_specifier(n),
436            NodeRef::ReExportKind(n) => self.visit_re_export_kind(n),
437            NodeRef::ExportDeclaration(n) => self.visit_export_declaration(n),
438            NodeRef::ExportSpecifier(n) => self.visit_export_specifier(n),
439        }
440    }
441}
442
443/// Represents an AST visitor which can modify AST content.
444///
445/// This implementation is based largely on [chalk](https://github.com/rust-lang/chalk/blob/23d39c90ceb9242fbd4c43e9368e813e7c2179f7/chalk-ir/src/visit.rs)'s
446/// visitor pattern.
447pub trait VisitorMut<'ast>: Sized {
448    /// Type which will be propagated from the visitor if completing early.
449    type BreakTy;
450
451    define_visit_mut!(visit_script_mut, Script);
452    define_visit_mut!(visit_module_mut, Module);
453    define_visit_mut!(visit_function_body_mut, FunctionBody);
454    define_visit_mut!(visit_statement_list_mut, StatementList);
455    define_visit_mut!(visit_statement_list_item_mut, StatementListItem);
456    define_visit_mut!(visit_statement_mut, Statement);
457    define_visit_mut!(visit_declaration_mut, Declaration);
458    define_visit_mut!(visit_function_expression_mut, FunctionExpression);
459    define_visit_mut!(visit_function_declaration_mut, FunctionDeclaration);
460    define_visit_mut!(visit_generator_expression_mut, GeneratorExpression);
461    define_visit_mut!(visit_generator_declaration_mut, GeneratorDeclaration);
462    define_visit_mut!(visit_async_function_expression_mut, AsyncFunctionExpression);
463    define_visit_mut!(
464        visit_async_function_declaration_mut,
465        AsyncFunctionDeclaration
466    );
467    define_visit_mut!(
468        visit_async_generator_expression_mut,
469        AsyncGeneratorExpression
470    );
471    define_visit_mut!(
472        visit_async_generator_declaration_mut,
473        AsyncGeneratorDeclaration
474    );
475    define_visit_mut!(visit_class_expression_mut, ClassExpression);
476    define_visit_mut!(visit_class_declaration_mut, ClassDeclaration);
477    define_visit_mut!(visit_lexical_declaration_mut, LexicalDeclaration);
478    define_visit_mut!(visit_block_mut, Block);
479    define_visit_mut!(visit_var_declaration_mut, VarDeclaration);
480    define_visit_mut!(visit_expression_mut, Expression);
481    define_visit_mut!(visit_if_mut, If);
482    define_visit_mut!(visit_do_while_loop_mut, DoWhileLoop);
483    define_visit_mut!(visit_while_loop_mut, WhileLoop);
484    define_visit_mut!(visit_for_loop_mut, ForLoop);
485    define_visit_mut!(visit_for_in_loop_mut, ForInLoop);
486    define_visit_mut!(visit_for_of_loop_mut, ForOfLoop);
487    define_visit_mut!(visit_switch_mut, Switch);
488    define_visit_mut!(visit_continue_mut, Continue);
489    define_visit_mut!(visit_break_mut, Break);
490    define_visit_mut!(visit_return_mut, Return);
491    define_visit_mut!(visit_labelled_mut, Labelled);
492    define_visit_mut!(visit_throw_mut, Throw);
493    define_visit_mut!(visit_try_mut, Try);
494    define_visit_mut!(visit_with_mut, With);
495    define_visit_mut!(visit_this_mut, This);
496    define_visit_mut!(visit_identifier_mut, Identifier);
497    define_visit_mut!(visit_formal_parameter_list_mut, FormalParameterList);
498    define_visit_mut!(visit_class_element_mut, ClassElement);
499    define_visit_mut!(visit_private_name_mut, PrivateName);
500    define_visit_mut!(visit_variable_list_mut, VariableList);
501    define_visit_mut!(visit_variable_mut, Variable);
502    define_visit_mut!(visit_binding_mut, Binding);
503    define_visit_mut!(visit_pattern_mut, Pattern);
504    define_visit_mut!(visit_literal_mut, Literal);
505    define_visit_mut!(visit_reg_exp_literal_mut, RegExpLiteral);
506    define_visit_mut!(visit_array_literal_mut, ArrayLiteral);
507    define_visit_mut!(visit_object_literal_mut, ObjectLiteral);
508    define_visit_mut!(visit_spread_mut, Spread);
509    define_visit_mut!(visit_arrow_function_mut, ArrowFunction);
510    define_visit_mut!(visit_async_arrow_function_mut, AsyncArrowFunction);
511    define_visit_mut!(visit_template_literal_mut, TemplateLiteral);
512    define_visit_mut!(visit_property_access_mut, PropertyAccess);
513    define_visit_mut!(visit_new_mut, New);
514    define_visit_mut!(visit_call_mut, Call);
515    define_visit_mut!(visit_super_call_mut, SuperCall);
516    define_visit_mut!(visit_import_call_mut, ImportCall);
517    define_visit_mut!(visit_optional_mut, Optional);
518    define_visit_mut!(visit_tagged_template_mut, TaggedTemplate);
519    define_visit_mut!(visit_assign_mut, Assign);
520    define_visit_mut!(visit_unary_mut, Unary);
521    define_visit_mut!(visit_update_mut, Update);
522    define_visit_mut!(visit_binary_mut, Binary);
523    define_visit_mut!(visit_binary_in_private_mut, BinaryInPrivate);
524    define_visit_mut!(visit_conditional_mut, Conditional);
525    define_visit_mut!(visit_await_mut, Await);
526    define_visit_mut!(visit_yield_mut, Yield);
527    define_visit_mut!(visit_parenthesized_mut, Parenthesized);
528    define_visit_mut!(visit_new_target_mut, NewTarget);
529    define_visit_mut!(visit_import_meta_mut, ImportMeta);
530    define_visit_mut!(visit_for_loop_initializer_mut, ForLoopInitializer);
531    define_visit_mut!(visit_iterable_loop_initializer_mut, IterableLoopInitializer);
532    define_visit_mut!(visit_case_mut, Case);
533    define_visit_mut!(visit_sym_mut, Sym);
534    define_visit_mut!(visit_labelled_item_mut, LabelledItem);
535    define_visit_mut!(visit_catch_mut, Catch);
536    define_visit_mut!(visit_finally_mut, Finally);
537    define_visit_mut!(visit_formal_parameter_mut, FormalParameter);
538    define_visit_mut!(visit_property_name_mut, PropertyName);
539    define_visit_mut!(visit_object_method_definition_mut, ObjectMethodDefinition);
540    define_visit_mut!(visit_object_pattern_mut, ObjectPattern);
541    define_visit_mut!(visit_array_pattern_mut, ArrayPattern);
542    define_visit_mut!(visit_property_definition_mut, PropertyDefinition);
543    define_visit_mut!(visit_template_element_mut, TemplateElement);
544    define_visit_mut!(visit_simple_property_access_mut, SimplePropertyAccess);
545    define_visit_mut!(visit_private_property_access_mut, PrivatePropertyAccess);
546    define_visit_mut!(visit_super_property_access_mut, SuperPropertyAccess);
547    define_visit_mut!(visit_optional_operation_mut, OptionalOperation);
548    define_visit_mut!(visit_assign_target_mut, AssignTarget);
549    define_visit_mut!(visit_object_pattern_element_mut, ObjectPatternElement);
550    define_visit_mut!(visit_array_pattern_element_mut, ArrayPatternElement);
551    define_visit_mut!(visit_property_access_field_mut, PropertyAccessField);
552    define_visit_mut!(visit_optional_operation_kind_mut, OptionalOperationKind);
553    define_visit_mut!(visit_module_item_list_mut, ModuleItemList);
554    define_visit_mut!(visit_module_item_mut, ModuleItem);
555    define_visit_mut!(visit_module_specifier_mut, ModuleSpecifier);
556    define_visit_mut!(visit_import_kind_mut, ImportKind);
557    define_visit_mut!(visit_import_declaration_mut, ImportDeclaration);
558    define_visit_mut!(visit_import_specifier_mut, ImportSpecifier);
559    define_visit_mut!(visit_re_export_kind_mut, ReExportKind);
560    define_visit_mut!(visit_export_declaration_mut, ExportDeclaration);
561    define_visit_mut!(visit_export_specifier_mut, ExportSpecifier);
562
563    /// Generic entry point for a node that is visitable by a `VisitorMut`.
564    ///
565    /// This is usually used for generic functions that need to visit an unnamed AST node.
566    fn visit<N: Into<NodeRefMut<'ast>>>(&mut self, node: N) -> ControlFlow<Self::BreakTy> {
567        let node = node.into();
568        match node {
569            NodeRefMut::Script(n) => self.visit_script_mut(n),
570            NodeRefMut::Module(n) => self.visit_module_mut(n),
571            NodeRefMut::FunctionBody(n) => self.visit_function_body_mut(n),
572            NodeRefMut::StatementList(n) => self.visit_statement_list_mut(n),
573            NodeRefMut::StatementListItem(n) => self.visit_statement_list_item_mut(n),
574            NodeRefMut::Statement(n) => self.visit_statement_mut(n),
575            NodeRefMut::Declaration(n) => self.visit_declaration_mut(n),
576            NodeRefMut::FunctionExpression(n) => self.visit_function_expression_mut(n),
577            NodeRefMut::FunctionDeclaration(n) => self.visit_function_declaration_mut(n),
578            NodeRefMut::GeneratorExpression(n) => self.visit_generator_expression_mut(n),
579            NodeRefMut::GeneratorDeclaration(n) => self.visit_generator_declaration_mut(n),
580            NodeRefMut::AsyncFunctionExpression(n) => self.visit_async_function_expression_mut(n),
581            NodeRefMut::AsyncFunctionDeclaration(n) => self.visit_async_function_declaration_mut(n),
582            NodeRefMut::AsyncGeneratorExpression(n) => self.visit_async_generator_expression_mut(n),
583            NodeRefMut::AsyncGeneratorDeclaration(n) => {
584                self.visit_async_generator_declaration_mut(n)
585            }
586            NodeRefMut::ClassExpression(n) => self.visit_class_expression_mut(n),
587            NodeRefMut::ClassDeclaration(n) => self.visit_class_declaration_mut(n),
588            NodeRefMut::LexicalDeclaration(n) => self.visit_lexical_declaration_mut(n),
589            NodeRefMut::Block(n) => self.visit_block_mut(n),
590            NodeRefMut::VarDeclaration(n) => self.visit_var_declaration_mut(n),
591            NodeRefMut::Expression(n) => self.visit_expression_mut(n),
592            NodeRefMut::If(n) => self.visit_if_mut(n),
593            NodeRefMut::DoWhileLoop(n) => self.visit_do_while_loop_mut(n),
594            NodeRefMut::WhileLoop(n) => self.visit_while_loop_mut(n),
595            NodeRefMut::ForLoop(n) => self.visit_for_loop_mut(n),
596            NodeRefMut::ForInLoop(n) => self.visit_for_in_loop_mut(n),
597            NodeRefMut::ForOfLoop(n) => self.visit_for_of_loop_mut(n),
598            NodeRefMut::Switch(n) => self.visit_switch_mut(n),
599            NodeRefMut::Continue(n) => self.visit_continue_mut(n),
600            NodeRefMut::Break(n) => self.visit_break_mut(n),
601            NodeRefMut::Return(n) => self.visit_return_mut(n),
602            NodeRefMut::Labelled(n) => self.visit_labelled_mut(n),
603            NodeRefMut::With(n) => self.visit_with_mut(n),
604            NodeRefMut::Throw(n) => self.visit_throw_mut(n),
605            NodeRefMut::Try(n) => self.visit_try_mut(n),
606            NodeRefMut::This(n) => self.visit_this_mut(n),
607            NodeRefMut::NewTarget(n) => self.visit_new_target_mut(n),
608            NodeRefMut::ImportMeta(n) => self.visit_import_meta_mut(n),
609            NodeRefMut::Identifier(n) => self.visit_identifier_mut(n),
610            NodeRefMut::FormalParameterList(n) => self.visit_formal_parameter_list_mut(n),
611            NodeRefMut::ClassElement(n) => self.visit_class_element_mut(n),
612            NodeRefMut::PrivateName(n) => self.visit_private_name_mut(n),
613            NodeRefMut::VariableList(n) => self.visit_variable_list_mut(n),
614            NodeRefMut::Variable(n) => self.visit_variable_mut(n),
615            NodeRefMut::Binding(n) => self.visit_binding_mut(n),
616            NodeRefMut::Pattern(n) => self.visit_pattern_mut(n),
617            NodeRefMut::Literal(n) => self.visit_literal_mut(n),
618            NodeRefMut::RegExpLiteral(n) => self.visit_reg_exp_literal_mut(n),
619            NodeRefMut::ArrayLiteral(n) => self.visit_array_literal_mut(n),
620            NodeRefMut::ObjectLiteral(n) => self.visit_object_literal_mut(n),
621            NodeRefMut::Spread(n) => self.visit_spread_mut(n),
622            NodeRefMut::ArrowFunction(n) => self.visit_arrow_function_mut(n),
623            NodeRefMut::AsyncArrowFunction(n) => self.visit_async_arrow_function_mut(n),
624            NodeRefMut::TemplateLiteral(n) => self.visit_template_literal_mut(n),
625            NodeRefMut::PropertyAccess(n) => self.visit_property_access_mut(n),
626            NodeRefMut::New(n) => self.visit_new_mut(n),
627            NodeRefMut::Call(n) => self.visit_call_mut(n),
628            NodeRefMut::SuperCall(n) => self.visit_super_call_mut(n),
629            NodeRefMut::ImportCall(n) => self.visit_import_call_mut(n),
630            NodeRefMut::Optional(n) => self.visit_optional_mut(n),
631            NodeRefMut::TaggedTemplate(n) => self.visit_tagged_template_mut(n),
632            NodeRefMut::Assign(n) => self.visit_assign_mut(n),
633            NodeRefMut::Unary(n) => self.visit_unary_mut(n),
634            NodeRefMut::Update(n) => self.visit_update_mut(n),
635            NodeRefMut::Binary(n) => self.visit_binary_mut(n),
636            NodeRefMut::BinaryInPrivate(n) => self.visit_binary_in_private_mut(n),
637            NodeRefMut::Conditional(n) => self.visit_conditional_mut(n),
638            NodeRefMut::Await(n) => self.visit_await_mut(n),
639            NodeRefMut::Yield(n) => self.visit_yield_mut(n),
640            NodeRefMut::Parenthesized(n) => self.visit_parenthesized_mut(n),
641            NodeRefMut::ForLoopInitializer(n) => self.visit_for_loop_initializer_mut(n),
642            NodeRefMut::IterableLoopInitializer(n) => self.visit_iterable_loop_initializer_mut(n),
643            NodeRefMut::Case(n) => self.visit_case_mut(n),
644            NodeRefMut::Sym(n) => self.visit_sym_mut(n),
645            NodeRefMut::LabelledItem(n) => self.visit_labelled_item_mut(n),
646            NodeRefMut::Catch(n) => self.visit_catch_mut(n),
647            NodeRefMut::Finally(n) => self.visit_finally_mut(n),
648            NodeRefMut::FormalParameter(n) => self.visit_formal_parameter_mut(n),
649            NodeRefMut::PropertyName(n) => self.visit_property_name_mut(n),
650            NodeRefMut::ObjectMethodDefinition(n) => self.visit_object_method_definition_mut(n),
651            NodeRefMut::ObjectPattern(n) => self.visit_object_pattern_mut(n),
652            NodeRefMut::ArrayPattern(n) => self.visit_array_pattern_mut(n),
653            NodeRefMut::PropertyDefinition(n) => self.visit_property_definition_mut(n),
654            NodeRefMut::TemplateElement(n) => self.visit_template_element_mut(n),
655            NodeRefMut::SimplePropertyAccess(n) => self.visit_simple_property_access_mut(n),
656            NodeRefMut::PrivatePropertyAccess(n) => self.visit_private_property_access_mut(n),
657            NodeRefMut::SuperPropertyAccess(n) => self.visit_super_property_access_mut(n),
658            NodeRefMut::OptionalOperation(n) => self.visit_optional_operation_mut(n),
659            NodeRefMut::AssignTarget(n) => self.visit_assign_target_mut(n),
660            NodeRefMut::ObjectPatternElement(n) => self.visit_object_pattern_element_mut(n),
661            NodeRefMut::ArrayPatternElement(n) => self.visit_array_pattern_element_mut(n),
662            NodeRefMut::PropertyAccessField(n) => self.visit_property_access_field_mut(n),
663            NodeRefMut::OptionalOperationKind(n) => self.visit_optional_operation_kind_mut(n),
664            NodeRefMut::ModuleItemList(n) => self.visit_module_item_list_mut(n),
665            NodeRefMut::ModuleItem(n) => self.visit_module_item_mut(n),
666            NodeRefMut::ModuleSpecifier(n) => self.visit_module_specifier_mut(n),
667            NodeRefMut::ImportKind(n) => self.visit_import_kind_mut(n),
668            NodeRefMut::ImportDeclaration(n) => self.visit_import_declaration_mut(n),
669            NodeRefMut::ImportSpecifier(n) => self.visit_import_specifier_mut(n),
670            NodeRefMut::ReExportKind(n) => self.visit_re_export_kind_mut(n),
671            NodeRefMut::ExportDeclaration(n) => self.visit_export_declaration_mut(n),
672            NodeRefMut::ExportSpecifier(n) => self.visit_export_specifier_mut(n),
673        }
674    }
675}
676
677/// Denotes that a type may be visited, providing a method which allows a visitor to traverse its
678/// private fields.
679pub trait VisitWith {
680    /// Visit this node with the provided visitor.
681    fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
682    where
683        V: Visitor<'a>;
684
685    /// Visit this node with the provided visitor mutably, allowing the visitor to modify private
686    /// fields.
687    fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
688    where
689        V: VisitorMut<'a>;
690}
691
692// implementation for Sym as it is out-of-crate
693impl VisitWith for Sym {
694    fn visit_with<'a, V>(&'a self, _visitor: &mut V) -> ControlFlow<V::BreakTy>
695    where
696        V: Visitor<'a>,
697    {
698        ControlFlow::Continue(())
699    }
700
701    fn visit_with_mut<'a, V>(&'a mut self, _visitor: &mut V) -> ControlFlow<V::BreakTy>
702    where
703        V: VisitorMut<'a>,
704    {
705        ControlFlow::Continue(())
706    }
707}