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 207 : void Run() {
35 : DCHECK_NOT_NULL(root_);
36 20018 : Visit(root_);
37 207 : }
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 391066 : 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 1700 : : 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 18597 : : root_(root), depth_(0) {
102 : InitializeAstVisitor(stack_limit);
103 : }
104 :
105 : template <class Subclass>
106 6415 : void AstTraversalVisitor<Subclass>::VisitDeclarations(
107 4682 : Declaration::List* decls) {
108 17512 : for (Declaration* decl : *decls) {
109 15779 : RECURSE(Visit(decl));
110 : }
111 : }
112 :
113 : template <class Subclass>
114 11232 : void AstTraversalVisitor<Subclass>::VisitStatements(
115 45794 : const ZonePtrList<Statement>* stmts) {
116 52580 : for (int i = 0; i < stmts->length(); ++i) {
117 19504 : Statement* stmt = stmts->at(i);
118 50240 : RECURSE(Visit(stmt));
119 19504 : if (stmt->IsJump()) break;
120 : }
121 : }
122 :
123 : template <class Subclass>
124 : void AstTraversalVisitor<Subclass>::VisitVariableDeclaration(
125 : VariableDeclaration* decl) {
126 665 : PROCESS_NODE(decl);
127 : }
128 :
129 : template <class Subclass>
130 2186 : void AstTraversalVisitor<Subclass>::VisitFunctionDeclaration(
131 2186 : FunctionDeclaration* decl) {
132 180 : PROCESS_NODE(decl);
133 2186 : RECURSE(Visit(decl->fun()));
134 : }
135 :
136 : template <class Subclass>
137 6655 : void AstTraversalVisitor<Subclass>::VisitBlock(Block* stmt) {
138 1565 : PROCESS_NODE(stmt);
139 4920 : if (stmt->scope() != nullptr) {
140 255 : RECURSE_EXPRESSION(VisitDeclarations(stmt->scope()->declarations()));
141 : }
142 4920 : RECURSE(VisitStatements(stmt->statements()));
143 : }
144 :
145 : template <class Subclass>
146 10389 : void AstTraversalVisitor<Subclass>::VisitExpressionStatement(
147 10389 : ExpressionStatement* stmt) {
148 2435 : PROCESS_NODE(stmt);
149 10389 : RECURSE(Visit(stmt->expression()));
150 : }
151 :
152 : template <class Subclass>
153 : void AstTraversalVisitor<Subclass>::VisitEmptyStatement(EmptyStatement* stmt) {}
154 :
155 : template <class Subclass>
156 5 : void AstTraversalVisitor<Subclass>::VisitSloppyBlockFunctionStatement(
157 5 : SloppyBlockFunctionStatement* stmt) {
158 0 : PROCESS_NODE(stmt);
159 5 : RECURSE(Visit(stmt->statement()));
160 : }
161 :
162 : template <class Subclass>
163 5950 : void AstTraversalVisitor<Subclass>::VisitIfStatement(IfStatement* stmt) {
164 570 : PROCESS_NODE(stmt);
165 2152 : RECURSE(Visit(stmt->condition()));
166 2152 : RECURSE(Visit(stmt->then_statement()));
167 1076 : RECURSE(Visit(stmt->else_statement()));
168 : }
169 :
170 : template <class Subclass>
171 : void AstTraversalVisitor<Subclass>::VisitContinueStatement(
172 : ContinueStatement* stmt) {
173 30 : PROCESS_NODE(stmt);
174 : }
175 :
176 : template <class Subclass>
177 : void AstTraversalVisitor<Subclass>::VisitBreakStatement(BreakStatement* stmt) {
178 115 : PROCESS_NODE(stmt);
179 : }
180 :
181 : template <class Subclass>
182 4553 : void AstTraversalVisitor<Subclass>::VisitReturnStatement(
183 4553 : ReturnStatement* stmt) {
184 610 : PROCESS_NODE(stmt);
185 4553 : RECURSE(Visit(stmt->expression()));
186 : }
187 :
188 : template <class Subclass>
189 0 : void AstTraversalVisitor<Subclass>::VisitWithStatement(WithStatement* stmt) {
190 0 : PROCESS_NODE(stmt);
191 0 : RECURSE(Visit(stmt->expression()));
192 0 : RECURSE(Visit(stmt->statement()));
193 : }
194 :
195 : template <class Subclass>
196 87 : void AstTraversalVisitor<Subclass>::VisitSwitchStatement(
197 733 : SwitchStatement* stmt) {
198 15 : PROCESS_NODE(stmt);
199 174 : RECURSE(Visit(stmt->tag()));
200 :
201 405 : ZonePtrList<CaseClause>* clauses = stmt->cases();
202 723 : for (int i = 0; i < clauses->length(); ++i) {
203 318 : CaseClause* clause = clauses->at(i);
204 318 : if (!clause->is_default()) {
205 : Expression* label = clause->label();
206 482 : RECURSE(Visit(label));
207 : }
208 318 : const ZonePtrList<Statement>* stmts = clause->statements();
209 636 : RECURSE(VisitStatements(stmts));
210 : }
211 : }
212 :
213 : template <class Subclass>
214 55 : void AstTraversalVisitor<Subclass>::VisitDoWhileStatement(
215 110 : DoWhileStatement* stmt) {
216 55 : PROCESS_NODE(stmt);
217 110 : RECURSE(Visit(stmt->body()));
218 55 : RECURSE(Visit(stmt->cond()));
219 : }
220 :
221 : template <class Subclass>
222 225 : void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) {
223 75 : PROCESS_NODE(stmt);
224 150 : RECURSE(Visit(stmt->cond()));
225 75 : RECURSE(Visit(stmt->body()));
226 : }
227 :
228 : template <class Subclass>
229 2164 : void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) {
230 125 : PROCESS_NODE(stmt);
231 364 : if (stmt->init() != nullptr) {
232 598 : RECURSE(Visit(stmt->init()));
233 : }
234 364 : if (stmt->cond() != nullptr) {
235 648 : RECURSE(Visit(stmt->cond()));
236 : }
237 364 : if (stmt->next() != nullptr) {
238 648 : RECURSE(Visit(stmt->next()));
239 : }
240 364 : RECURSE(Visit(stmt->body()));
241 : }
242 :
243 : template <class Subclass>
244 60 : void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
245 10 : PROCESS_NODE(stmt);
246 40 : RECURSE(Visit(stmt->each()));
247 40 : RECURSE(Visit(stmt->subject()));
248 20 : RECURSE(Visit(stmt->body()));
249 : }
250 :
251 : template <class Subclass>
252 120 : void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* stmt) {
253 40 : PROCESS_NODE(stmt);
254 80 : RECURSE(Visit(stmt->each()));
255 80 : RECURSE(Visit(stmt->subject()));
256 40 : RECURSE(Visit(stmt->body()));
257 : }
258 :
259 : template <class Subclass>
260 363 : void AstTraversalVisitor<Subclass>::VisitTryCatchStatement(
261 726 : TryCatchStatement* stmt) {
262 75 : PROCESS_NODE(stmt);
263 726 : RECURSE(Visit(stmt->try_block()));
264 363 : RECURSE(Visit(stmt->catch_block()));
265 : }
266 :
267 : template <class Subclass>
268 35 : void AstTraversalVisitor<Subclass>::VisitTryFinallyStatement(
269 70 : TryFinallyStatement* stmt) {
270 35 : PROCESS_NODE(stmt);
271 70 : RECURSE(Visit(stmt->try_block()));
272 35 : RECURSE(Visit(stmt->finally_block()));
273 : }
274 :
275 : template <class Subclass>
276 : void AstTraversalVisitor<Subclass>::VisitDebuggerStatement(
277 : DebuggerStatement* stmt) {
278 0 : PROCESS_NODE(stmt);
279 : }
280 :
281 : template <class Subclass>
282 6330 : void AstTraversalVisitor<Subclass>::VisitFunctionLiteral(
283 18990 : FunctionLiteral* expr) {
284 1470 : PROCESS_EXPRESSION(expr);
285 : DeclarationScope* scope = expr->scope();
286 12660 : RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
287 : // A lazily parsed function literal won't have a body.
288 6330 : if (expr->scope()->was_lazily_parsed()) return;
289 5994 : RECURSE_EXPRESSION(VisitStatements(expr->body()));
290 : }
291 :
292 : template <class Subclass>
293 : void AstTraversalVisitor<Subclass>::VisitNativeFunctionLiteral(
294 : NativeFunctionLiteral* expr) {
295 0 : PROCESS_EXPRESSION(expr);
296 : }
297 :
298 : template <class Subclass>
299 0 : void AstTraversalVisitor<Subclass>::VisitDoExpression(DoExpression* expr) {
300 0 : PROCESS_EXPRESSION(expr);
301 0 : RECURSE(VisitBlock(expr->block()));
302 0 : RECURSE(VisitVariableProxy(expr->result()));
303 : }
304 :
305 : template <class Subclass>
306 5580 : void AstTraversalVisitor<Subclass>::VisitConditional(Conditional* expr) {
307 100 : PROCESS_EXPRESSION(expr);
308 2790 : RECURSE_EXPRESSION(Visit(expr->condition()));
309 2790 : RECURSE_EXPRESSION(Visit(expr->then_expression()));
310 1860 : RECURSE_EXPRESSION(Visit(expr->else_expression()));
311 : }
312 :
313 : template <class Subclass>
314 : void AstTraversalVisitor<Subclass>::VisitVariableProxy(VariableProxy* expr) {
315 4475 : PROCESS_EXPRESSION(expr);
316 : }
317 :
318 : template <class Subclass>
319 : void AstTraversalVisitor<Subclass>::VisitLiteral(Literal* expr) {
320 2765 : PROCESS_EXPRESSION(expr);
321 : }
322 :
323 : template <class Subclass>
324 : void AstTraversalVisitor<Subclass>::VisitRegExpLiteral(RegExpLiteral* expr) {
325 20 : PROCESS_EXPRESSION(expr);
326 : }
327 :
328 : template <class Subclass>
329 4937 : void AstTraversalVisitor<Subclass>::VisitObjectLiteral(ObjectLiteral* expr) {
330 20 : PROCESS_EXPRESSION(expr);
331 3410 : const ZonePtrList<ObjectLiteralProperty>* props = expr->properties();
332 6800 : for (int i = 0; i < props->length(); ++i) {
333 1527 : ObjectLiteralProperty* prop = props->at(i);
334 6108 : RECURSE_EXPRESSION(Visit(prop->key()));
335 4581 : RECURSE_EXPRESSION(Visit(prop->value()));
336 : }
337 : }
338 :
339 : template <class Subclass>
340 3361 : void AstTraversalVisitor<Subclass>::VisitArrayLiteral(ArrayLiteral* expr) {
341 30 : PROCESS_EXPRESSION(expr);
342 3361 : const ZonePtrList<Expression>* values = expr->values();
343 6692 : for (int i = 0; i < values->length(); ++i) {
344 1993 : Expression* value = values->at(i);
345 3986 : RECURSE_EXPRESSION(Visit(value));
346 : }
347 : }
348 :
349 : template <class Subclass>
350 24800 : void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
351 895 : PROCESS_EXPRESSION(expr);
352 18600 : RECURSE_EXPRESSION(Visit(expr->target()));
353 12400 : RECURSE_EXPRESSION(Visit(expr->value()));
354 : }
355 :
356 : template <class Subclass>
357 910 : void AstTraversalVisitor<Subclass>::VisitCompoundAssignment(
358 : CompoundAssignment* expr) {
359 910 : VisitAssignment(expr);
360 910 : }
361 :
362 : template <class Subclass>
363 340 : void AstTraversalVisitor<Subclass>::VisitYield(Yield* expr) {
364 150 : PROCESS_EXPRESSION(expr);
365 340 : RECURSE_EXPRESSION(Visit(expr->expression()));
366 : }
367 :
368 : template <class Subclass>
369 30 : void AstTraversalVisitor<Subclass>::VisitYieldStar(YieldStar* expr) {
370 30 : PROCESS_EXPRESSION(expr);
371 30 : RECURSE_EXPRESSION(Visit(expr->expression()));
372 : }
373 :
374 : template <class Subclass>
375 64 : void AstTraversalVisitor<Subclass>::VisitAwait(Await* expr) {
376 10 : PROCESS_EXPRESSION(expr);
377 64 : RECURSE_EXPRESSION(Visit(expr->expression()));
378 : }
379 :
380 : template <class Subclass>
381 142 : void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
382 35 : PROCESS_EXPRESSION(expr);
383 142 : RECURSE_EXPRESSION(Visit(expr->exception()));
384 : }
385 :
386 : template <class Subclass>
387 14356 : void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
388 385 : PROCESS_EXPRESSION(expr);
389 10767 : RECURSE_EXPRESSION(Visit(expr->obj()));
390 7178 : RECURSE_EXPRESSION(Visit(expr->key()));
391 : }
392 :
393 : template <class Subclass>
394 0 : void AstTraversalVisitor<Subclass>::VisitResolvedProperty(
395 0 : ResolvedProperty* expr) {
396 0 : PROCESS_EXPRESSION(expr);
397 0 : RECURSE_EXPRESSION(VisitVariableProxy(expr->object()));
398 0 : RECURSE_EXPRESSION(VisitVariableProxy(expr->property()));
399 : }
400 :
401 : template <class Subclass>
402 34140 : void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
403 1830 : PROCESS_EXPRESSION(expr);
404 27252 : RECURSE_EXPRESSION(Visit(expr->expression()));
405 15972 : const ZonePtrList<Expression>* args = expr->arguments();
406 22860 : for (int i = 0; i < args->length(); ++i) {
407 6888 : Expression* arg = args->at(i);
408 13776 : RECURSE_EXPRESSION(Visit(arg));
409 : }
410 : }
411 :
412 : template <class Subclass>
413 504 : void AstTraversalVisitor<Subclass>::VisitCallNew(CallNew* expr) {
414 30 : PROCESS_EXPRESSION(expr);
415 450 : RECURSE_EXPRESSION(Visit(expr->expression()));
416 204 : const ZonePtrList<Expression>* args = expr->arguments();
417 258 : for (int i = 0; i < args->length(); ++i) {
418 54 : Expression* arg = args->at(i);
419 108 : RECURSE_EXPRESSION(Visit(arg));
420 : }
421 : }
422 :
423 : template <class Subclass>
424 1063 : void AstTraversalVisitor<Subclass>::VisitCallRuntime(CallRuntime* expr) {
425 100 : PROCESS_EXPRESSION(expr);
426 1063 : const ZonePtrList<Expression>* args = expr->arguments();
427 2026 : for (int i = 0; i < args->length(); ++i) {
428 684 : Expression* arg = args->at(i);
429 1368 : RECURSE_EXPRESSION(Visit(arg));
430 : }
431 : }
432 :
433 : template <class Subclass>
434 1412 : void AstTraversalVisitor<Subclass>::VisitUnaryOperation(UnaryOperation* expr) {
435 450 : PROCESS_EXPRESSION(expr);
436 1412 : RECURSE_EXPRESSION(Visit(expr->expression()));
437 : }
438 :
439 : template <class Subclass>
440 1434 : void AstTraversalVisitor<Subclass>::VisitCountOperation(CountOperation* expr) {
441 125 : PROCESS_EXPRESSION(expr);
442 1434 : RECURSE_EXPRESSION(Visit(expr->expression()));
443 : }
444 :
445 : template <class Subclass>
446 1536 : void AstTraversalVisitor<Subclass>::VisitBinaryOperation(
447 4608 : BinaryOperation* expr) {
448 310 : PROCESS_EXPRESSION(expr);
449 4608 : RECURSE_EXPRESSION(Visit(expr->left()));
450 3072 : RECURSE_EXPRESSION(Visit(expr->right()));
451 : }
452 :
453 : template <class Subclass>
454 1030 : void AstTraversalVisitor<Subclass>::VisitNaryOperation(NaryOperation* expr) {
455 130 : PROCESS_EXPRESSION(expr);
456 588 : RECURSE_EXPRESSION(Visit(expr->first()));
457 1080 : for (size_t i = 0; i < expr->subsequent_length(); ++i) {
458 1326 : RECURSE_EXPRESSION(Visit(expr->subsequent(i)));
459 : }
460 : }
461 :
462 : template <class Subclass>
463 2163 : void AstTraversalVisitor<Subclass>::VisitCompareOperation(
464 6489 : CompareOperation* expr) {
465 585 : PROCESS_EXPRESSION(expr);
466 6489 : RECURSE_EXPRESSION(Visit(expr->left()));
467 4326 : RECURSE_EXPRESSION(Visit(expr->right()));
468 : }
469 :
470 : template <class Subclass>
471 : void AstTraversalVisitor<Subclass>::VisitThisFunction(ThisFunction* expr) {
472 0 : PROCESS_EXPRESSION(expr);
473 : }
474 :
475 : template <class Subclass>
476 1259 : void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) {
477 60 : PROCESS_EXPRESSION(expr);
478 157 : if (expr->extends() != nullptr) {
479 36 : RECURSE_EXPRESSION(Visit(expr->extends()));
480 : }
481 471 : RECURSE_EXPRESSION(Visit(expr->constructor()));
482 157 : if (expr->static_fields_initializer() != nullptr) {
483 60 : RECURSE_EXPRESSION(Visit(expr->static_fields_initializer()));
484 : }
485 157 : if (expr->instance_members_initializer_function() != nullptr) {
486 105 : RECURSE_EXPRESSION(Visit(expr->instance_members_initializer_function()));
487 : }
488 235 : ZonePtrList<ClassLiteral::Property>* props = expr->properties();
489 470 : for (int i = 0; i < props->length(); ++i) {
490 78 : ClassLiteralProperty* prop = props->at(i);
491 156 : if (!prop->key()->IsLiteral()) {
492 135 : RECURSE_EXPRESSION(Visit(prop->key()));
493 : }
494 234 : RECURSE_EXPRESSION(Visit(prop->value()));
495 : }
496 : }
497 :
498 : template <class Subclass>
499 55 : void AstTraversalVisitor<Subclass>::VisitInitializeClassMembersStatement(
500 130 : InitializeClassMembersStatement* stmt) {
501 55 : PROCESS_NODE(stmt);
502 120 : ZonePtrList<ClassLiteral::Property>* props = stmt->fields();
503 240 : for (int i = 0; i < props->length(); ++i) {
504 65 : ClassLiteralProperty* prop = props->at(i);
505 130 : if (!prop->key()->IsLiteral()) {
506 20 : RECURSE(Visit(prop->key()));
507 : }
508 130 : RECURSE(Visit(prop->value()));
509 : }
510 : }
511 :
512 : template <class Subclass>
513 94 : void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
514 0 : PROCESS_EXPRESSION(expr);
515 94 : RECURSE_EXPRESSION(Visit(expr->expression()));
516 : }
517 :
518 : template <class Subclass>
519 0 : void AstTraversalVisitor<Subclass>::VisitStoreInArrayLiteral(
520 0 : StoreInArrayLiteral* expr) {
521 0 : PROCESS_EXPRESSION(expr);
522 0 : RECURSE_EXPRESSION(Visit(expr->array()));
523 0 : RECURSE_EXPRESSION(Visit(expr->index()));
524 0 : RECURSE_EXPRESSION(Visit(expr->value()));
525 : }
526 :
527 : template <class Subclass>
528 : void AstTraversalVisitor<Subclass>::VisitEmptyParentheses(
529 : EmptyParentheses* expr) {
530 0 : PROCESS_EXPRESSION(expr);
531 : }
532 :
533 : template <class Subclass>
534 : void AstTraversalVisitor<Subclass>::VisitGetTemplateObject(
535 : GetTemplateObject* expr) {
536 0 : PROCESS_EXPRESSION(expr);
537 : }
538 :
539 : template <class Subclass>
540 6 : void AstTraversalVisitor<Subclass>::VisitTemplateLiteral(
541 12 : TemplateLiteral* expr) {
542 0 : PROCESS_EXPRESSION(expr);
543 18 : for (Expression* sub : *expr->substitutions()) {
544 12 : RECURSE_EXPRESSION(Visit(sub));
545 : }
546 : }
547 :
548 : template <class Subclass>
549 0 : void AstTraversalVisitor<Subclass>::VisitImportCallExpression(
550 0 : ImportCallExpression* expr) {
551 0 : PROCESS_EXPRESSION(expr);
552 0 : RECURSE_EXPRESSION(Visit(expr->argument()));
553 : }
554 :
555 : template <class Subclass>
556 5 : void AstTraversalVisitor<Subclass>::VisitSuperPropertyReference(
557 10 : SuperPropertyReference* expr) {
558 0 : PROCESS_EXPRESSION(expr);
559 10 : RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
560 10 : RECURSE_EXPRESSION(Visit(expr->home_object()));
561 : }
562 :
563 : template <class Subclass>
564 0 : void AstTraversalVisitor<Subclass>::VisitSuperCallReference(
565 10 : SuperCallReference* expr) {
566 0 : PROCESS_EXPRESSION(expr);
567 20 : RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
568 10 : RECURSE_EXPRESSION(VisitVariableProxy(expr->new_target_var()));
569 10 : RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var()));
570 : }
571 :
572 : #undef PROCESS_NODE
573 : #undef PROCESS_EXPRESSION
574 : #undef RECURSE_EXPRESSION
575 : #undef RECURSE
576 :
577 : } // namespace internal
578 : } // namespace v8
579 :
580 : #endif // V8_AST_AST_TRAVERSAL_VISITOR_H_
|