LCOV - code coverage report
Current view: top level - src/ast - ast-traversal-visitor.h (source / functions) Hit Total Coverage
Test: app.info Lines: 185 224 82.6 %
Date: 2019-03-21 Functions: 107 227 47.1 %

          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_

Generated by: LCOV version 1.10