5 #ifndef V8_AST_AST_TRAVERSAL_VISITOR_H_ 6 #define V8_AST_AST_TRAVERSAL_VISITOR_H_ 8 #include "src/ast/ast.h" 9 #include "src/ast/scopes.h" 28 template <
class Sub
class>
35 DCHECK_NOT_NULL(root_);
39 bool VisitNode(
AstNode* node) {
return true; }
40 bool VisitExpression(
Expression* node) {
return true; }
47 #define DECLARE_VISIT(type) void Visit##type(type* node); 48 AST_NODE_LIST(DECLARE_VISIT)
52 int depth()
const {
return depth_; }
55 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
66 #define PROCESS_NODE(node) do { \ 67 if (!(this->impl()->VisitNode(node))) return; \ 70 #define PROCESS_EXPRESSION(node) do { \ 72 if (!(this->impl()->VisitExpression(node))) return; \ 75 #define RECURSE(call) \ 77 DCHECK(!HasStackOverflow()); \ 79 if (HasStackOverflow()) return; \ 82 #define RECURSE_EXPRESSION(call) \ 84 DCHECK(!HasStackOverflow()); \ 88 if (HasStackOverflow()) return; \ 91 template <
class Sub
class>
94 : root_(root), depth_(0) {
95 InitializeAstVisitor(isolate);
98 template <
class Sub
class>
99 AstTraversalVisitor<Subclass>::AstTraversalVisitor(
uintptr_t stack_limit,
101 : root_(root), depth_(0) {
102 InitializeAstVisitor(stack_limit);
105 template <
class Sub
class>
106 void AstTraversalVisitor<Subclass>::VisitDeclarations(
107 Declaration::List* decls) {
108 for (Declaration* decl : *decls) {
109 RECURSE(Visit(decl));
113 template <
class Sub
class>
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 if (stmt->IsJump())
break;
123 template <
class Sub
class>
124 void AstTraversalVisitor<Subclass>::VisitVariableDeclaration(
125 VariableDeclaration* decl) {
129 template <
class Sub
class>
130 void AstTraversalVisitor<Subclass>::VisitFunctionDeclaration(
131 FunctionDeclaration* decl) {
133 RECURSE(Visit(decl->fun()));
136 template <
class Sub
class>
137 void AstTraversalVisitor<Subclass>::VisitBlock(Block* stmt) {
139 if (stmt->scope() !=
nullptr) {
140 RECURSE_EXPRESSION(VisitDeclarations(stmt->scope()->declarations()));
142 RECURSE(VisitStatements(stmt->statements()));
145 template <
class Sub
class>
146 void AstTraversalVisitor<Subclass>::VisitExpressionStatement(
147 ExpressionStatement* stmt) {
149 RECURSE(Visit(stmt->expression()));
152 template <
class Sub
class>
153 void AstTraversalVisitor<Subclass>::VisitEmptyStatement(EmptyStatement* stmt) {}
155 template <
class Sub
class>
156 void AstTraversalVisitor<Subclass>::VisitSloppyBlockFunctionStatement(
157 SloppyBlockFunctionStatement* stmt) {
159 RECURSE(Visit(stmt->statement()));
162 template <
class Sub
class>
163 void AstTraversalVisitor<Subclass>::VisitIfStatement(IfStatement* stmt) {
165 RECURSE(Visit(stmt->condition()));
166 RECURSE(Visit(stmt->then_statement()));
167 RECURSE(Visit(stmt->else_statement()));
170 template <
class Sub
class>
171 void AstTraversalVisitor<Subclass>::VisitContinueStatement(
172 ContinueStatement* stmt) {
176 template <
class Sub
class>
177 void AstTraversalVisitor<Subclass>::VisitBreakStatement(BreakStatement* stmt) {
181 template <
class Sub
class>
182 void AstTraversalVisitor<Subclass>::VisitReturnStatement(
183 ReturnStatement* stmt) {
185 RECURSE(Visit(stmt->expression()));
188 template <
class Sub
class>
189 void AstTraversalVisitor<Subclass>::VisitWithStatement(WithStatement* stmt) {
191 RECURSE(Visit(stmt->expression()));
192 RECURSE(Visit(stmt->statement()));
195 template <
class Sub
class>
196 void AstTraversalVisitor<Subclass>::VisitSwitchStatement(
197 SwitchStatement* stmt) {
199 RECURSE(Visit(stmt->tag()));
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));
208 const ZonePtrList<Statement>* stmts = clause->statements();
209 RECURSE(VisitStatements(stmts));
213 template <
class Sub
class>
214 void AstTraversalVisitor<Subclass>::VisitDoWhileStatement(
215 DoWhileStatement* stmt) {
217 RECURSE(Visit(stmt->body()));
218 RECURSE(Visit(stmt->cond()));
221 template <
class Sub
class>
222 void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) {
224 RECURSE(Visit(stmt->cond()));
225 RECURSE(Visit(stmt->body()));
228 template <
class Sub
class>
229 void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) {
231 if (stmt->init() !=
nullptr) {
232 RECURSE(Visit(stmt->init()));
234 if (stmt->cond() !=
nullptr) {
235 RECURSE(Visit(stmt->cond()));
237 if (stmt->next() !=
nullptr) {
238 RECURSE(Visit(stmt->next()));
240 RECURSE(Visit(stmt->body()));
243 template <
class Sub
class>
244 void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
246 RECURSE(Visit(stmt->each()));
247 RECURSE(Visit(stmt->enumerable()));
248 RECURSE(Visit(stmt->body()));
251 template <
class Sub
class>
252 void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* 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()));
261 template <
class Sub
class>
262 void AstTraversalVisitor<Subclass>::VisitTryCatchStatement(
263 TryCatchStatement* stmt) {
265 RECURSE(Visit(stmt->try_block()));
266 RECURSE(Visit(stmt->catch_block()));
269 template <
class Sub
class>
270 void AstTraversalVisitor<Subclass>::VisitTryFinallyStatement(
271 TryFinallyStatement* stmt) {
273 RECURSE(Visit(stmt->try_block()));
274 RECURSE(Visit(stmt->finally_block()));
277 template <
class Sub
class>
278 void AstTraversalVisitor<Subclass>::VisitDebuggerStatement(
279 DebuggerStatement* stmt) {
283 template <
class Sub
class>
284 void AstTraversalVisitor<Subclass>::VisitFunctionLiteral(
285 FunctionLiteral* expr) {
286 PROCESS_EXPRESSION(expr);
287 DeclarationScope* scope = expr->scope();
288 RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
290 if (expr->scope()->was_lazily_parsed())
return;
291 RECURSE_EXPRESSION(VisitStatements(expr->body()));
294 template <
class Sub
class>
295 void AstTraversalVisitor<Subclass>::VisitNativeFunctionLiteral(
296 NativeFunctionLiteral* expr) {
297 PROCESS_EXPRESSION(expr);
300 template <
class Sub
class>
301 void AstTraversalVisitor<Subclass>::VisitDoExpression(DoExpression* expr) {
302 PROCESS_EXPRESSION(expr);
303 RECURSE(VisitBlock(expr->block()));
304 RECURSE(VisitVariableProxy(expr->result()));
307 template <
class Sub
class>
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()));
315 template <
class Sub
class>
316 void AstTraversalVisitor<Subclass>::VisitVariableProxy(VariableProxy* expr) {
317 PROCESS_EXPRESSION(expr);
320 template <
class Sub
class>
321 void AstTraversalVisitor<Subclass>::VisitLiteral(Literal* expr) {
322 PROCESS_EXPRESSION(expr);
325 template <
class Sub
class>
326 void AstTraversalVisitor<Subclass>::VisitRegExpLiteral(RegExpLiteral* expr) {
327 PROCESS_EXPRESSION(expr);
330 template <
class Sub
class>
331 void AstTraversalVisitor<Subclass>::VisitObjectLiteral(ObjectLiteral* expr) {
332 PROCESS_EXPRESSION(expr);
333 const 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()));
341 template <
class Sub
class>
342 void AstTraversalVisitor<Subclass>::VisitArrayLiteral(ArrayLiteral* expr) {
343 PROCESS_EXPRESSION(expr);
344 const 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));
351 template <
class Sub
class>
352 void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
353 PROCESS_EXPRESSION(expr);
354 RECURSE_EXPRESSION(Visit(expr->target()));
355 RECURSE_EXPRESSION(Visit(expr->value()));
358 template <
class Sub
class>
359 void AstTraversalVisitor<Subclass>::VisitCompoundAssignment(
360 CompoundAssignment* expr) {
361 VisitAssignment(expr);
364 template <
class Sub
class>
365 void AstTraversalVisitor<Subclass>::VisitYield(Yield* expr) {
366 PROCESS_EXPRESSION(expr);
367 RECURSE_EXPRESSION(Visit(expr->expression()));
370 template <
class Sub
class>
371 void AstTraversalVisitor<Subclass>::VisitYieldStar(YieldStar* expr) {
372 PROCESS_EXPRESSION(expr);
373 RECURSE_EXPRESSION(Visit(expr->expression()));
376 template <
class Sub
class>
377 void AstTraversalVisitor<Subclass>::VisitAwait(Await* expr) {
378 PROCESS_EXPRESSION(expr);
379 RECURSE_EXPRESSION(Visit(expr->expression()));
382 template <
class Sub
class>
383 void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
384 PROCESS_EXPRESSION(expr);
385 RECURSE_EXPRESSION(Visit(expr->exception()));
388 template <
class Sub
class>
389 void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
390 PROCESS_EXPRESSION(expr);
391 RECURSE_EXPRESSION(Visit(expr->obj()));
392 RECURSE_EXPRESSION(Visit(expr->key()));
395 template <
class Sub
class>
396 void AstTraversalVisitor<Subclass>::VisitResolvedProperty(
397 ResolvedProperty* expr) {
398 PROCESS_EXPRESSION(expr);
399 RECURSE_EXPRESSION(VisitVariableProxy(expr->object()));
400 RECURSE_EXPRESSION(VisitVariableProxy(expr->property()));
403 template <
class Sub
class>
404 void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
405 PROCESS_EXPRESSION(expr);
406 RECURSE_EXPRESSION(Visit(expr->expression()));
407 const 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));
414 template <
class Sub
class>
415 void AstTraversalVisitor<Subclass>::VisitCallNew(CallNew* expr) {
416 PROCESS_EXPRESSION(expr);
417 RECURSE_EXPRESSION(Visit(expr->expression()));
418 const 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));
425 template <
class Sub
class>
426 void AstTraversalVisitor<Subclass>::VisitCallRuntime(CallRuntime* expr) {
427 PROCESS_EXPRESSION(expr);
428 const 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));
435 template <
class Sub
class>
436 void AstTraversalVisitor<Subclass>::VisitUnaryOperation(UnaryOperation* expr) {
437 PROCESS_EXPRESSION(expr);
438 RECURSE_EXPRESSION(Visit(expr->expression()));
441 template <
class Sub
class>
442 void AstTraversalVisitor<Subclass>::VisitCountOperation(CountOperation* expr) {
443 PROCESS_EXPRESSION(expr);
444 RECURSE_EXPRESSION(Visit(expr->expression()));
447 template <
class Sub
class>
448 void AstTraversalVisitor<Subclass>::VisitBinaryOperation(
449 BinaryOperation* expr) {
450 PROCESS_EXPRESSION(expr);
451 RECURSE_EXPRESSION(Visit(expr->left()));
452 RECURSE_EXPRESSION(Visit(expr->right()));
455 template <
class Sub
class>
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)));
464 template <
class Sub
class>
465 void AstTraversalVisitor<Subclass>::VisitCompareOperation(
466 CompareOperation* expr) {
467 PROCESS_EXPRESSION(expr);
468 RECURSE_EXPRESSION(Visit(expr->left()));
469 RECURSE_EXPRESSION(Visit(expr->right()));
472 template <
class Sub
class>
473 void AstTraversalVisitor<Subclass>::VisitThisFunction(ThisFunction* expr) {
474 PROCESS_EXPRESSION(expr);
477 template <
class Sub
class>
478 void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) {
479 PROCESS_EXPRESSION(expr);
480 if (expr->extends() !=
nullptr) {
481 RECURSE_EXPRESSION(Visit(expr->extends()));
483 RECURSE_EXPRESSION(Visit(expr->constructor()));
484 if (expr->static_fields_initializer() !=
nullptr) {
485 RECURSE_EXPRESSION(Visit(expr->static_fields_initializer()));
487 if (expr->instance_members_initializer_function() !=
nullptr) {
488 RECURSE_EXPRESSION(Visit(expr->instance_members_initializer_function()));
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()));
496 RECURSE_EXPRESSION(Visit(prop->value()));
500 template <
class Sub
class>
501 void AstTraversalVisitor<Subclass>::VisitInitializeClassMembersStatement(
502 InitializeClassMembersStatement* 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()));
510 RECURSE(Visit(prop->value()));
514 template <
class Sub
class>
515 void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
516 PROCESS_EXPRESSION(expr);
517 RECURSE_EXPRESSION(Visit(expr->expression()));
520 template <
class Sub
class>
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()));
529 template <
class Sub
class>
530 void AstTraversalVisitor<Subclass>::VisitEmptyParentheses(
531 EmptyParentheses* expr) {
532 PROCESS_EXPRESSION(expr);
535 template <
class Sub
class>
536 void AstTraversalVisitor<Subclass>::VisitGetIterator(GetIterator* expr) {
537 PROCESS_EXPRESSION(expr);
538 RECURSE_EXPRESSION(Visit(expr->iterable()));
541 template <
class Sub
class>
542 void AstTraversalVisitor<Subclass>::VisitGetTemplateObject(
543 GetTemplateObject* expr) {
544 PROCESS_EXPRESSION(expr);
547 template <
class Sub
class>
548 void AstTraversalVisitor<Subclass>::VisitTemplateLiteral(
549 TemplateLiteral* expr) {
550 PROCESS_EXPRESSION(expr);
551 for (Expression* sub : *expr->substitutions()) {
552 RECURSE_EXPRESSION(Visit(sub));
556 template <
class Sub
class>
557 void AstTraversalVisitor<Subclass>::VisitImportCallExpression(
558 ImportCallExpression* expr) {
559 PROCESS_EXPRESSION(expr);
560 RECURSE_EXPRESSION(Visit(expr->argument()));
563 template <
class Sub
class>
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()));
571 template <
class Sub
class>
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()));
580 template <
class Sub
class>
581 void AstTraversalVisitor<Subclass>::VisitRewritableExpression(
582 RewritableExpression* expr) {
583 PROCESS_EXPRESSION(expr);
584 RECURSE(Visit(expr->expression()));
588 #undef PROCESS_EXPRESSION 589 #undef RECURSE_EXPRESSION 595 #endif // V8_AST_AST_TRAVERSAL_VISITOR_H_