1use crate::Program;
8use crate::declarations::*;
9use crate::expressions::*;
10use crate::jsx::*;
11use crate::patterns::*;
12use crate::scope::ScopeId;
13use crate::scope::ScopeInfo;
14use crate::statements::*;
15
16pub trait Visitor<'ast> {
25 fn traverse_function_bodies(&self) -> bool {
32 true
33 }
34
35 fn enter_function_declaration(
36 &mut self,
37 _node: &'ast FunctionDeclaration,
38 _scope_stack: &[ScopeId],
39 ) {
40 }
41 fn leave_function_declaration(
42 &mut self,
43 _node: &'ast FunctionDeclaration,
44 _scope_stack: &[ScopeId],
45 ) {
46 }
47 fn enter_function_expression(
48 &mut self,
49 _node: &'ast FunctionExpression,
50 _scope_stack: &[ScopeId],
51 ) {
52 }
53 fn leave_function_expression(
54 &mut self,
55 _node: &'ast FunctionExpression,
56 _scope_stack: &[ScopeId],
57 ) {
58 }
59 fn enter_arrow_function_expression(
60 &mut self,
61 _node: &'ast ArrowFunctionExpression,
62 _scope_stack: &[ScopeId],
63 ) {
64 }
65 fn leave_arrow_function_expression(
66 &mut self,
67 _node: &'ast ArrowFunctionExpression,
68 _scope_stack: &[ScopeId],
69 ) {
70 }
71 fn enter_class_declaration(
72 &mut self,
73 _node: &'ast crate::statements::ClassDeclaration,
74 _scope_stack: &[ScopeId],
75 ) {
76 }
77 fn enter_class_expression(&mut self, _node: &'ast ClassExpression, _scope_stack: &[ScopeId]) {}
78 fn enter_object_method(&mut self, _node: &'ast ObjectMethod, _scope_stack: &[ScopeId]) {}
79 fn leave_object_method(&mut self, _node: &'ast ObjectMethod, _scope_stack: &[ScopeId]) {}
80 fn enter_assignment_expression(
81 &mut self,
82 _node: &'ast AssignmentExpression,
83 _scope_stack: &[ScopeId],
84 ) {
85 }
86 fn enter_update_expression(&mut self, _node: &'ast UpdateExpression, _scope_stack: &[ScopeId]) {
87 }
88 fn enter_identifier(&mut self, _node: &'ast Identifier, _scope_stack: &[ScopeId]) {}
89 fn enter_jsx_identifier(&mut self, _node: &'ast JSXIdentifier, _scope_stack: &[ScopeId]) {}
90 fn enter_jsx_opening_element(
91 &mut self,
92 _node: &'ast JSXOpeningElement,
93 _scope_stack: &[ScopeId],
94 ) {
95 }
96 fn leave_jsx_opening_element(
97 &mut self,
98 _node: &'ast JSXOpeningElement,
99 _scope_stack: &[ScopeId],
100 ) {
101 }
102
103 fn enter_variable_declarator(
104 &mut self,
105 _node: &'ast VariableDeclarator,
106 _scope_stack: &[ScopeId],
107 ) {
108 }
109 fn leave_variable_declarator(
110 &mut self,
111 _node: &'ast VariableDeclarator,
112 _scope_stack: &[ScopeId],
113 ) {
114 }
115
116 fn enter_call_expression(&mut self, _node: &'ast CallExpression, _scope_stack: &[ScopeId]) {}
117 fn leave_call_expression(&mut self, _node: &'ast CallExpression, _scope_stack: &[ScopeId]) {}
118
119 fn enter_loop_expression(&mut self) {}
124 fn leave_loop_expression(&mut self) {}
125}
126
127pub struct AstWalker<'a> {
129 scope_info: &'a ScopeInfo,
130 scope_stack: Vec<ScopeId>,
131 loop_expression_depth: usize,
137}
138
139impl<'a> AstWalker<'a> {
140 pub fn new(scope_info: &'a ScopeInfo) -> Self {
141 AstWalker {
142 scope_info,
143 scope_stack: Vec::new(),
144 loop_expression_depth: 0,
145 }
146 }
147
148 pub fn with_initial_scope(scope_info: &'a ScopeInfo, initial_scope: ScopeId) -> Self {
150 AstWalker {
151 scope_info,
152 scope_stack: vec![initial_scope],
153 loop_expression_depth: 0,
154 }
155 }
156
157 pub fn scope_stack(&self) -> &[ScopeId] {
158 &self.scope_stack
159 }
160
161 pub fn loop_expression_depth(&self) -> usize {
166 self.loop_expression_depth
167 }
168
169 fn try_push_scope(&mut self, _start: Option<u32>, node_id: Option<u32>) -> bool {
171 let scope = self.scope_info.resolve_scope_for_node(node_id);
172 if let Some(scope_id) = scope {
173 self.scope_stack.push(scope_id);
174 return true;
175 }
176 false
177 }
178
179 pub fn walk_program<'ast>(&mut self, v: &mut impl Visitor<'ast>, node: &'ast Program) {
182 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
183 for stmt in &node.body {
184 self.walk_statement(v, stmt);
185 }
186 if pushed {
187 self.scope_stack.pop();
188 }
189 }
190
191 pub fn walk_block_statement<'ast>(
192 &mut self,
193 v: &mut impl Visitor<'ast>,
194 node: &'ast BlockStatement,
195 ) {
196 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
197 for stmt in &node.body {
198 self.walk_statement(v, stmt);
199 }
200 if pushed {
201 self.scope_stack.pop();
202 }
203 }
204
205 pub fn walk_statement<'ast>(&mut self, v: &mut impl Visitor<'ast>, stmt: &'ast Statement) {
206 match stmt {
207 Statement::BlockStatement(node) => self.walk_block_statement(v, node),
208 Statement::ReturnStatement(node) => {
209 if let Some(arg) = &node.argument {
210 self.walk_expression(v, arg);
211 }
212 }
213 Statement::ExpressionStatement(node) => {
214 self.walk_expression(v, &node.expression);
215 }
216 Statement::IfStatement(node) => {
217 self.walk_expression(v, &node.test);
218 self.walk_statement(v, &node.consequent);
219 if let Some(alt) = &node.alternate {
220 self.walk_statement(v, alt);
221 }
222 }
223 Statement::ForStatement(node) => {
224 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
225 if let Some(init) = &node.init {
226 match init.as_ref() {
227 ForInit::VariableDeclaration(decl) => {
228 self.walk_variable_declaration(v, decl)
229 }
230 ForInit::Expression(expr) => self.walk_expression(v, expr),
231 }
232 }
233 if let Some(test) = &node.test {
234 self.walk_expression(v, test);
235 }
236 if let Some(update) = &node.update {
237 self.walk_expression(v, update);
238 }
239 self.walk_statement(v, &node.body);
240 if pushed {
241 self.scope_stack.pop();
242 }
243 }
244 Statement::WhileStatement(node) => {
245 self.loop_expression_depth += 1;
246 v.enter_loop_expression();
247 self.walk_expression(v, &node.test);
248 v.leave_loop_expression();
249 self.loop_expression_depth -= 1;
250 self.walk_statement(v, &node.body);
251 }
252 Statement::DoWhileStatement(node) => {
253 self.walk_statement(v, &node.body);
254 self.loop_expression_depth += 1;
255 v.enter_loop_expression();
256 self.walk_expression(v, &node.test);
257 v.leave_loop_expression();
258 self.loop_expression_depth -= 1;
259 }
260 Statement::ForInStatement(node) => {
261 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
262 self.walk_for_in_of_left(v, &node.left);
263 self.loop_expression_depth += 1;
264 v.enter_loop_expression();
265 self.walk_expression(v, &node.right);
266 v.leave_loop_expression();
267 self.loop_expression_depth -= 1;
268 self.walk_statement(v, &node.body);
269 if pushed {
270 self.scope_stack.pop();
271 }
272 }
273 Statement::ForOfStatement(node) => {
274 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
275 self.walk_for_in_of_left(v, &node.left);
276 self.loop_expression_depth += 1;
277 v.enter_loop_expression();
278 self.walk_expression(v, &node.right);
279 v.leave_loop_expression();
280 self.loop_expression_depth -= 1;
281 self.walk_statement(v, &node.body);
282 if pushed {
283 self.scope_stack.pop();
284 }
285 }
286 Statement::SwitchStatement(node) => {
287 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
288 self.walk_expression(v, &node.discriminant);
289 for case in &node.cases {
290 if let Some(test) = &case.test {
291 self.walk_expression(v, test);
292 }
293 for consequent in &case.consequent {
294 self.walk_statement(v, consequent);
295 }
296 }
297 if pushed {
298 self.scope_stack.pop();
299 }
300 }
301 Statement::ThrowStatement(node) => {
302 self.walk_expression(v, &node.argument);
303 }
304 Statement::TryStatement(node) => {
305 self.walk_block_statement(v, &node.block);
306 if let Some(handler) = &node.handler {
307 let pushed = self.try_push_scope(handler.base.start, handler.base.node_id);
308 if let Some(param) = &handler.param {
309 self.walk_pattern(v, param);
310 }
311 self.walk_block_statement(v, &handler.body);
312 if pushed {
313 self.scope_stack.pop();
314 }
315 }
316 if let Some(finalizer) = &node.finalizer {
317 self.walk_block_statement(v, finalizer);
318 }
319 }
320 Statement::LabeledStatement(node) => {
321 self.walk_statement(v, &node.body);
322 }
323 Statement::VariableDeclaration(node) => {
324 self.walk_variable_declaration(v, node);
325 }
326 Statement::FunctionDeclaration(node) => {
327 self.walk_function_declaration_inner(v, node);
328 }
329 Statement::ClassDeclaration(node) => {
330 v.enter_class_declaration(node, &self.scope_stack);
333 }
334 Statement::WithStatement(node) => {
335 self.walk_expression(v, &node.object);
336 self.walk_statement(v, &node.body);
337 }
338 Statement::ExportNamedDeclaration(node) => {
339 if let Some(decl) = &node.declaration {
340 self.walk_declaration(v, decl);
341 }
342 }
343 Statement::ExportDefaultDeclaration(node) => {
344 self.walk_export_default_decl(v, &node.declaration);
345 }
346 Statement::BreakStatement(_)
348 | Statement::ContinueStatement(_)
349 | Statement::EmptyStatement(_)
350 | Statement::DebuggerStatement(_)
351 | Statement::ImportDeclaration(_)
352 | Statement::ExportAllDeclaration(_)
353 | Statement::TSTypeAliasDeclaration(_)
354 | Statement::TSInterfaceDeclaration(_)
355 | Statement::TSEnumDeclaration(_)
356 | Statement::TSModuleDeclaration(_)
357 | Statement::TSDeclareFunction(_)
358 | Statement::TypeAlias(_)
359 | Statement::OpaqueType(_)
360 | Statement::InterfaceDeclaration(_)
361 | Statement::DeclareVariable(_)
362 | Statement::DeclareFunction(_)
363 | Statement::DeclareClass(_)
364 | Statement::DeclareModule(_)
365 | Statement::DeclareModuleExports(_)
366 | Statement::DeclareExportDeclaration(_)
367 | Statement::DeclareExportAllDeclaration(_)
368 | Statement::DeclareInterface(_)
369 | Statement::DeclareTypeAlias(_)
370 | Statement::DeclareOpaqueType(_)
371 | Statement::EnumDeclaration(_) => {}
372 }
373 }
374
375 pub fn walk_expression<'ast>(&mut self, v: &mut impl Visitor<'ast>, expr: &'ast Expression) {
376 match expr {
377 Expression::Identifier(node) => {
378 v.enter_identifier(node, &self.scope_stack);
379 }
380 Expression::CallExpression(node) => {
381 v.enter_call_expression(node, &self.scope_stack);
382 self.walk_expression(v, &node.callee);
383 for arg in &node.arguments {
384 self.walk_expression(v, arg);
385 }
386 v.leave_call_expression(node, &self.scope_stack);
387 }
388 Expression::MemberExpression(node) => {
389 self.walk_expression(v, &node.object);
390 if node.computed {
391 self.walk_expression(v, &node.property);
392 }
393 }
394 Expression::OptionalCallExpression(node) => {
395 self.walk_expression(v, &node.callee);
396 for arg in &node.arguments {
397 self.walk_expression(v, arg);
398 }
399 }
400 Expression::OptionalMemberExpression(node) => {
401 self.walk_expression(v, &node.object);
402 if node.computed {
403 self.walk_expression(v, &node.property);
404 }
405 }
406 Expression::BinaryExpression(node) => {
407 self.walk_expression(v, &node.left);
408 self.walk_expression(v, &node.right);
409 }
410 Expression::LogicalExpression(node) => {
411 self.walk_expression(v, &node.left);
412 self.walk_expression(v, &node.right);
413 }
414 Expression::UnaryExpression(node) => {
415 self.walk_expression(v, &node.argument);
416 }
417 Expression::UpdateExpression(node) => {
418 v.enter_update_expression(node, &self.scope_stack);
419 self.walk_expression(v, &node.argument);
420 }
421 Expression::ConditionalExpression(node) => {
422 self.walk_expression(v, &node.test);
423 self.walk_expression(v, &node.consequent);
424 self.walk_expression(v, &node.alternate);
425 }
426 Expression::AssignmentExpression(node) => {
427 v.enter_assignment_expression(node, &self.scope_stack);
428 self.walk_pattern(v, &node.left);
429 self.walk_expression(v, &node.right);
430 }
431 Expression::SequenceExpression(node) => {
432 for expr in &node.expressions {
433 self.walk_expression(v, expr);
434 }
435 }
436 Expression::ArrowFunctionExpression(node) => {
437 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
438 v.enter_arrow_function_expression(node, &self.scope_stack);
439 if v.traverse_function_bodies() {
440 for param in &node.params {
441 self.walk_pattern(v, param);
442 }
443 match node.body.as_ref() {
444 ArrowFunctionBody::BlockStatement(block) => {
445 self.walk_block_statement(v, block);
446 }
447 ArrowFunctionBody::Expression(expr) => {
448 self.walk_expression(v, expr);
449 }
450 }
451 }
452 v.leave_arrow_function_expression(node, &self.scope_stack);
453 if pushed {
454 self.scope_stack.pop();
455 }
456 }
457 Expression::FunctionExpression(node) => {
458 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
459 v.enter_function_expression(node, &self.scope_stack);
460 if v.traverse_function_bodies() {
461 for param in &node.params {
462 self.walk_pattern(v, param);
463 }
464 self.walk_block_statement(v, &node.body);
465 }
466 v.leave_function_expression(node, &self.scope_stack);
467 if pushed {
468 self.scope_stack.pop();
469 }
470 }
471 Expression::ObjectExpression(node) => {
472 for prop in &node.properties {
473 self.walk_object_expression_property(v, prop);
474 }
475 }
476 Expression::ArrayExpression(node) => {
477 for element in &node.elements {
478 if let Some(el) = element {
479 self.walk_expression(v, el);
480 }
481 }
482 }
483 Expression::NewExpression(node) => {
484 self.walk_expression(v, &node.callee);
485 for arg in &node.arguments {
486 self.walk_expression(v, arg);
487 }
488 }
489 Expression::TemplateLiteral(node) => {
490 for expr in &node.expressions {
491 self.walk_expression(v, expr);
492 }
493 }
494 Expression::TaggedTemplateExpression(node) => {
495 self.walk_expression(v, &node.tag);
496 for expr in &node.quasi.expressions {
497 self.walk_expression(v, expr);
498 }
499 }
500 Expression::AwaitExpression(node) => {
501 self.walk_expression(v, &node.argument);
502 }
503 Expression::YieldExpression(node) => {
504 if let Some(arg) = &node.argument {
505 self.walk_expression(v, arg);
506 }
507 }
508 Expression::SpreadElement(node) => {
509 self.walk_expression(v, &node.argument);
510 }
511 Expression::ParenthesizedExpression(node) => {
512 self.walk_expression(v, &node.expression);
513 }
514 Expression::AssignmentPattern(node) => {
515 self.walk_pattern(v, &node.left);
516 self.walk_expression(v, &node.right);
517 }
518 Expression::ClassExpression(node) => {
519 v.enter_class_expression(node, &self.scope_stack);
522 }
523 Expression::JSXElement(node) => self.walk_jsx_element(v, node),
525 Expression::JSXFragment(node) => self.walk_jsx_fragment(v, node),
526 Expression::TSAsExpression(node) => self.walk_expression(v, &node.expression),
528 Expression::TSSatisfiesExpression(node) => self.walk_expression(v, &node.expression),
529 Expression::TSNonNullExpression(node) => self.walk_expression(v, &node.expression),
530 Expression::TSTypeAssertion(node) => self.walk_expression(v, &node.expression),
531 Expression::TSInstantiationExpression(node) => {
532 self.walk_expression(v, &node.expression)
533 }
534 Expression::TypeCastExpression(node) => self.walk_expression(v, &node.expression),
535 Expression::StringLiteral(_)
537 | Expression::NumericLiteral(_)
538 | Expression::BooleanLiteral(_)
539 | Expression::NullLiteral(_)
540 | Expression::BigIntLiteral(_)
541 | Expression::RegExpLiteral(_)
542 | Expression::MetaProperty(_)
543 | Expression::PrivateName(_)
544 | Expression::Super(_)
545 | Expression::Import(_)
546 | Expression::ThisExpression(_) => {}
547 }
548 }
549
550 pub fn walk_pattern<'ast>(&mut self, v: &mut impl Visitor<'ast>, pat: &'ast PatternLike) {
551 match pat {
552 PatternLike::Identifier(node) => {
553 v.enter_identifier(node, &self.scope_stack);
554 }
555 PatternLike::ObjectPattern(node) => {
556 for prop in &node.properties {
557 match prop {
558 ObjectPatternProperty::ObjectProperty(p) => {
559 if p.computed {
560 self.walk_expression(v, &p.key);
561 }
562 self.walk_pattern(v, &p.value);
563 }
564 ObjectPatternProperty::RestElement(p) => {
565 self.walk_pattern(v, &p.argument);
566 }
567 }
568 }
569 }
570 PatternLike::ArrayPattern(node) => {
571 for element in &node.elements {
572 if let Some(el) = element {
573 self.walk_pattern(v, el);
574 }
575 }
576 }
577 PatternLike::AssignmentPattern(node) => {
578 self.walk_pattern(v, &node.left);
579 self.walk_expression(v, &node.right);
580 }
581 PatternLike::RestElement(node) => {
582 self.walk_pattern(v, &node.argument);
583 }
584 PatternLike::MemberExpression(node) => {
585 self.walk_expression(v, &node.object);
586 if node.computed {
587 self.walk_expression(v, &node.property);
588 }
589 }
590 PatternLike::TSAsExpression(node) => self.walk_expression(v, &node.expression),
591 PatternLike::TSSatisfiesExpression(node) => {
592 self.walk_expression(v, &node.expression)
593 }
594 PatternLike::TSNonNullExpression(node) => {
595 self.walk_expression(v, &node.expression)
596 }
597 PatternLike::TSTypeAssertion(node) => self.walk_expression(v, &node.expression),
598 PatternLike::TypeCastExpression(node) => self.walk_expression(v, &node.expression),
599 }
600 }
601
602 fn walk_for_in_of_left<'ast>(&mut self, v: &mut impl Visitor<'ast>, left: &'ast ForInOfLeft) {
605 match left {
606 ForInOfLeft::VariableDeclaration(decl) => self.walk_variable_declaration(v, decl),
607 ForInOfLeft::Pattern(pat) => self.walk_pattern(v, pat),
608 }
609 }
610
611 fn walk_variable_declaration<'ast>(
612 &mut self,
613 v: &mut impl Visitor<'ast>,
614 decl: &'ast VariableDeclaration,
615 ) {
616 for declarator in &decl.declarations {
617 v.enter_variable_declarator(declarator, &self.scope_stack);
618 self.walk_pattern(v, &declarator.id);
619 if let Some(init) = &declarator.init {
620 self.walk_expression(v, init);
621 }
622 v.leave_variable_declarator(declarator, &self.scope_stack);
623 }
624 }
625
626 fn walk_function_declaration_inner<'ast>(
627 &mut self,
628 v: &mut impl Visitor<'ast>,
629 node: &'ast FunctionDeclaration,
630 ) {
631 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
632 v.enter_function_declaration(node, &self.scope_stack);
633 if v.traverse_function_bodies() {
634 for param in &node.params {
635 self.walk_pattern(v, param);
636 }
637 self.walk_block_statement(v, &node.body);
638 }
639 v.leave_function_declaration(node, &self.scope_stack);
640 if pushed {
641 self.scope_stack.pop();
642 }
643 }
644
645 fn walk_object_expression_property<'ast>(
646 &mut self,
647 v: &mut impl Visitor<'ast>,
648 prop: &'ast ObjectExpressionProperty,
649 ) {
650 match prop {
651 ObjectExpressionProperty::ObjectProperty(p) => {
652 if p.computed {
653 self.walk_expression(v, &p.key);
654 }
655 self.walk_expression(v, &p.value);
656 }
657 ObjectExpressionProperty::ObjectMethod(node) => {
658 let pushed = self.try_push_scope(node.base.start, node.base.node_id);
659 v.enter_object_method(node, &self.scope_stack);
660 if v.traverse_function_bodies() {
661 if node.computed {
662 self.walk_expression(v, &node.key);
663 }
664 for param in &node.params {
665 self.walk_pattern(v, param);
666 }
667 self.walk_block_statement(v, &node.body);
668 }
669 v.leave_object_method(node, &self.scope_stack);
670 if pushed {
671 self.scope_stack.pop();
672 }
673 }
674 ObjectExpressionProperty::SpreadElement(p) => {
675 self.walk_expression(v, &p.argument);
676 }
677 }
678 }
679
680 fn walk_declaration<'ast>(&mut self, v: &mut impl Visitor<'ast>, decl: &'ast Declaration) {
681 match decl {
682 Declaration::FunctionDeclaration(node) => {
683 self.walk_function_declaration_inner(v, node);
684 }
685 Declaration::VariableDeclaration(node) => {
686 self.walk_variable_declaration(v, node);
687 }
688 _ => {}
690 }
691 }
692
693 fn walk_export_default_decl<'ast>(
694 &mut self,
695 v: &mut impl Visitor<'ast>,
696 decl: &'ast ExportDefaultDecl,
697 ) {
698 match decl {
699 ExportDefaultDecl::FunctionDeclaration(node) => {
700 self.walk_function_declaration_inner(v, node);
701 }
702 ExportDefaultDecl::ClassDeclaration(node) => {
703 v.enter_class_declaration(node, &self.scope_stack);
705 }
706 ExportDefaultDecl::EnumDeclaration(_) => {
707 }
709 ExportDefaultDecl::Expression(expr) => {
710 self.walk_expression(v, expr);
711 }
712 }
713 }
714
715 fn walk_jsx_element<'ast>(&mut self, v: &mut impl Visitor<'ast>, node: &'ast JSXElement) {
716 v.enter_jsx_opening_element(&node.opening_element, &self.scope_stack);
717 self.walk_jsx_element_name(v, &node.opening_element.name);
718 v.leave_jsx_opening_element(&node.opening_element, &self.scope_stack);
719 for attr in &node.opening_element.attributes {
720 match attr {
721 JSXAttributeItem::JSXAttribute(a) => {
722 if let Some(value) = &a.value {
723 match value {
724 JSXAttributeValue::JSXExpressionContainer(c) => {
725 self.walk_jsx_expr_container(v, c);
726 }
727 JSXAttributeValue::JSXElement(el) => {
728 self.walk_jsx_element(v, el);
729 }
730 JSXAttributeValue::JSXFragment(f) => {
731 self.walk_jsx_fragment(v, f);
732 }
733 JSXAttributeValue::StringLiteral(_) => {}
734 }
735 }
736 }
737 JSXAttributeItem::JSXSpreadAttribute(a) => {
738 self.walk_expression(v, &a.argument);
739 }
740 }
741 }
742 for child in &node.children {
743 self.walk_jsx_child(v, child);
744 }
745 }
746
747 fn walk_jsx_fragment<'ast>(&mut self, v: &mut impl Visitor<'ast>, node: &'ast JSXFragment) {
748 for child in &node.children {
749 self.walk_jsx_child(v, child);
750 }
751 }
752
753 fn walk_jsx_child<'ast>(&mut self, v: &mut impl Visitor<'ast>, child: &'ast JSXChild) {
754 match child {
755 JSXChild::JSXElement(el) => self.walk_jsx_element(v, el),
756 JSXChild::JSXFragment(f) => self.walk_jsx_fragment(v, f),
757 JSXChild::JSXExpressionContainer(c) => self.walk_jsx_expr_container(v, c),
758 JSXChild::JSXSpreadChild(s) => self.walk_expression(v, &s.expression),
759 JSXChild::JSXText(_) => {}
760 }
761 }
762
763 fn walk_jsx_expr_container<'ast>(
764 &mut self,
765 v: &mut impl Visitor<'ast>,
766 node: &'ast JSXExpressionContainer,
767 ) {
768 match &node.expression {
769 JSXExpressionContainerExpr::Expression(expr) => self.walk_expression(v, expr),
770 JSXExpressionContainerExpr::JSXEmptyExpression(_) => {}
771 }
772 }
773
774 fn walk_jsx_element_name<'ast>(
775 &mut self,
776 v: &mut impl Visitor<'ast>,
777 name: &'ast JSXElementName,
778 ) {
779 match name {
780 JSXElementName::JSXIdentifier(id) => {
781 v.enter_jsx_identifier(id, &self.scope_stack);
782 }
783 JSXElementName::JSXMemberExpression(expr) => {
784 self.walk_jsx_member_expression(v, expr);
785 }
786 JSXElementName::JSXNamespacedName(_) => {}
787 }
788 }
789
790 fn walk_jsx_member_expression<'ast>(
791 &mut self,
792 v: &mut impl Visitor<'ast>,
793 expr: &'ast JSXMemberExpression,
794 ) {
795 match &*expr.object {
796 JSXMemberExprObject::JSXIdentifier(id) => {
797 v.enter_jsx_identifier(id, &self.scope_stack);
798 }
799 JSXMemberExprObject::JSXMemberExpression(inner) => {
800 self.walk_jsx_member_expression(v, inner);
801 }
802 }
803 v.enter_jsx_identifier(&expr.property, &self.scope_stack);
804 }
805}
806
807#[derive(Debug, Clone, Copy, PartialEq, Eq)]
813pub enum VisitResult {
814 Continue,
816 Stop,
818}
819
820impl VisitResult {
821 pub fn is_stop(self) -> bool {
822 self == VisitResult::Stop
823 }
824}
825
826pub trait MutVisitor {
833 fn visit_statement(&mut self, _stmt: &mut Statement) -> VisitResult {
835 VisitResult::Continue
836 }
837
838 fn visit_expression(&mut self, _expr: &mut Expression) -> VisitResult {
840 VisitResult::Continue
841 }
842
843 fn visit_identifier(&mut self, _node: &mut Identifier) -> VisitResult {
845 VisitResult::Continue
846 }
847}
848
849pub fn walk_program_mut(v: &mut impl MutVisitor, program: &mut Program) -> VisitResult {
851 for stmt in program.body.iter_mut() {
852 if walk_statement_mut(v, stmt).is_stop() {
853 return VisitResult::Stop;
854 }
855 }
856 VisitResult::Continue
857}
858
859pub fn walk_statement_mut(v: &mut impl MutVisitor, stmt: &mut Statement) -> VisitResult {
861 if v.visit_statement(stmt).is_stop() {
862 return VisitResult::Stop;
863 }
864 match stmt {
865 Statement::BlockStatement(node) => {
866 for s in node.body.iter_mut() {
867 if walk_statement_mut(v, s).is_stop() {
868 return VisitResult::Stop;
869 }
870 }
871 }
872 Statement::ReturnStatement(node) => {
873 if let Some(ref mut arg) = node.argument {
874 if walk_expression_mut(v, arg).is_stop() {
875 return VisitResult::Stop;
876 }
877 }
878 }
879 Statement::ExpressionStatement(node) => {
880 if walk_expression_mut(v, &mut node.expression).is_stop() {
881 return VisitResult::Stop;
882 }
883 }
884 Statement::IfStatement(node) => {
885 if walk_expression_mut(v, &mut node.test).is_stop() {
886 return VisitResult::Stop;
887 }
888 if walk_statement_mut(v, &mut node.consequent).is_stop() {
889 return VisitResult::Stop;
890 }
891 if let Some(ref mut alt) = node.alternate {
892 if walk_statement_mut(v, alt).is_stop() {
893 return VisitResult::Stop;
894 }
895 }
896 }
897 Statement::ForStatement(node) => {
898 if let Some(ref mut init) = node.init {
899 match init.as_mut() {
900 ForInit::VariableDeclaration(decl) => {
901 if walk_variable_declaration_mut(v, decl).is_stop() {
902 return VisitResult::Stop;
903 }
904 }
905 ForInit::Expression(expr) => {
906 if walk_expression_mut(v, expr).is_stop() {
907 return VisitResult::Stop;
908 }
909 }
910 }
911 }
912 if let Some(ref mut test) = node.test {
913 if walk_expression_mut(v, test).is_stop() {
914 return VisitResult::Stop;
915 }
916 }
917 if let Some(ref mut update) = node.update {
918 if walk_expression_mut(v, update).is_stop() {
919 return VisitResult::Stop;
920 }
921 }
922 if walk_statement_mut(v, &mut node.body).is_stop() {
923 return VisitResult::Stop;
924 }
925 }
926 Statement::WhileStatement(node) => {
927 if walk_expression_mut(v, &mut node.test).is_stop() {
928 return VisitResult::Stop;
929 }
930 if walk_statement_mut(v, &mut node.body).is_stop() {
931 return VisitResult::Stop;
932 }
933 }
934 Statement::DoWhileStatement(node) => {
935 if walk_statement_mut(v, &mut node.body).is_stop() {
936 return VisitResult::Stop;
937 }
938 if walk_expression_mut(v, &mut node.test).is_stop() {
939 return VisitResult::Stop;
940 }
941 }
942 Statement::ForInStatement(node) => {
943 if walk_expression_mut(v, &mut node.right).is_stop() {
944 return VisitResult::Stop;
945 }
946 if walk_statement_mut(v, &mut node.body).is_stop() {
947 return VisitResult::Stop;
948 }
949 }
950 Statement::ForOfStatement(node) => {
951 if walk_expression_mut(v, &mut node.right).is_stop() {
952 return VisitResult::Stop;
953 }
954 if walk_statement_mut(v, &mut node.body).is_stop() {
955 return VisitResult::Stop;
956 }
957 }
958 Statement::SwitchStatement(node) => {
959 if walk_expression_mut(v, &mut node.discriminant).is_stop() {
960 return VisitResult::Stop;
961 }
962 for case in node.cases.iter_mut() {
963 if let Some(ref mut test) = case.test {
964 if walk_expression_mut(v, test).is_stop() {
965 return VisitResult::Stop;
966 }
967 }
968 for s in case.consequent.iter_mut() {
969 if walk_statement_mut(v, s).is_stop() {
970 return VisitResult::Stop;
971 }
972 }
973 }
974 }
975 Statement::ThrowStatement(node) => {
976 if walk_expression_mut(v, &mut node.argument).is_stop() {
977 return VisitResult::Stop;
978 }
979 }
980 Statement::TryStatement(node) => {
981 for s in node.block.body.iter_mut() {
982 if walk_statement_mut(v, s).is_stop() {
983 return VisitResult::Stop;
984 }
985 }
986 if let Some(ref mut handler) = node.handler {
987 for s in handler.body.body.iter_mut() {
988 if walk_statement_mut(v, s).is_stop() {
989 return VisitResult::Stop;
990 }
991 }
992 }
993 if let Some(ref mut finalizer) = node.finalizer {
994 for s in finalizer.body.iter_mut() {
995 if walk_statement_mut(v, s).is_stop() {
996 return VisitResult::Stop;
997 }
998 }
999 }
1000 }
1001 Statement::LabeledStatement(node) => {
1002 if walk_statement_mut(v, &mut node.body).is_stop() {
1003 return VisitResult::Stop;
1004 }
1005 }
1006 Statement::VariableDeclaration(node) => {
1007 if walk_variable_declaration_mut(v, node).is_stop() {
1008 return VisitResult::Stop;
1009 }
1010 }
1011 Statement::FunctionDeclaration(node) => {
1012 for s in node.body.body.iter_mut() {
1013 if walk_statement_mut(v, s).is_stop() {
1014 return VisitResult::Stop;
1015 }
1016 }
1017 }
1018 Statement::ClassDeclaration(node) => {
1019 if let Some(ref mut sc) = node.super_class {
1020 if walk_expression_mut(v, sc).is_stop() {
1021 return VisitResult::Stop;
1022 }
1023 }
1024 }
1025 Statement::WithStatement(node) => {
1026 if walk_expression_mut(v, &mut node.object).is_stop() {
1027 return VisitResult::Stop;
1028 }
1029 if walk_statement_mut(v, &mut node.body).is_stop() {
1030 return VisitResult::Stop;
1031 }
1032 }
1033 Statement::ExportNamedDeclaration(node) => {
1034 if let Some(ref mut decl) = node.declaration {
1035 if walk_declaration_mut(v, decl).is_stop() {
1036 return VisitResult::Stop;
1037 }
1038 }
1039 }
1040 Statement::ExportDefaultDeclaration(node) => {
1041 if walk_export_default_decl_mut(v, &mut node.declaration).is_stop() {
1042 return VisitResult::Stop;
1043 }
1044 }
1045 Statement::BreakStatement(_)
1047 | Statement::ContinueStatement(_)
1048 | Statement::EmptyStatement(_)
1049 | Statement::DebuggerStatement(_)
1050 | Statement::ImportDeclaration(_)
1051 | Statement::ExportAllDeclaration(_)
1052 | Statement::TSTypeAliasDeclaration(_)
1053 | Statement::TSInterfaceDeclaration(_)
1054 | Statement::TSEnumDeclaration(_)
1055 | Statement::TSModuleDeclaration(_)
1056 | Statement::TSDeclareFunction(_)
1057 | Statement::TypeAlias(_)
1058 | Statement::OpaqueType(_)
1059 | Statement::InterfaceDeclaration(_)
1060 | Statement::DeclareVariable(_)
1061 | Statement::DeclareFunction(_)
1062 | Statement::DeclareClass(_)
1063 | Statement::DeclareModule(_)
1064 | Statement::DeclareModuleExports(_)
1065 | Statement::DeclareExportDeclaration(_)
1066 | Statement::DeclareExportAllDeclaration(_)
1067 | Statement::DeclareInterface(_)
1068 | Statement::DeclareTypeAlias(_)
1069 | Statement::DeclareOpaqueType(_)
1070 | Statement::EnumDeclaration(_) => {}
1071 }
1072 VisitResult::Continue
1073}
1074
1075pub fn walk_expression_mut(v: &mut impl MutVisitor, expr: &mut Expression) -> VisitResult {
1077 if v.visit_expression(expr).is_stop() {
1078 return VisitResult::Stop;
1079 }
1080 match expr {
1081 Expression::Identifier(node) => {
1082 if v.visit_identifier(node).is_stop() {
1083 return VisitResult::Stop;
1084 }
1085 }
1086 Expression::CallExpression(node) => {
1087 if walk_expression_mut(v, &mut node.callee).is_stop() {
1088 return VisitResult::Stop;
1089 }
1090 for arg in node.arguments.iter_mut() {
1091 if walk_expression_mut(v, arg).is_stop() {
1092 return VisitResult::Stop;
1093 }
1094 }
1095 }
1096 Expression::MemberExpression(node) => {
1097 if walk_expression_mut(v, &mut node.object).is_stop() {
1098 return VisitResult::Stop;
1099 }
1100 if node.computed {
1101 if walk_expression_mut(v, &mut node.property).is_stop() {
1102 return VisitResult::Stop;
1103 }
1104 }
1105 }
1106 Expression::OptionalCallExpression(node) => {
1107 if walk_expression_mut(v, &mut node.callee).is_stop() {
1108 return VisitResult::Stop;
1109 }
1110 for arg in node.arguments.iter_mut() {
1111 if walk_expression_mut(v, arg).is_stop() {
1112 return VisitResult::Stop;
1113 }
1114 }
1115 }
1116 Expression::OptionalMemberExpression(node) => {
1117 if walk_expression_mut(v, &mut node.object).is_stop() {
1118 return VisitResult::Stop;
1119 }
1120 if node.computed {
1121 if walk_expression_mut(v, &mut node.property).is_stop() {
1122 return VisitResult::Stop;
1123 }
1124 }
1125 }
1126 Expression::BinaryExpression(node) => {
1127 if walk_expression_mut(v, &mut node.left).is_stop() {
1128 return VisitResult::Stop;
1129 }
1130 if walk_expression_mut(v, &mut node.right).is_stop() {
1131 return VisitResult::Stop;
1132 }
1133 }
1134 Expression::LogicalExpression(node) => {
1135 if walk_expression_mut(v, &mut node.left).is_stop() {
1136 return VisitResult::Stop;
1137 }
1138 if walk_expression_mut(v, &mut node.right).is_stop() {
1139 return VisitResult::Stop;
1140 }
1141 }
1142 Expression::UnaryExpression(node) => {
1143 if walk_expression_mut(v, &mut node.argument).is_stop() {
1144 return VisitResult::Stop;
1145 }
1146 }
1147 Expression::UpdateExpression(node) => {
1148 if walk_expression_mut(v, &mut node.argument).is_stop() {
1149 return VisitResult::Stop;
1150 }
1151 }
1152 Expression::ConditionalExpression(node) => {
1153 if walk_expression_mut(v, &mut node.test).is_stop() {
1154 return VisitResult::Stop;
1155 }
1156 if walk_expression_mut(v, &mut node.consequent).is_stop() {
1157 return VisitResult::Stop;
1158 }
1159 if walk_expression_mut(v, &mut node.alternate).is_stop() {
1160 return VisitResult::Stop;
1161 }
1162 }
1163 Expression::AssignmentExpression(node) => {
1164 if walk_expression_mut(v, &mut node.right).is_stop() {
1165 return VisitResult::Stop;
1166 }
1167 }
1168 Expression::SequenceExpression(node) => {
1169 for e in node.expressions.iter_mut() {
1170 if walk_expression_mut(v, e).is_stop() {
1171 return VisitResult::Stop;
1172 }
1173 }
1174 }
1175 Expression::ArrowFunctionExpression(node) => match node.body.as_mut() {
1176 ArrowFunctionBody::BlockStatement(block) => {
1177 for s in block.body.iter_mut() {
1178 if walk_statement_mut(v, s).is_stop() {
1179 return VisitResult::Stop;
1180 }
1181 }
1182 }
1183 ArrowFunctionBody::Expression(e) => {
1184 if walk_expression_mut(v, e).is_stop() {
1185 return VisitResult::Stop;
1186 }
1187 }
1188 },
1189 Expression::FunctionExpression(node) => {
1190 for s in node.body.body.iter_mut() {
1191 if walk_statement_mut(v, s).is_stop() {
1192 return VisitResult::Stop;
1193 }
1194 }
1195 }
1196 Expression::ObjectExpression(node) => {
1197 for prop in node.properties.iter_mut() {
1198 match prop {
1199 ObjectExpressionProperty::ObjectProperty(p) => {
1200 if p.computed {
1201 if walk_expression_mut(v, &mut p.key).is_stop() {
1202 return VisitResult::Stop;
1203 }
1204 }
1205 if walk_expression_mut(v, &mut p.value).is_stop() {
1206 return VisitResult::Stop;
1207 }
1208 }
1209 ObjectExpressionProperty::ObjectMethod(m) => {
1210 for s in m.body.body.iter_mut() {
1211 if walk_statement_mut(v, s).is_stop() {
1212 return VisitResult::Stop;
1213 }
1214 }
1215 }
1216 ObjectExpressionProperty::SpreadElement(s) => {
1217 if walk_expression_mut(v, &mut s.argument).is_stop() {
1218 return VisitResult::Stop;
1219 }
1220 }
1221 }
1222 }
1223 }
1224 Expression::ArrayExpression(node) => {
1225 for elem in node.elements.iter_mut().flatten() {
1226 if walk_expression_mut(v, elem).is_stop() {
1227 return VisitResult::Stop;
1228 }
1229 }
1230 }
1231 Expression::NewExpression(node) => {
1232 if walk_expression_mut(v, &mut node.callee).is_stop() {
1233 return VisitResult::Stop;
1234 }
1235 for arg in node.arguments.iter_mut() {
1236 if walk_expression_mut(v, arg).is_stop() {
1237 return VisitResult::Stop;
1238 }
1239 }
1240 }
1241 Expression::TemplateLiteral(node) => {
1242 for e in node.expressions.iter_mut() {
1243 if walk_expression_mut(v, e).is_stop() {
1244 return VisitResult::Stop;
1245 }
1246 }
1247 }
1248 Expression::TaggedTemplateExpression(node) => {
1249 if walk_expression_mut(v, &mut node.tag).is_stop() {
1250 return VisitResult::Stop;
1251 }
1252 for e in node.quasi.expressions.iter_mut() {
1253 if walk_expression_mut(v, e).is_stop() {
1254 return VisitResult::Stop;
1255 }
1256 }
1257 }
1258 Expression::AwaitExpression(node) => {
1259 if walk_expression_mut(v, &mut node.argument).is_stop() {
1260 return VisitResult::Stop;
1261 }
1262 }
1263 Expression::YieldExpression(node) => {
1264 if let Some(ref mut arg) = node.argument {
1265 if walk_expression_mut(v, arg).is_stop() {
1266 return VisitResult::Stop;
1267 }
1268 }
1269 }
1270 Expression::SpreadElement(node) => {
1271 if walk_expression_mut(v, &mut node.argument).is_stop() {
1272 return VisitResult::Stop;
1273 }
1274 }
1275 Expression::ParenthesizedExpression(node) => {
1276 if walk_expression_mut(v, &mut node.expression).is_stop() {
1277 return VisitResult::Stop;
1278 }
1279 }
1280 Expression::AssignmentPattern(node) => {
1281 if walk_expression_mut(v, &mut node.right).is_stop() {
1282 return VisitResult::Stop;
1283 }
1284 }
1285 Expression::ClassExpression(node) => {
1286 if let Some(ref mut sc) = node.super_class {
1287 if walk_expression_mut(v, sc).is_stop() {
1288 return VisitResult::Stop;
1289 }
1290 }
1291 }
1292 Expression::JSXElement(node) => {
1293 if walk_jsx_mut(v, &mut node.opening_element.attributes, &mut node.children).is_stop() {
1294 return VisitResult::Stop;
1295 }
1296 }
1297 Expression::JSXFragment(node) => {
1298 if walk_jsx_children_mut(v, &mut node.children).is_stop() {
1299 return VisitResult::Stop;
1300 }
1301 }
1302 Expression::TSAsExpression(node) => {
1304 if walk_expression_mut(v, &mut node.expression).is_stop() {
1305 return VisitResult::Stop;
1306 }
1307 }
1308 Expression::TSSatisfiesExpression(node) => {
1309 if walk_expression_mut(v, &mut node.expression).is_stop() {
1310 return VisitResult::Stop;
1311 }
1312 }
1313 Expression::TSNonNullExpression(node) => {
1314 if walk_expression_mut(v, &mut node.expression).is_stop() {
1315 return VisitResult::Stop;
1316 }
1317 }
1318 Expression::TSTypeAssertion(node) => {
1319 if walk_expression_mut(v, &mut node.expression).is_stop() {
1320 return VisitResult::Stop;
1321 }
1322 }
1323 Expression::TSInstantiationExpression(node) => {
1324 if walk_expression_mut(v, &mut node.expression).is_stop() {
1325 return VisitResult::Stop;
1326 }
1327 }
1328 Expression::TypeCastExpression(node) => {
1329 if walk_expression_mut(v, &mut node.expression).is_stop() {
1330 return VisitResult::Stop;
1331 }
1332 }
1333 Expression::StringLiteral(_)
1335 | Expression::NumericLiteral(_)
1336 | Expression::BooleanLiteral(_)
1337 | Expression::NullLiteral(_)
1338 | Expression::BigIntLiteral(_)
1339 | Expression::RegExpLiteral(_)
1340 | Expression::MetaProperty(_)
1341 | Expression::PrivateName(_)
1342 | Expression::Super(_)
1343 | Expression::Import(_)
1344 | Expression::ThisExpression(_) => {}
1345 }
1346 VisitResult::Continue
1347}
1348
1349fn walk_jsx_mut(
1350 v: &mut impl MutVisitor,
1351 attrs: &mut [crate::jsx::JSXAttributeItem],
1352 children: &mut [crate::jsx::JSXChild],
1353) -> VisitResult {
1354 for attr in attrs.iter_mut() {
1355 match attr {
1356 crate::jsx::JSXAttributeItem::JSXAttribute(a) => {
1357 if let Some(ref mut val) = a.value {
1358 match val {
1359 crate::jsx::JSXAttributeValue::JSXExpressionContainer(c) => {
1360 if let crate::jsx::JSXExpressionContainerExpr::Expression(ref mut e) =
1361 c.expression
1362 {
1363 if walk_expression_mut(v, e).is_stop() {
1364 return VisitResult::Stop;
1365 }
1366 }
1367 }
1368 _ => {}
1369 }
1370 }
1371 }
1372 crate::jsx::JSXAttributeItem::JSXSpreadAttribute(s) => {
1373 if walk_expression_mut(v, &mut s.argument).is_stop() {
1374 return VisitResult::Stop;
1375 }
1376 }
1377 }
1378 }
1379 walk_jsx_children_mut(v, children)
1380}
1381
1382fn walk_jsx_children_mut(
1383 v: &mut impl MutVisitor,
1384 children: &mut [crate::jsx::JSXChild],
1385) -> VisitResult {
1386 for child in children.iter_mut() {
1387 match child {
1388 crate::jsx::JSXChild::JSXElement(el) => {
1389 if walk_jsx_mut(v, &mut el.opening_element.attributes, &mut el.children).is_stop() {
1390 return VisitResult::Stop;
1391 }
1392 }
1393 crate::jsx::JSXChild::JSXFragment(f) => {
1394 if walk_jsx_children_mut(v, &mut f.children).is_stop() {
1395 return VisitResult::Stop;
1396 }
1397 }
1398 crate::jsx::JSXChild::JSXExpressionContainer(c) => {
1399 if let crate::jsx::JSXExpressionContainerExpr::Expression(ref mut e) = c.expression
1400 {
1401 if walk_expression_mut(v, e).is_stop() {
1402 return VisitResult::Stop;
1403 }
1404 }
1405 }
1406 crate::jsx::JSXChild::JSXSpreadChild(s) => {
1407 if walk_expression_mut(v, &mut s.expression).is_stop() {
1408 return VisitResult::Stop;
1409 }
1410 }
1411 _ => {}
1412 }
1413 }
1414 VisitResult::Continue
1415}
1416
1417fn walk_variable_declaration_mut(
1420 v: &mut impl MutVisitor,
1421 decl: &mut VariableDeclaration,
1422) -> VisitResult {
1423 for declarator in decl.declarations.iter_mut() {
1424 if let Some(ref mut init) = declarator.init {
1425 if walk_expression_mut(v, init).is_stop() {
1426 return VisitResult::Stop;
1427 }
1428 }
1429 }
1430 VisitResult::Continue
1431}
1432
1433fn walk_declaration_mut(v: &mut impl MutVisitor, decl: &mut Declaration) -> VisitResult {
1434 match decl {
1435 Declaration::FunctionDeclaration(node) => {
1436 for s in node.body.body.iter_mut() {
1437 if walk_statement_mut(v, s).is_stop() {
1438 return VisitResult::Stop;
1439 }
1440 }
1441 }
1442 Declaration::VariableDeclaration(node) => {
1443 if walk_variable_declaration_mut(v, node).is_stop() {
1444 return VisitResult::Stop;
1445 }
1446 }
1447 Declaration::ClassDeclaration(node) => {
1448 if let Some(ref mut sc) = node.super_class {
1449 if walk_expression_mut(v, sc).is_stop() {
1450 return VisitResult::Stop;
1451 }
1452 }
1453 }
1454 _ => {}
1455 }
1456 VisitResult::Continue
1457}
1458
1459fn walk_export_default_decl_mut(
1460 v: &mut impl MutVisitor,
1461 decl: &mut ExportDefaultDecl,
1462) -> VisitResult {
1463 match decl {
1464 ExportDefaultDecl::FunctionDeclaration(node) => {
1465 for s in node.body.body.iter_mut() {
1466 if walk_statement_mut(v, s).is_stop() {
1467 return VisitResult::Stop;
1468 }
1469 }
1470 }
1471 ExportDefaultDecl::Expression(expr) => {
1472 if walk_expression_mut(v, expr).is_stop() {
1473 return VisitResult::Stop;
1474 }
1475 }
1476 ExportDefaultDecl::ClassDeclaration(node) => {
1477 if let Some(ref mut sc) = node.super_class {
1478 if walk_expression_mut(v, sc).is_stop() {
1479 return VisitResult::Stop;
1480 }
1481 }
1482 }
1483 ExportDefaultDecl::EnumDeclaration(_) => {
1484 }
1486 }
1487 VisitResult::Continue
1488}