• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_AST_AST_TRAVERSAL_VISITOR_H_
6 #define V8_AST_AST_TRAVERSAL_VISITOR_H_
7 
8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // ----------------------------------------------------------------------------
15 // Traversal visitor
16 // - fully traverses the entire AST.
17 //
18 // Sub-class should parametrize AstTraversalVisitor with itself, e.g.:
19 //   class SpecificVisitor : public AstTraversalVisitor<SpecificVisitor> { ... }
20 //
21 // It invokes VisitNode on each AST node, before proceeding with its subtrees.
22 // It invokes VisitExpression (after VisitNode) on each AST node that is an
23 // expression, before proceeding with its subtrees.
24 // It proceeds with the subtrees only if these two methods return true.
25 // Sub-classes may override VisitNode and VisitExpressions, whose implementation
26 // is dummy here.  Or they may override the specific Visit* methods.
27 
28 template <class Subclass>
29 class AstTraversalVisitor : public AstVisitor<Subclass> {
30  public:
31   explicit AstTraversalVisitor(Isolate* isolate, AstNode* root = nullptr);
32   explicit AstTraversalVisitor(uintptr_t stack_limit, AstNode* root = nullptr);
33   AstTraversalVisitor(const AstTraversalVisitor&) = delete;
34   AstTraversalVisitor& operator=(const AstTraversalVisitor&) = delete;
35 
Run()36   void Run() {
37     DCHECK_NOT_NULL(root_);
38     Visit(root_);
39   }
40 
VisitNode(AstNode * node)41   bool VisitNode(AstNode* node) { return true; }
VisitExpression(Expression * node)42   bool VisitExpression(Expression* node) { return true; }
43 
44   // Iteration left-to-right.
45   void VisitDeclarations(Declaration::List* declarations);
46   void VisitStatements(const ZonePtrList<Statement>* statements);
47 
48 // Individual nodes
49 #define DECLARE_VISIT(type) void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)50   AST_NODE_LIST(DECLARE_VISIT)
51 #undef DECLARE_VISIT
52 
53  protected:
54   int depth() const { return depth_; }
55 
56  private:
57   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
58 
59   AstNode* root_;
60   int depth_;
61 };
62 
63 // ----------------------------------------------------------------------------
64 // Implementation of AstTraversalVisitor
65 
66 #define PROCESS_NODE(node) do {                         \
67     if (!(this->impl()->VisitNode(node))) return;       \
68   } while (false)
69 
70 #define PROCESS_EXPRESSION(node) do {                           \
71     PROCESS_NODE(node);                                         \
72     if (!(this->impl()->VisitExpression(node))) return;         \
73   } while (false)
74 
75 #define RECURSE(call)               \
76   do {                              \
77     DCHECK(!HasStackOverflow());    \
78     this->impl()->call;             \
79     if (HasStackOverflow()) return; \
80   } while (false)
81 
82 #define RECURSE_EXPRESSION(call)    \
83   do {                              \
84     DCHECK(!HasStackOverflow());    \
85     ++depth_;                       \
86     this->impl()->call;             \
87     --depth_;                       \
88     if (HasStackOverflow()) return; \
89   } while (false)
90 
91 template <class Subclass>
AstTraversalVisitor(Isolate * isolate,AstNode * root)92 AstTraversalVisitor<Subclass>::AstTraversalVisitor(Isolate* isolate,
93                                                    AstNode* root)
94     : root_(root), depth_(0) {
95   InitializeAstVisitor(isolate);
96 }
97 
98 template <class Subclass>
AstTraversalVisitor(uintptr_t stack_limit,AstNode * root)99 AstTraversalVisitor<Subclass>::AstTraversalVisitor(uintptr_t stack_limit,
100                                                    AstNode* root)
101     : root_(root), depth_(0) {
102   InitializeAstVisitor(stack_limit);
103 }
104 
105 template <class Subclass>
VisitDeclarations(Declaration::List * decls)106 void AstTraversalVisitor<Subclass>::VisitDeclarations(
107     Declaration::List* decls) {
108   for (Declaration* decl : *decls) {
109     RECURSE(Visit(decl));
110   }
111 }
112 
113 template <class Subclass>
VisitStatements(const ZonePtrList<Statement> * stmts)114 void AstTraversalVisitor<Subclass>::VisitStatements(
115     const ZonePtrList<Statement>* stmts) {
116   for (int i = 0; i < stmts->length(); ++i) {
117     Statement* stmt = stmts->at(i);
118     RECURSE(Visit(stmt));
119   }
120 }
121 
122 template <class Subclass>
VisitVariableDeclaration(VariableDeclaration * decl)123 void AstTraversalVisitor<Subclass>::VisitVariableDeclaration(
124     VariableDeclaration* decl) {
125   PROCESS_NODE(decl);
126 }
127 
128 template <class Subclass>
VisitFunctionDeclaration(FunctionDeclaration * decl)129 void AstTraversalVisitor<Subclass>::VisitFunctionDeclaration(
130     FunctionDeclaration* decl) {
131   PROCESS_NODE(decl);
132   RECURSE(Visit(decl->fun()));
133 }
134 
135 template <class Subclass>
VisitBlock(Block * stmt)136 void AstTraversalVisitor<Subclass>::VisitBlock(Block* stmt) {
137   PROCESS_NODE(stmt);
138   if (stmt->scope() != nullptr) {
139     RECURSE_EXPRESSION(VisitDeclarations(stmt->scope()->declarations()));
140   }
141   RECURSE(VisitStatements(stmt->statements()));
142 }
143 
144 template <class Subclass>
VisitExpressionStatement(ExpressionStatement * stmt)145 void AstTraversalVisitor<Subclass>::VisitExpressionStatement(
146     ExpressionStatement* stmt) {
147   PROCESS_NODE(stmt);
148   RECURSE(Visit(stmt->expression()));
149 }
150 
151 template <class Subclass>
VisitEmptyStatement(EmptyStatement * stmt)152 void AstTraversalVisitor<Subclass>::VisitEmptyStatement(EmptyStatement* stmt) {}
153 
154 template <class Subclass>
VisitSloppyBlockFunctionStatement(SloppyBlockFunctionStatement * stmt)155 void AstTraversalVisitor<Subclass>::VisitSloppyBlockFunctionStatement(
156     SloppyBlockFunctionStatement* stmt) {
157   PROCESS_NODE(stmt);
158   RECURSE(Visit(stmt->statement()));
159 }
160 
161 template <class Subclass>
VisitIfStatement(IfStatement * stmt)162 void AstTraversalVisitor<Subclass>::VisitIfStatement(IfStatement* stmt) {
163   PROCESS_NODE(stmt);
164   RECURSE(Visit(stmt->condition()));
165   RECURSE(Visit(stmt->then_statement()));
166   RECURSE(Visit(stmt->else_statement()));
167 }
168 
169 template <class Subclass>
VisitContinueStatement(ContinueStatement * stmt)170 void AstTraversalVisitor<Subclass>::VisitContinueStatement(
171     ContinueStatement* stmt) {
172   PROCESS_NODE(stmt);
173 }
174 
175 template <class Subclass>
VisitBreakStatement(BreakStatement * stmt)176 void AstTraversalVisitor<Subclass>::VisitBreakStatement(BreakStatement* stmt) {
177   PROCESS_NODE(stmt);
178 }
179 
180 template <class Subclass>
VisitReturnStatement(ReturnStatement * stmt)181 void AstTraversalVisitor<Subclass>::VisitReturnStatement(
182     ReturnStatement* stmt) {
183   PROCESS_NODE(stmt);
184   RECURSE(Visit(stmt->expression()));
185 }
186 
187 template <class Subclass>
VisitWithStatement(WithStatement * stmt)188 void AstTraversalVisitor<Subclass>::VisitWithStatement(WithStatement* stmt) {
189   PROCESS_NODE(stmt);
190   RECURSE(Visit(stmt->expression()));
191   RECURSE(Visit(stmt->statement()));
192 }
193 
194 template <class Subclass>
VisitSwitchStatement(SwitchStatement * stmt)195 void AstTraversalVisitor<Subclass>::VisitSwitchStatement(
196     SwitchStatement* stmt) {
197   PROCESS_NODE(stmt);
198   RECURSE(Visit(stmt->tag()));
199 
200   ZonePtrList<CaseClause>* clauses = stmt->cases();
201   for (int i = 0; i < clauses->length(); ++i) {
202     CaseClause* clause = clauses->at(i);
203     if (!clause->is_default()) {
204       Expression* label = clause->label();
205       RECURSE(Visit(label));
206     }
207     const ZonePtrList<Statement>* stmts = clause->statements();
208     RECURSE(VisitStatements(stmts));
209   }
210 }
211 
212 template <class Subclass>
VisitDoWhileStatement(DoWhileStatement * stmt)213 void AstTraversalVisitor<Subclass>::VisitDoWhileStatement(
214     DoWhileStatement* stmt) {
215   PROCESS_NODE(stmt);
216   RECURSE(Visit(stmt->body()));
217   RECURSE(Visit(stmt->cond()));
218 }
219 
220 template <class Subclass>
VisitWhileStatement(WhileStatement * stmt)221 void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) {
222   PROCESS_NODE(stmt);
223   RECURSE(Visit(stmt->cond()));
224   RECURSE(Visit(stmt->body()));
225 }
226 
227 template <class Subclass>
VisitForStatement(ForStatement * stmt)228 void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) {
229   PROCESS_NODE(stmt);
230   if (stmt->init() != nullptr) {
231     RECURSE(Visit(stmt->init()));
232   }
233   if (stmt->cond() != nullptr) {
234     RECURSE(Visit(stmt->cond()));
235   }
236   if (stmt->next() != nullptr) {
237     RECURSE(Visit(stmt->next()));
238   }
239   RECURSE(Visit(stmt->body()));
240 }
241 
242 template <class Subclass>
VisitForInStatement(ForInStatement * stmt)243 void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
244   PROCESS_NODE(stmt);
245   RECURSE(Visit(stmt->each()));
246   RECURSE(Visit(stmt->subject()));
247   RECURSE(Visit(stmt->body()));
248 }
249 
250 template <class Subclass>
VisitForOfStatement(ForOfStatement * stmt)251 void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* stmt) {
252   PROCESS_NODE(stmt);
253   RECURSE(Visit(stmt->each()));
254   RECURSE(Visit(stmt->subject()));
255   RECURSE(Visit(stmt->body()));
256 }
257 
258 template <class Subclass>
VisitTryCatchStatement(TryCatchStatement * stmt)259 void AstTraversalVisitor<Subclass>::VisitTryCatchStatement(
260     TryCatchStatement* stmt) {
261   PROCESS_NODE(stmt);
262   RECURSE(Visit(stmt->try_block()));
263   RECURSE(Visit(stmt->catch_block()));
264 }
265 
266 template <class Subclass>
VisitTryFinallyStatement(TryFinallyStatement * stmt)267 void AstTraversalVisitor<Subclass>::VisitTryFinallyStatement(
268     TryFinallyStatement* stmt) {
269   PROCESS_NODE(stmt);
270   RECURSE(Visit(stmt->try_block()));
271   RECURSE(Visit(stmt->finally_block()));
272 }
273 
274 template <class Subclass>
VisitDebuggerStatement(DebuggerStatement * stmt)275 void AstTraversalVisitor<Subclass>::VisitDebuggerStatement(
276     DebuggerStatement* stmt) {
277   PROCESS_NODE(stmt);
278 }
279 
280 template <class Subclass>
VisitFunctionLiteral(FunctionLiteral * expr)281 void AstTraversalVisitor<Subclass>::VisitFunctionLiteral(
282     FunctionLiteral* expr) {
283   PROCESS_EXPRESSION(expr);
284   DeclarationScope* scope = expr->scope();
285   RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
286   // A lazily parsed function literal won't have a body.
287   if (expr->scope()->was_lazily_parsed()) return;
288   RECURSE_EXPRESSION(VisitStatements(expr->body()));
289 }
290 
291 template <class Subclass>
VisitNativeFunctionLiteral(NativeFunctionLiteral * expr)292 void AstTraversalVisitor<Subclass>::VisitNativeFunctionLiteral(
293     NativeFunctionLiteral* expr) {
294   PROCESS_EXPRESSION(expr);
295 }
296 
297 template <class Subclass>
VisitConditional(Conditional * expr)298 void AstTraversalVisitor<Subclass>::VisitConditional(Conditional* expr) {
299   PROCESS_EXPRESSION(expr);
300   RECURSE_EXPRESSION(Visit(expr->condition()));
301   RECURSE_EXPRESSION(Visit(expr->then_expression()));
302   RECURSE_EXPRESSION(Visit(expr->else_expression()));
303 }
304 
305 template <class Subclass>
VisitVariableProxy(VariableProxy * expr)306 void AstTraversalVisitor<Subclass>::VisitVariableProxy(VariableProxy* expr) {
307   PROCESS_EXPRESSION(expr);
308 }
309 
310 template <class Subclass>
VisitLiteral(Literal * expr)311 void AstTraversalVisitor<Subclass>::VisitLiteral(Literal* expr) {
312   PROCESS_EXPRESSION(expr);
313 }
314 
315 template <class Subclass>
VisitRegExpLiteral(RegExpLiteral * expr)316 void AstTraversalVisitor<Subclass>::VisitRegExpLiteral(RegExpLiteral* expr) {
317   PROCESS_EXPRESSION(expr);
318 }
319 
320 template <class Subclass>
VisitObjectLiteral(ObjectLiteral * expr)321 void AstTraversalVisitor<Subclass>::VisitObjectLiteral(ObjectLiteral* expr) {
322   PROCESS_EXPRESSION(expr);
323   const ZonePtrList<ObjectLiteralProperty>* props = expr->properties();
324   for (int i = 0; i < props->length(); ++i) {
325     ObjectLiteralProperty* prop = props->at(i);
326     RECURSE_EXPRESSION(Visit(prop->key()));
327     RECURSE_EXPRESSION(Visit(prop->value()));
328   }
329 }
330 
331 template <class Subclass>
VisitArrayLiteral(ArrayLiteral * expr)332 void AstTraversalVisitor<Subclass>::VisitArrayLiteral(ArrayLiteral* expr) {
333   PROCESS_EXPRESSION(expr);
334   const ZonePtrList<Expression>* values = expr->values();
335   for (int i = 0; i < values->length(); ++i) {
336     Expression* value = values->at(i);
337     RECURSE_EXPRESSION(Visit(value));
338   }
339 }
340 
341 template <class Subclass>
VisitAssignment(Assignment * expr)342 void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
343   PROCESS_EXPRESSION(expr);
344   RECURSE_EXPRESSION(Visit(expr->target()));
345   RECURSE_EXPRESSION(Visit(expr->value()));
346 }
347 
348 template <class Subclass>
VisitCompoundAssignment(CompoundAssignment * expr)349 void AstTraversalVisitor<Subclass>::VisitCompoundAssignment(
350     CompoundAssignment* expr) {
351   VisitAssignment(expr);
352 }
353 
354 template <class Subclass>
VisitYield(Yield * expr)355 void AstTraversalVisitor<Subclass>::VisitYield(Yield* expr) {
356   PROCESS_EXPRESSION(expr);
357   RECURSE_EXPRESSION(Visit(expr->expression()));
358 }
359 
360 template <class Subclass>
VisitYieldStar(YieldStar * expr)361 void AstTraversalVisitor<Subclass>::VisitYieldStar(YieldStar* expr) {
362   PROCESS_EXPRESSION(expr);
363   RECURSE_EXPRESSION(Visit(expr->expression()));
364 }
365 
366 template <class Subclass>
VisitAwait(Await * expr)367 void AstTraversalVisitor<Subclass>::VisitAwait(Await* expr) {
368   PROCESS_EXPRESSION(expr);
369   RECURSE_EXPRESSION(Visit(expr->expression()));
370 }
371 
372 template <class Subclass>
VisitThrow(Throw * expr)373 void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
374   PROCESS_EXPRESSION(expr);
375   RECURSE_EXPRESSION(Visit(expr->exception()));
376 }
377 
378 template <class Subclass>
VisitOptionalChain(OptionalChain * expr)379 void AstTraversalVisitor<Subclass>::VisitOptionalChain(OptionalChain* expr) {
380   PROCESS_EXPRESSION(expr);
381   RECURSE_EXPRESSION(Visit(expr->expression()));
382 }
383 
384 template <class Subclass>
VisitProperty(Property * expr)385 void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
386   PROCESS_EXPRESSION(expr);
387   RECURSE_EXPRESSION(Visit(expr->obj()));
388   RECURSE_EXPRESSION(Visit(expr->key()));
389 }
390 
391 template <class Subclass>
VisitCall(Call * expr)392 void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
393   PROCESS_EXPRESSION(expr);
394   RECURSE_EXPRESSION(Visit(expr->expression()));
395   const ZonePtrList<Expression>* args = expr->arguments();
396   for (int i = 0; i < args->length(); ++i) {
397     Expression* arg = args->at(i);
398     RECURSE_EXPRESSION(Visit(arg));
399   }
400 }
401 
402 template <class Subclass>
VisitCallNew(CallNew * expr)403 void AstTraversalVisitor<Subclass>::VisitCallNew(CallNew* expr) {
404   PROCESS_EXPRESSION(expr);
405   RECURSE_EXPRESSION(Visit(expr->expression()));
406   const ZonePtrList<Expression>* args = expr->arguments();
407   for (int i = 0; i < args->length(); ++i) {
408     Expression* arg = args->at(i);
409     RECURSE_EXPRESSION(Visit(arg));
410   }
411 }
412 
413 template <class Subclass>
VisitCallRuntime(CallRuntime * expr)414 void AstTraversalVisitor<Subclass>::VisitCallRuntime(CallRuntime* expr) {
415   PROCESS_EXPRESSION(expr);
416   const ZonePtrList<Expression>* args = expr->arguments();
417   for (int i = 0; i < args->length(); ++i) {
418     Expression* arg = args->at(i);
419     RECURSE_EXPRESSION(Visit(arg));
420   }
421 }
422 
423 template <class Subclass>
VisitUnaryOperation(UnaryOperation * expr)424 void AstTraversalVisitor<Subclass>::VisitUnaryOperation(UnaryOperation* expr) {
425   PROCESS_EXPRESSION(expr);
426   RECURSE_EXPRESSION(Visit(expr->expression()));
427 }
428 
429 template <class Subclass>
VisitCountOperation(CountOperation * expr)430 void AstTraversalVisitor<Subclass>::VisitCountOperation(CountOperation* expr) {
431   PROCESS_EXPRESSION(expr);
432   RECURSE_EXPRESSION(Visit(expr->expression()));
433 }
434 
435 template <class Subclass>
VisitBinaryOperation(BinaryOperation * expr)436 void AstTraversalVisitor<Subclass>::VisitBinaryOperation(
437     BinaryOperation* expr) {
438   PROCESS_EXPRESSION(expr);
439   RECURSE_EXPRESSION(Visit(expr->left()));
440   RECURSE_EXPRESSION(Visit(expr->right()));
441 }
442 
443 template <class Subclass>
VisitNaryOperation(NaryOperation * expr)444 void AstTraversalVisitor<Subclass>::VisitNaryOperation(NaryOperation* expr) {
445   PROCESS_EXPRESSION(expr);
446   RECURSE_EXPRESSION(Visit(expr->first()));
447   for (size_t i = 0; i < expr->subsequent_length(); ++i) {
448     RECURSE_EXPRESSION(Visit(expr->subsequent(i)));
449   }
450 }
451 
452 template <class Subclass>
VisitCompareOperation(CompareOperation * expr)453 void AstTraversalVisitor<Subclass>::VisitCompareOperation(
454     CompareOperation* expr) {
455   PROCESS_EXPRESSION(expr);
456   RECURSE_EXPRESSION(Visit(expr->left()));
457   RECURSE_EXPRESSION(Visit(expr->right()));
458 }
459 
460 template <class Subclass>
VisitThisExpression(ThisExpression * expr)461 void AstTraversalVisitor<Subclass>::VisitThisExpression(ThisExpression* expr) {
462   PROCESS_EXPRESSION(expr);
463 }
464 
465 template <class Subclass>
VisitClassLiteral(ClassLiteral * expr)466 void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) {
467   PROCESS_EXPRESSION(expr);
468   if (expr->extends() != nullptr) {
469     RECURSE_EXPRESSION(Visit(expr->extends()));
470   }
471   RECURSE_EXPRESSION(Visit(expr->constructor()));
472   if (expr->static_initializer() != nullptr) {
473     RECURSE_EXPRESSION(Visit(expr->static_initializer()));
474   }
475   if (expr->instance_members_initializer_function() != nullptr) {
476     RECURSE_EXPRESSION(Visit(expr->instance_members_initializer_function()));
477   }
478   ZonePtrList<ClassLiteral::Property>* private_members =
479       expr->private_members();
480   for (int i = 0; i < private_members->length(); ++i) {
481     ClassLiteralProperty* prop = private_members->at(i);
482     RECURSE_EXPRESSION(Visit(prop->value()));
483   }
484   ZonePtrList<ClassLiteral::Property>* props = expr->public_members();
485   for (int i = 0; i < props->length(); ++i) {
486     ClassLiteralProperty* prop = props->at(i);
487     if (!prop->key()->IsLiteral()) {
488       RECURSE_EXPRESSION(Visit(prop->key()));
489     }
490     RECURSE_EXPRESSION(Visit(prop->value()));
491   }
492 }
493 
494 template <class Subclass>
VisitInitializeClassMembersStatement(InitializeClassMembersStatement * stmt)495 void AstTraversalVisitor<Subclass>::VisitInitializeClassMembersStatement(
496     InitializeClassMembersStatement* stmt) {
497   PROCESS_NODE(stmt);
498   ZonePtrList<ClassLiteral::Property>* props = stmt->fields();
499   for (int i = 0; i < props->length(); ++i) {
500     ClassLiteralProperty* prop = props->at(i);
501     if (!prop->key()->IsLiteral()) {
502       RECURSE(Visit(prop->key()));
503     }
504     RECURSE(Visit(prop->value()));
505   }
506 }
507 
508 template <class Subclass>
VisitInitializeClassStaticElementsStatement(InitializeClassStaticElementsStatement * stmt)509 void AstTraversalVisitor<Subclass>::VisitInitializeClassStaticElementsStatement(
510     InitializeClassStaticElementsStatement* stmt) {
511   PROCESS_NODE(stmt);
512   ZonePtrList<ClassLiteral::StaticElement>* elements = stmt->elements();
513   for (int i = 0; i < elements->length(); ++i) {
514     ClassLiteral::StaticElement* element = elements->at(i);
515     switch (element->kind()) {
516       case ClassLiteral::StaticElement::PROPERTY: {
517         ClassLiteral::Property* prop = element->property();
518         if (!prop->key()->IsLiteral()) {
519           RECURSE(Visit(prop->key()));
520         }
521         RECURSE(Visit(prop->value()));
522         break;
523       }
524       case ClassLiteral::StaticElement::STATIC_BLOCK:
525         RECURSE(Visit(element->static_block()));
526         break;
527     }
528   }
529 }
530 
531 template <class Subclass>
VisitSpread(Spread * expr)532 void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
533   PROCESS_EXPRESSION(expr);
534   RECURSE_EXPRESSION(Visit(expr->expression()));
535 }
536 
537 template <class Subclass>
VisitEmptyParentheses(EmptyParentheses * expr)538 void AstTraversalVisitor<Subclass>::VisitEmptyParentheses(
539     EmptyParentheses* expr) {
540   PROCESS_EXPRESSION(expr);
541 }
542 
543 template <class Subclass>
VisitGetTemplateObject(GetTemplateObject * expr)544 void AstTraversalVisitor<Subclass>::VisitGetTemplateObject(
545     GetTemplateObject* expr) {
546   PROCESS_EXPRESSION(expr);
547 }
548 
549 template <class Subclass>
VisitTemplateLiteral(TemplateLiteral * expr)550 void AstTraversalVisitor<Subclass>::VisitTemplateLiteral(
551     TemplateLiteral* expr) {
552   PROCESS_EXPRESSION(expr);
553   for (Expression* sub : *expr->substitutions()) {
554     RECURSE_EXPRESSION(Visit(sub));
555   }
556 }
557 
558 template <class Subclass>
VisitImportCallExpression(ImportCallExpression * expr)559 void AstTraversalVisitor<Subclass>::VisitImportCallExpression(
560     ImportCallExpression* expr) {
561   PROCESS_EXPRESSION(expr);
562   RECURSE_EXPRESSION(Visit(expr->specifier()));
563   if (expr->import_assertions()) {
564     RECURSE_EXPRESSION(Visit(expr->import_assertions()));
565   }
566 }
567 
568 template <class Subclass>
VisitSuperPropertyReference(SuperPropertyReference * expr)569 void AstTraversalVisitor<Subclass>::VisitSuperPropertyReference(
570     SuperPropertyReference* expr) {
571   PROCESS_EXPRESSION(expr);
572 }
573 
574 template <class Subclass>
VisitSuperCallReference(SuperCallReference * expr)575 void AstTraversalVisitor<Subclass>::VisitSuperCallReference(
576     SuperCallReference* expr) {
577   PROCESS_EXPRESSION(expr);
578   RECURSE_EXPRESSION(VisitVariableProxy(expr->new_target_var()));
579   RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var()));
580 }
581 
582 #undef PROCESS_NODE
583 #undef PROCESS_EXPRESSION
584 #undef RECURSE_EXPRESSION
585 #undef RECURSE
586 
587 }  // namespace internal
588 }  // namespace v8
589 
590 #endif  // V8_AST_AST_TRAVERSAL_VISITOR_H_
591