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 
Run()34   void Run() {
35     DCHECK_NOT_NULL(root_);
36     Visit(root_);
37   }
38 
VisitNode(AstNode * node)39   bool VisitNode(AstNode* node) { return true; }
VisitExpression(Expression * node)40   bool VisitExpression(Expression* node) { return true; }
41 
42   // Iteration left-to-right.
43   void VisitDeclarations(Declaration::List* declarations);
44   void VisitStatements(ZonePtrList<Statement>* statements);
45 
46 // Individual nodes
47 #define DECLARE_VISIT(type) void Visit##type(type* node);
AST_NODE_LIST(DECLARE_VISIT)48   AST_NODE_LIST(DECLARE_VISIT)
49 #undef DECLARE_VISIT
50 
51  protected:
52   int depth() const { return depth_; }
53 
54  private:
55   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
56 
57   AstNode* root_;
58   int depth_;
59 
60   DISALLOW_COPY_AND_ASSIGN(AstTraversalVisitor);
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(ZonePtrList<Statement> * stmts)114 void AstTraversalVisitor<Subclass>::VisitStatements(
115     ZonePtrList<Statement>* stmts) {
116   for (int i = 0; i < stmts->length(); ++i) {
117     Statement* stmt = stmts->at(i);
118     RECURSE(Visit(stmt));
119     if (stmt->IsJump()) break;
120   }
121 }
122 
123 template <class Subclass>
VisitVariableDeclaration(VariableDeclaration * decl)124 void AstTraversalVisitor<Subclass>::VisitVariableDeclaration(
125     VariableDeclaration* decl) {
126   PROCESS_NODE(decl);
127 }
128 
129 template <class Subclass>
VisitFunctionDeclaration(FunctionDeclaration * decl)130 void AstTraversalVisitor<Subclass>::VisitFunctionDeclaration(
131     FunctionDeclaration* decl) {
132   PROCESS_NODE(decl);
133   RECURSE(Visit(decl->fun()));
134 }
135 
136 template <class Subclass>
VisitBlock(Block * stmt)137 void AstTraversalVisitor<Subclass>::VisitBlock(Block* stmt) {
138   PROCESS_NODE(stmt);
139   if (stmt->scope() != nullptr) {
140     RECURSE_EXPRESSION(VisitDeclarations(stmt->scope()->declarations()));
141   }
142   RECURSE(VisitStatements(stmt->statements()));
143 }
144 
145 template <class Subclass>
VisitExpressionStatement(ExpressionStatement * stmt)146 void AstTraversalVisitor<Subclass>::VisitExpressionStatement(
147     ExpressionStatement* stmt) {
148   PROCESS_NODE(stmt);
149   RECURSE(Visit(stmt->expression()));
150 }
151 
152 template <class Subclass>
VisitEmptyStatement(EmptyStatement * stmt)153 void AstTraversalVisitor<Subclass>::VisitEmptyStatement(EmptyStatement* stmt) {}
154 
155 template <class Subclass>
VisitSloppyBlockFunctionStatement(SloppyBlockFunctionStatement * stmt)156 void AstTraversalVisitor<Subclass>::VisitSloppyBlockFunctionStatement(
157     SloppyBlockFunctionStatement* stmt) {
158   PROCESS_NODE(stmt);
159   RECURSE(Visit(stmt->statement()));
160 }
161 
162 template <class Subclass>
VisitIfStatement(IfStatement * stmt)163 void AstTraversalVisitor<Subclass>::VisitIfStatement(IfStatement* stmt) {
164   PROCESS_NODE(stmt);
165   RECURSE(Visit(stmt->condition()));
166   RECURSE(Visit(stmt->then_statement()));
167   RECURSE(Visit(stmt->else_statement()));
168 }
169 
170 template <class Subclass>
VisitContinueStatement(ContinueStatement * stmt)171 void AstTraversalVisitor<Subclass>::VisitContinueStatement(
172     ContinueStatement* stmt) {
173   PROCESS_NODE(stmt);
174 }
175 
176 template <class Subclass>
VisitBreakStatement(BreakStatement * stmt)177 void AstTraversalVisitor<Subclass>::VisitBreakStatement(BreakStatement* stmt) {
178   PROCESS_NODE(stmt);
179 }
180 
181 template <class Subclass>
VisitReturnStatement(ReturnStatement * stmt)182 void AstTraversalVisitor<Subclass>::VisitReturnStatement(
183     ReturnStatement* stmt) {
184   PROCESS_NODE(stmt);
185   RECURSE(Visit(stmt->expression()));
186 }
187 
188 template <class Subclass>
VisitWithStatement(WithStatement * stmt)189 void AstTraversalVisitor<Subclass>::VisitWithStatement(WithStatement* stmt) {
190   PROCESS_NODE(stmt);
191   RECURSE(Visit(stmt->expression()));
192   RECURSE(Visit(stmt->statement()));
193 }
194 
195 template <class Subclass>
VisitSwitchStatement(SwitchStatement * stmt)196 void AstTraversalVisitor<Subclass>::VisitSwitchStatement(
197     SwitchStatement* stmt) {
198   PROCESS_NODE(stmt);
199   RECURSE(Visit(stmt->tag()));
200 
201   ZonePtrList<CaseClause>* clauses = stmt->cases();
202   for (int i = 0; i < clauses->length(); ++i) {
203     CaseClause* clause = clauses->at(i);
204     if (!clause->is_default()) {
205       Expression* label = clause->label();
206       RECURSE(Visit(label));
207     }
208     ZonePtrList<Statement>* stmts = clause->statements();
209     RECURSE(VisitStatements(stmts));
210   }
211 }
212 
213 template <class Subclass>
VisitDoWhileStatement(DoWhileStatement * stmt)214 void AstTraversalVisitor<Subclass>::VisitDoWhileStatement(
215     DoWhileStatement* stmt) {
216   PROCESS_NODE(stmt);
217   RECURSE(Visit(stmt->body()));
218   RECURSE(Visit(stmt->cond()));
219 }
220 
221 template <class Subclass>
VisitWhileStatement(WhileStatement * stmt)222 void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) {
223   PROCESS_NODE(stmt);
224   RECURSE(Visit(stmt->cond()));
225   RECURSE(Visit(stmt->body()));
226 }
227 
228 template <class Subclass>
VisitForStatement(ForStatement * stmt)229 void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) {
230   PROCESS_NODE(stmt);
231   if (stmt->init() != nullptr) {
232     RECURSE(Visit(stmt->init()));
233   }
234   if (stmt->cond() != nullptr) {
235     RECURSE(Visit(stmt->cond()));
236   }
237   if (stmt->next() != nullptr) {
238     RECURSE(Visit(stmt->next()));
239   }
240   RECURSE(Visit(stmt->body()));
241 }
242 
243 template <class Subclass>
VisitForInStatement(ForInStatement * stmt)244 void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
245   PROCESS_NODE(stmt);
246   RECURSE(Visit(stmt->each()));
247   RECURSE(Visit(stmt->enumerable()));
248   RECURSE(Visit(stmt->body()));
249 }
250 
251 template <class Subclass>
VisitForOfStatement(ForOfStatement * stmt)252 void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* stmt) {
253   PROCESS_NODE(stmt);
254   RECURSE(Visit(stmt->assign_iterator()));
255   RECURSE(Visit(stmt->next_result()));
256   RECURSE(Visit(stmt->result_done()));
257   RECURSE(Visit(stmt->assign_each()));
258   RECURSE(Visit(stmt->body()));
259 }
260 
261 template <class Subclass>
VisitTryCatchStatement(TryCatchStatement * stmt)262 void AstTraversalVisitor<Subclass>::VisitTryCatchStatement(
263     TryCatchStatement* stmt) {
264   PROCESS_NODE(stmt);
265   RECURSE(Visit(stmt->try_block()));
266   RECURSE(Visit(stmt->catch_block()));
267 }
268 
269 template <class Subclass>
VisitTryFinallyStatement(TryFinallyStatement * stmt)270 void AstTraversalVisitor<Subclass>::VisitTryFinallyStatement(
271     TryFinallyStatement* stmt) {
272   PROCESS_NODE(stmt);
273   RECURSE(Visit(stmt->try_block()));
274   RECURSE(Visit(stmt->finally_block()));
275 }
276 
277 template <class Subclass>
VisitDebuggerStatement(DebuggerStatement * stmt)278 void AstTraversalVisitor<Subclass>::VisitDebuggerStatement(
279     DebuggerStatement* stmt) {
280   PROCESS_NODE(stmt);
281 }
282 
283 template <class Subclass>
VisitFunctionLiteral(FunctionLiteral * expr)284 void AstTraversalVisitor<Subclass>::VisitFunctionLiteral(
285     FunctionLiteral* expr) {
286   PROCESS_EXPRESSION(expr);
287   DeclarationScope* scope = expr->scope();
288   RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
289   // A lazily parsed function literal won't have a body.
290   if (expr->scope()->was_lazily_parsed()) return;
291   RECURSE_EXPRESSION(VisitStatements(expr->body()));
292 }
293 
294 template <class Subclass>
VisitNativeFunctionLiteral(NativeFunctionLiteral * expr)295 void AstTraversalVisitor<Subclass>::VisitNativeFunctionLiteral(
296     NativeFunctionLiteral* expr) {
297   PROCESS_EXPRESSION(expr);
298 }
299 
300 template <class Subclass>
VisitDoExpression(DoExpression * expr)301 void AstTraversalVisitor<Subclass>::VisitDoExpression(DoExpression* expr) {
302   PROCESS_EXPRESSION(expr);
303   RECURSE(VisitBlock(expr->block()));
304   RECURSE(VisitVariableProxy(expr->result()));
305 }
306 
307 template <class Subclass>
VisitConditional(Conditional * expr)308 void AstTraversalVisitor<Subclass>::VisitConditional(Conditional* expr) {
309   PROCESS_EXPRESSION(expr);
310   RECURSE_EXPRESSION(Visit(expr->condition()));
311   RECURSE_EXPRESSION(Visit(expr->then_expression()));
312   RECURSE_EXPRESSION(Visit(expr->else_expression()));
313 }
314 
315 template <class Subclass>
VisitVariableProxy(VariableProxy * expr)316 void AstTraversalVisitor<Subclass>::VisitVariableProxy(VariableProxy* expr) {
317   PROCESS_EXPRESSION(expr);
318 }
319 
320 template <class Subclass>
VisitLiteral(Literal * expr)321 void AstTraversalVisitor<Subclass>::VisitLiteral(Literal* expr) {
322   PROCESS_EXPRESSION(expr);
323 }
324 
325 template <class Subclass>
VisitRegExpLiteral(RegExpLiteral * expr)326 void AstTraversalVisitor<Subclass>::VisitRegExpLiteral(RegExpLiteral* expr) {
327   PROCESS_EXPRESSION(expr);
328 }
329 
330 template <class Subclass>
VisitObjectLiteral(ObjectLiteral * expr)331 void AstTraversalVisitor<Subclass>::VisitObjectLiteral(ObjectLiteral* expr) {
332   PROCESS_EXPRESSION(expr);
333   ZonePtrList<ObjectLiteralProperty>* props = expr->properties();
334   for (int i = 0; i < props->length(); ++i) {
335     ObjectLiteralProperty* prop = props->at(i);
336     RECURSE_EXPRESSION(Visit(prop->key()));
337     RECURSE_EXPRESSION(Visit(prop->value()));
338   }
339 }
340 
341 template <class Subclass>
VisitArrayLiteral(ArrayLiteral * expr)342 void AstTraversalVisitor<Subclass>::VisitArrayLiteral(ArrayLiteral* expr) {
343   PROCESS_EXPRESSION(expr);
344   ZonePtrList<Expression>* values = expr->values();
345   for (int i = 0; i < values->length(); ++i) {
346     Expression* value = values->at(i);
347     RECURSE_EXPRESSION(Visit(value));
348   }
349 }
350 
351 template <class Subclass>
VisitAssignment(Assignment * expr)352 void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
353   PROCESS_EXPRESSION(expr);
354   RECURSE_EXPRESSION(Visit(expr->target()));
355   RECURSE_EXPRESSION(Visit(expr->value()));
356 }
357 
358 template <class Subclass>
VisitCompoundAssignment(CompoundAssignment * expr)359 void AstTraversalVisitor<Subclass>::VisitCompoundAssignment(
360     CompoundAssignment* expr) {
361   VisitAssignment(expr);
362 }
363 
364 template <class Subclass>
VisitYield(Yield * expr)365 void AstTraversalVisitor<Subclass>::VisitYield(Yield* expr) {
366   PROCESS_EXPRESSION(expr);
367   RECURSE_EXPRESSION(Visit(expr->expression()));
368 }
369 
370 template <class Subclass>
VisitYieldStar(YieldStar * expr)371 void AstTraversalVisitor<Subclass>::VisitYieldStar(YieldStar* expr) {
372   PROCESS_EXPRESSION(expr);
373   RECURSE_EXPRESSION(Visit(expr->expression()));
374 }
375 
376 template <class Subclass>
VisitAwait(Await * expr)377 void AstTraversalVisitor<Subclass>::VisitAwait(Await* expr) {
378   PROCESS_EXPRESSION(expr);
379   RECURSE_EXPRESSION(Visit(expr->expression()));
380 }
381 
382 template <class Subclass>
VisitThrow(Throw * expr)383 void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
384   PROCESS_EXPRESSION(expr);
385   RECURSE_EXPRESSION(Visit(expr->exception()));
386 }
387 
388 template <class Subclass>
VisitProperty(Property * expr)389 void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
390   PROCESS_EXPRESSION(expr);
391   RECURSE_EXPRESSION(Visit(expr->obj()));
392   RECURSE_EXPRESSION(Visit(expr->key()));
393 }
394 
395 template <class Subclass>
VisitResolvedProperty(ResolvedProperty * expr)396 void AstTraversalVisitor<Subclass>::VisitResolvedProperty(
397     ResolvedProperty* expr) {
398   PROCESS_EXPRESSION(expr);
399   RECURSE_EXPRESSION(VisitVariableProxy(expr->object()));
400   RECURSE_EXPRESSION(VisitVariableProxy(expr->property()));
401 }
402 
403 template <class Subclass>
VisitCall(Call * expr)404 void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
405   PROCESS_EXPRESSION(expr);
406   RECURSE_EXPRESSION(Visit(expr->expression()));
407   ZonePtrList<Expression>* args = expr->arguments();
408   for (int i = 0; i < args->length(); ++i) {
409     Expression* arg = args->at(i);
410     RECURSE_EXPRESSION(Visit(arg));
411   }
412 }
413 
414 template <class Subclass>
VisitCallNew(CallNew * expr)415 void AstTraversalVisitor<Subclass>::VisitCallNew(CallNew* expr) {
416   PROCESS_EXPRESSION(expr);
417   RECURSE_EXPRESSION(Visit(expr->expression()));
418   ZonePtrList<Expression>* args = expr->arguments();
419   for (int i = 0; i < args->length(); ++i) {
420     Expression* arg = args->at(i);
421     RECURSE_EXPRESSION(Visit(arg));
422   }
423 }
424 
425 template <class Subclass>
VisitCallRuntime(CallRuntime * expr)426 void AstTraversalVisitor<Subclass>::VisitCallRuntime(CallRuntime* expr) {
427   PROCESS_EXPRESSION(expr);
428   ZonePtrList<Expression>* args = expr->arguments();
429   for (int i = 0; i < args->length(); ++i) {
430     Expression* arg = args->at(i);
431     RECURSE_EXPRESSION(Visit(arg));
432   }
433 }
434 
435 template <class Subclass>
VisitUnaryOperation(UnaryOperation * expr)436 void AstTraversalVisitor<Subclass>::VisitUnaryOperation(UnaryOperation* expr) {
437   PROCESS_EXPRESSION(expr);
438   RECURSE_EXPRESSION(Visit(expr->expression()));
439 }
440 
441 template <class Subclass>
VisitCountOperation(CountOperation * expr)442 void AstTraversalVisitor<Subclass>::VisitCountOperation(CountOperation* expr) {
443   PROCESS_EXPRESSION(expr);
444   RECURSE_EXPRESSION(Visit(expr->expression()));
445 }
446 
447 template <class Subclass>
VisitBinaryOperation(BinaryOperation * expr)448 void AstTraversalVisitor<Subclass>::VisitBinaryOperation(
449     BinaryOperation* expr) {
450   PROCESS_EXPRESSION(expr);
451   RECURSE_EXPRESSION(Visit(expr->left()));
452   RECURSE_EXPRESSION(Visit(expr->right()));
453 }
454 
455 template <class Subclass>
VisitNaryOperation(NaryOperation * expr)456 void AstTraversalVisitor<Subclass>::VisitNaryOperation(NaryOperation* expr) {
457   PROCESS_EXPRESSION(expr);
458   RECURSE_EXPRESSION(Visit(expr->first()));
459   for (size_t i = 0; i < expr->subsequent_length(); ++i) {
460     RECURSE_EXPRESSION(Visit(expr->subsequent(i)));
461   }
462 }
463 
464 template <class Subclass>
VisitCompareOperation(CompareOperation * expr)465 void AstTraversalVisitor<Subclass>::VisitCompareOperation(
466     CompareOperation* expr) {
467   PROCESS_EXPRESSION(expr);
468   RECURSE_EXPRESSION(Visit(expr->left()));
469   RECURSE_EXPRESSION(Visit(expr->right()));
470 }
471 
472 template <class Subclass>
VisitThisFunction(ThisFunction * expr)473 void AstTraversalVisitor<Subclass>::VisitThisFunction(ThisFunction* expr) {
474   PROCESS_EXPRESSION(expr);
475 }
476 
477 template <class Subclass>
VisitClassLiteral(ClassLiteral * expr)478 void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) {
479   PROCESS_EXPRESSION(expr);
480   if (expr->extends() != nullptr) {
481     RECURSE_EXPRESSION(Visit(expr->extends()));
482   }
483   RECURSE_EXPRESSION(Visit(expr->constructor()));
484   if (expr->static_fields_initializer() != nullptr) {
485     RECURSE_EXPRESSION(Visit(expr->static_fields_initializer()));
486   }
487   if (expr->instance_fields_initializer_function() != nullptr) {
488     RECURSE_EXPRESSION(Visit(expr->instance_fields_initializer_function()));
489   }
490   ZonePtrList<ClassLiteral::Property>* props = expr->properties();
491   for (int i = 0; i < props->length(); ++i) {
492     ClassLiteralProperty* prop = props->at(i);
493     if (!prop->key()->IsLiteral()) {
494       RECURSE_EXPRESSION(Visit(prop->key()));
495     }
496     RECURSE_EXPRESSION(Visit(prop->value()));
497   }
498 }
499 
500 template <class Subclass>
VisitInitializeClassFieldsStatement(InitializeClassFieldsStatement * stmt)501 void AstTraversalVisitor<Subclass>::VisitInitializeClassFieldsStatement(
502     InitializeClassFieldsStatement* stmt) {
503   PROCESS_NODE(stmt);
504   ZonePtrList<ClassLiteral::Property>* props = stmt->fields();
505   for (int i = 0; i < props->length(); ++i) {
506     ClassLiteralProperty* prop = props->at(i);
507     if (!prop->key()->IsLiteral()) {
508       RECURSE(Visit(prop->key()));
509     }
510     RECURSE(Visit(prop->value()));
511   }
512 }
513 
514 template <class Subclass>
VisitSpread(Spread * expr)515 void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
516   PROCESS_EXPRESSION(expr);
517   RECURSE_EXPRESSION(Visit(expr->expression()));
518 }
519 
520 template <class Subclass>
VisitStoreInArrayLiteral(StoreInArrayLiteral * expr)521 void AstTraversalVisitor<Subclass>::VisitStoreInArrayLiteral(
522     StoreInArrayLiteral* expr) {
523   PROCESS_EXPRESSION(expr);
524   RECURSE_EXPRESSION(Visit(expr->array()));
525   RECURSE_EXPRESSION(Visit(expr->index()));
526   RECURSE_EXPRESSION(Visit(expr->value()));
527 }
528 
529 template <class Subclass>
VisitEmptyParentheses(EmptyParentheses * expr)530 void AstTraversalVisitor<Subclass>::VisitEmptyParentheses(
531     EmptyParentheses* expr) {
532   PROCESS_EXPRESSION(expr);
533 }
534 
535 template <class Subclass>
VisitGetIterator(GetIterator * expr)536 void AstTraversalVisitor<Subclass>::VisitGetIterator(GetIterator* expr) {
537   PROCESS_EXPRESSION(expr);
538   RECURSE_EXPRESSION(Visit(expr->iterable()));
539 }
540 
541 template <class Subclass>
VisitGetTemplateObject(GetTemplateObject * expr)542 void AstTraversalVisitor<Subclass>::VisitGetTemplateObject(
543     GetTemplateObject* expr) {
544   PROCESS_EXPRESSION(expr);
545 }
546 
547 template <class Subclass>
VisitTemplateLiteral(TemplateLiteral * expr)548 void AstTraversalVisitor<Subclass>::VisitTemplateLiteral(
549     TemplateLiteral* expr) {
550   PROCESS_EXPRESSION(expr);
551   for (Expression* sub : *expr->substitutions()) {
552     RECURSE_EXPRESSION(Visit(sub));
553   }
554 }
555 
556 template <class Subclass>
VisitImportCallExpression(ImportCallExpression * expr)557 void AstTraversalVisitor<Subclass>::VisitImportCallExpression(
558     ImportCallExpression* expr) {
559   PROCESS_EXPRESSION(expr);
560   RECURSE_EXPRESSION(Visit(expr->argument()));
561 }
562 
563 template <class Subclass>
VisitSuperPropertyReference(SuperPropertyReference * expr)564 void AstTraversalVisitor<Subclass>::VisitSuperPropertyReference(
565     SuperPropertyReference* expr) {
566   PROCESS_EXPRESSION(expr);
567   RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
568   RECURSE_EXPRESSION(Visit(expr->home_object()));
569 }
570 
571 template <class Subclass>
VisitSuperCallReference(SuperCallReference * expr)572 void AstTraversalVisitor<Subclass>::VisitSuperCallReference(
573     SuperCallReference* expr) {
574   PROCESS_EXPRESSION(expr);
575   RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
576   RECURSE_EXPRESSION(VisitVariableProxy(expr->new_target_var()));
577   RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var()));
578 }
579 
580 template <class Subclass>
VisitRewritableExpression(RewritableExpression * expr)581 void AstTraversalVisitor<Subclass>::VisitRewritableExpression(
582     RewritableExpression* expr) {
583   PROCESS_EXPRESSION(expr);
584   RECURSE(Visit(expr->expression()));
585 }
586 
587 #undef PROCESS_NODE
588 #undef PROCESS_EXPRESSION
589 #undef RECURSE_EXPRESSION
590 #undef RECURSE
591 
592 }  // namespace internal
593 }  // namespace v8
594 
595 #endif  // V8_AST_AST_TRAVERSAL_VISITOR_H_
596