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