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 4717 : 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 307726 : 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 3286 : : root_(root), depth_(0) {
102 : InitializeAstVisitor(stack_limit);
103 : }
104 :
105 : template <class Subclass>
106 6160 : void AstTraversalVisitor<Subclass>::VisitDeclarations(
107 6671 : Declaration::List* decls) {
108 18991 : for (Declaration* decl : *decls) {
109 19502 : RECURSE(Visit(decl));
110 : }
111 : }
112 :
113 : template <class Subclass>
114 10756 : void AstTraversalVisitor<Subclass>::VisitStatements(
115 48324 : const ZonePtrList<Statement>* stmts) {
116 59080 : for (int i = 0; i < stmts->length(); ++i) {
117 18784 : Statement* stmt = stmts->at(i);
118 48324 : RECURSE(Visit(stmt));
119 : }
120 : }
121 :
122 : template <class Subclass>
123 : void AstTraversalVisitor<Subclass>::VisitVariableDeclaration(
124 : VariableDeclaration* decl) {
125 804 : PROCESS_NODE(decl);
126 : }
127 :
128 : template <class Subclass>
129 2154 : void AstTraversalVisitor<Subclass>::VisitFunctionDeclaration(
130 2154 : FunctionDeclaration* decl) {
131 148 : PROCESS_NODE(decl);
132 2154 : RECURSE(Visit(decl->fun()));
133 : }
134 :
135 : template <class Subclass>
136 6024 : void AstTraversalVisitor<Subclass>::VisitBlock(Block* stmt) {
137 1252 : PROCESS_NODE(stmt);
138 4632 : if (stmt->scope() != nullptr) {
139 210 : RECURSE_EXPRESSION(VisitDeclarations(stmt->scope()->declarations()));
140 : }
141 4632 : RECURSE(VisitStatements(stmt->statements()));
142 : }
143 :
144 : template <class Subclass>
145 9991 : void AstTraversalVisitor<Subclass>::VisitExpressionStatement(
146 9991 : ExpressionStatement* stmt) {
147 2012 : PROCESS_NODE(stmt);
148 9991 : 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 5 : SloppyBlockFunctionStatement* stmt) {
157 0 : PROCESS_NODE(stmt);
158 5 : RECURSE(Visit(stmt->statement()));
159 : }
160 :
161 : template <class Subclass>
162 5291 : void AstTraversalVisitor<Subclass>::VisitIfStatement(IfStatement* stmt) {
163 456 : PROCESS_NODE(stmt);
164 1934 : RECURSE(Visit(stmt->condition()));
165 1934 : RECURSE(Visit(stmt->then_statement()));
166 967 : 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 4495 : 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 716 : SwitchStatement* stmt) {
197 12 : PROCESS_NODE(stmt);
198 168 : RECURSE(Visit(stmt->tag()));
199 :
200 396 : 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 472 : RECURSE(Visit(label));
206 : }
207 312 : const ZonePtrList<Statement>* stmts = clause->statements();
208 624 : RECURSE(VisitStatements(stmts));
209 : }
210 : }
211 :
212 : template <class Subclass>
213 44 : void AstTraversalVisitor<Subclass>::VisitDoWhileStatement(
214 88 : DoWhileStatement* stmt) {
215 44 : PROCESS_NODE(stmt);
216 88 : RECURSE(Visit(stmt->body()));
217 44 : RECURSE(Visit(stmt->cond()));
218 : }
219 :
220 : template <class Subclass>
221 180 : void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) {
222 60 : PROCESS_NODE(stmt);
223 120 : RECURSE(Visit(stmt->cond()));
224 60 : RECURSE(Visit(stmt->body()));
225 : }
226 :
227 : template <class Subclass>
228 2018 : void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) {
229 100 : PROCESS_NODE(stmt);
230 339 : if (stmt->init() != nullptr) {
231 574 : RECURSE(Visit(stmt->init()));
232 : }
233 339 : if (stmt->cond() != nullptr) {
234 614 : RECURSE(Visit(stmt->cond()));
235 : }
236 339 : if (stmt->next() != nullptr) {
237 614 : RECURSE(Visit(stmt->next()));
238 : }
239 339 : RECURSE(Visit(stmt->body()));
240 : }
241 :
242 : template <class Subclass>
243 54 : void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
244 8 : PROCESS_NODE(stmt);
245 36 : RECURSE(Visit(stmt->each()));
246 36 : RECURSE(Visit(stmt->subject()));
247 18 : RECURSE(Visit(stmt->body()));
248 : }
249 :
250 : template <class Subclass>
251 96 : void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* stmt) {
252 32 : PROCESS_NODE(stmt);
253 64 : RECURSE(Visit(stmt->each()));
254 64 : RECURSE(Visit(stmt->subject()));
255 32 : RECURSE(Visit(stmt->body()));
256 : }
257 :
258 : template <class Subclass>
259 348 : void AstTraversalVisitor<Subclass>::VisitTryCatchStatement(
260 696 : TryCatchStatement* stmt) {
261 60 : PROCESS_NODE(stmt);
262 696 : RECURSE(Visit(stmt->try_block()));
263 348 : RECURSE(Visit(stmt->catch_block()));
264 : }
265 :
266 : template <class Subclass>
267 28 : void AstTraversalVisitor<Subclass>::VisitTryFinallyStatement(
268 56 : TryFinallyStatement* stmt) {
269 28 : PROCESS_NODE(stmt);
270 56 : 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 6090 : void AstTraversalVisitor<Subclass>::VisitFunctionLiteral(
282 18270 : FunctionLiteral* expr) {
283 1200 : PROCESS_EXPRESSION(expr);
284 : DeclarationScope* scope = expr->scope();
285 12180 : RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
286 : // A lazily parsed function literal won't have a body.
287 6090 : if (expr->scope()->was_lazily_parsed()) return;
288 5812 : 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 5484 : void AstTraversalVisitor<Subclass>::VisitConditional(Conditional* expr) {
306 80 : PROCESS_EXPRESSION(expr);
307 2742 : RECURSE_EXPRESSION(Visit(expr->condition()));
308 2742 : RECURSE_EXPRESSION(Visit(expr->then_expression()));
309 1828 : RECURSE_EXPRESSION(Visit(expr->else_expression()));
310 : }
311 :
312 : template <class Subclass>
313 : void AstTraversalVisitor<Subclass>::VisitVariableProxy(VariableProxy* expr) {
314 3640 : PROCESS_EXPRESSION(expr);
315 : }
316 :
317 : template <class Subclass>
318 : void AstTraversalVisitor<Subclass>::VisitLiteral(Literal* expr) {
319 2212 : 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 1847 : void AstTraversalVisitor<Subclass>::VisitObjectLiteral(ObjectLiteral* expr) {
329 16 : PROCESS_EXPRESSION(expr);
330 1195 : const ZonePtrList<ObjectLiteralProperty>* props = expr->properties();
331 2374 : for (int i = 0; i < props->length(); ++i) {
332 652 : ObjectLiteralProperty* prop = props->at(i);
333 2608 : RECURSE_EXPRESSION(Visit(prop->key()));
334 1956 : RECURSE_EXPRESSION(Visit(prop->value()));
335 : }
336 : }
337 :
338 : template <class Subclass>
339 2226 : void AstTraversalVisitor<Subclass>::VisitArrayLiteral(ArrayLiteral* expr) {
340 24 : PROCESS_EXPRESSION(expr);
341 2226 : const ZonePtrList<Expression>* values = expr->values();
342 4428 : for (int i = 0; i < values->length(); ++i) {
343 1381 : Expression* value = values->at(i);
344 2762 : RECURSE_EXPRESSION(Visit(value));
345 : }
346 : }
347 :
348 : template <class Subclass>
349 24364 : void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
350 716 : PROCESS_EXPRESSION(expr);
351 18273 : RECURSE_EXPRESSION(Visit(expr->target()));
352 12182 : 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 128 : void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
381 28 : PROCESS_EXPRESSION(expr);
382 128 : RECURSE_EXPRESSION(Visit(expr->exception()));
383 : }
384 :
385 : template <class Subclass>
386 13576 : void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
387 308 : PROCESS_EXPRESSION(expr);
388 10182 : RECURSE_EXPRESSION(Visit(expr->obj()));
389 6788 : RECURSE_EXPRESSION(Visit(expr->key()));
390 : }
391 :
392 : template <class Subclass>
393 0 : void AstTraversalVisitor<Subclass>::VisitResolvedProperty(
394 0 : 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 27077 : void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
402 1528 : PROCESS_EXPRESSION(expr);
403 21558 : RECURSE_EXPRESSION(Visit(expr->expression()));
404 12705 : const ZonePtrList<Expression>* args = expr->arguments();
405 18224 : for (int i = 0; i < args->length(); ++i) {
406 5519 : Expression* arg = args->at(i);
407 11038 : RECURSE_EXPRESSION(Visit(arg));
408 : }
409 : }
410 :
411 : template <class Subclass>
412 342 : void AstTraversalVisitor<Subclass>::VisitCallNew(CallNew* expr) {
413 24 : PROCESS_EXPRESSION(expr);
414 288 : RECURSE_EXPRESSION(Visit(expr->expression()));
415 150 : const ZonePtrList<Expression>* args = expr->arguments();
416 204 : for (int i = 0; i < args->length(); ++i) {
417 54 : Expression* arg = args->at(i);
418 108 : RECURSE_EXPRESSION(Visit(arg));
419 : }
420 : }
421 :
422 : template <class Subclass>
423 974 : void AstTraversalVisitor<Subclass>::VisitCallRuntime(CallRuntime* expr) {
424 80 : PROCESS_EXPRESSION(expr);
425 974 : const ZonePtrList<Expression>* args = expr->arguments();
426 1868 : for (int i = 0; i < args->length(); ++i) {
427 632 : Expression* arg = args->at(i);
428 1264 : RECURSE_EXPRESSION(Visit(arg));
429 : }
430 : }
431 :
432 : template <class Subclass>
433 1206 : void AstTraversalVisitor<Subclass>::VisitUnaryOperation(UnaryOperation* expr) {
434 364 : PROCESS_EXPRESSION(expr);
435 1206 : RECURSE_EXPRESSION(Visit(expr->expression()));
436 : }
437 :
438 : template <class Subclass>
439 1372 : void AstTraversalVisitor<Subclass>::VisitCountOperation(CountOperation* expr) {
440 100 : PROCESS_EXPRESSION(expr);
441 1372 : RECURSE_EXPRESSION(Visit(expr->expression()));
442 : }
443 :
444 : template <class Subclass>
445 1404 : void AstTraversalVisitor<Subclass>::VisitBinaryOperation(
446 4212 : BinaryOperation* expr) {
447 248 : PROCESS_EXPRESSION(expr);
448 4212 : RECURSE_EXPRESSION(Visit(expr->left()));
449 2808 : RECURSE_EXPRESSION(Visit(expr->right()));
450 : }
451 :
452 : template <class Subclass>
453 771 : void AstTraversalVisitor<Subclass>::VisitNaryOperation(NaryOperation* expr) {
454 104 : PROCESS_EXPRESSION(expr);
455 441 : RECURSE_EXPRESSION(Visit(expr->first()));
456 807 : for (size_t i = 0; i < expr->subsequent_length(); ++i) {
457 990 : RECURSE_EXPRESSION(Visit(expr->subsequent(i)));
458 : }
459 : }
460 :
461 : template <class Subclass>
462 2044 : void AstTraversalVisitor<Subclass>::VisitCompareOperation(
463 6132 : CompareOperation* expr) {
464 468 : PROCESS_EXPRESSION(expr);
465 6132 : RECURSE_EXPRESSION(Visit(expr->left()));
466 4088 : 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 508 : 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 174 : RECURSE_EXPRESSION(Visit(expr->constructor()));
481 58 : if (expr->static_fields_initializer() != nullptr) {
482 48 : RECURSE_EXPRESSION(Visit(expr->static_fields_initializer()));
483 : }
484 58 : if (expr->instance_members_initializer_function() != nullptr) {
485 84 : RECURSE_EXPRESSION(Visit(expr->instance_members_initializer_function()));
486 : }
487 74 : ZonePtrList<ClassLiteral::Property>* props = expr->properties();
488 148 : for (int i = 0; i < props->length(); ++i) {
489 16 : ClassLiteralProperty* prop = props->at(i);
490 32 : if (!prop->key()->IsLiteral()) {
491 24 : RECURSE_EXPRESSION(Visit(prop->key()));
492 : }
493 48 : RECURSE_EXPRESSION(Visit(prop->value()));
494 : }
495 : }
496 :
497 : template <class Subclass>
498 44 : void AstTraversalVisitor<Subclass>::VisitInitializeClassMembersStatement(
499 104 : InitializeClassMembersStatement* stmt) {
500 44 : PROCESS_NODE(stmt);
501 96 : ZonePtrList<ClassLiteral::Property>* props = stmt->fields();
502 192 : for (int i = 0; i < props->length(); ++i) {
503 52 : ClassLiteralProperty* prop = props->at(i);
504 104 : if (!prop->key()->IsLiteral()) {
505 16 : RECURSE(Visit(prop->key()));
506 : }
507 104 : RECURSE(Visit(prop->value()));
508 : }
509 : }
510 :
511 : template <class Subclass>
512 10 : void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
513 0 : PROCESS_EXPRESSION(expr);
514 10 : RECURSE_EXPRESSION(Visit(expr->expression()));
515 : }
516 :
517 : template <class Subclass>
518 0 : void AstTraversalVisitor<Subclass>::VisitStoreInArrayLiteral(
519 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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_
|