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