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