Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1129)

Side by Side Diff: src/ast/ast-traversal-visitor.h

Issue 2169833002: [parser] Refactor AstTraversalVisitor (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/ast-expression-visitor.cc ('k') | src/debug/liveedit.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 void Run() {
35 DCHECK_NOT_NULL(root_);
36 Visit(root_);
37 }
38
39 bool VisitNode(AstNode* node) { return true; }
40 bool VisitExpression(Expression* node) { return true; }
41
42 // Iteration left-to-right.
43 void VisitDeclarations(ZoneList<Declaration*>* declarations);
44 void VisitStatements(ZoneList<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 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 : 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 : root_(root), depth_(0) {
102 InitializeAstVisitor(stack_limit);
103 }
104
105 template <class Subclass>
106 void AstTraversalVisitor<Subclass>::VisitDeclarations(
107 ZoneList<Declaration*>* decls) {
108 for (int i = 0; i < decls->length(); ++i) {
109 Declaration* decl = decls->at(i);
110 RECURSE(Visit(decl));
111 }
112 }
113
114 template <class Subclass>
115 void AstTraversalVisitor<Subclass>::VisitStatements(
116 ZoneList<Statement*>* stmts) {
117 for (int i = 0; i < stmts->length(); ++i) {
118 Statement* stmt = stmts->at(i);
119 RECURSE(Visit(stmt));
120 if (stmt->IsJump()) break;
121 }
122 }
123
124 template <class Subclass>
125 void AstTraversalVisitor<Subclass>::VisitVariableDeclaration(
126 VariableDeclaration* decl) {
127 PROCESS_NODE(decl);
128 }
129
130 template <class Subclass>
131 void AstTraversalVisitor<Subclass>::VisitFunctionDeclaration(
132 FunctionDeclaration* decl) {
133 PROCESS_NODE(decl);
134 RECURSE(Visit(decl->fun()));
135 }
136
137 template <class Subclass>
138 void AstTraversalVisitor<Subclass>::VisitBlock(Block* stmt) {
139 PROCESS_NODE(stmt);
140 RECURSE(VisitStatements(stmt->statements()));
141 }
142
143 template <class Subclass>
144 void AstTraversalVisitor<Subclass>::VisitExpressionStatement(
145 ExpressionStatement* stmt) {
146 PROCESS_NODE(stmt);
147 RECURSE(Visit(stmt->expression()));
148 }
149
150 template <class Subclass>
151 void AstTraversalVisitor<Subclass>::VisitEmptyStatement(EmptyStatement* stmt) {}
152
153 template <class Subclass>
154 void AstTraversalVisitor<Subclass>::VisitSloppyBlockFunctionStatement(
155 SloppyBlockFunctionStatement* stmt) {
156 PROCESS_NODE(stmt);
157 RECURSE(Visit(stmt->statement()));
158 }
159
160 template <class Subclass>
161 void AstTraversalVisitor<Subclass>::VisitIfStatement(IfStatement* stmt) {
162 PROCESS_NODE(stmt);
163 RECURSE(Visit(stmt->condition()));
164 RECURSE(Visit(stmt->then_statement()));
165 RECURSE(Visit(stmt->else_statement()));
166 }
167
168 template <class Subclass>
169 void AstTraversalVisitor<Subclass>::VisitContinueStatement(
170 ContinueStatement* stmt) {
171 PROCESS_NODE(stmt);
172 }
173
174 template <class Subclass>
175 void AstTraversalVisitor<Subclass>::VisitBreakStatement(BreakStatement* stmt) {
176 PROCESS_NODE(stmt);
177 }
178
179 template <class Subclass>
180 void AstTraversalVisitor<Subclass>::VisitReturnStatement(
181 ReturnStatement* stmt) {
182 PROCESS_NODE(stmt);
183 RECURSE(Visit(stmt->expression()));
184 }
185
186 template <class Subclass>
187 void AstTraversalVisitor<Subclass>::VisitWithStatement(WithStatement* stmt) {
188 PROCESS_NODE(stmt);
189 RECURSE(Visit(stmt->expression()));
190 RECURSE(Visit(stmt->statement()));
191 }
192
193 template <class Subclass>
194 void AstTraversalVisitor<Subclass>::VisitSwitchStatement(
195 SwitchStatement* stmt) {
196 PROCESS_NODE(stmt);
197 RECURSE(Visit(stmt->tag()));
198
199 ZoneList<CaseClause*>* clauses = stmt->cases();
200 for (int i = 0; i < clauses->length(); ++i) {
201 CaseClause* clause = clauses->at(i);
202 if (!clause->is_default()) {
203 Expression* label = clause->label();
204 RECURSE(Visit(label));
205 }
206 ZoneList<Statement*>* stmts = clause->statements();
207 RECURSE(VisitStatements(stmts));
208 }
209 }
210
211 template <class Subclass>
212 void AstTraversalVisitor<Subclass>::VisitCaseClause(CaseClause* clause) {
213 UNREACHABLE();
214 }
215
216 template <class Subclass>
217 void AstTraversalVisitor<Subclass>::VisitDoWhileStatement(
218 DoWhileStatement* stmt) {
219 PROCESS_NODE(stmt);
220 RECURSE(Visit(stmt->body()));
221 RECURSE(Visit(stmt->cond()));
222 }
223
224 template <class Subclass>
225 void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) {
226 PROCESS_NODE(stmt);
227 RECURSE(Visit(stmt->cond()));
228 RECURSE(Visit(stmt->body()));
229 }
230
231 template <class Subclass>
232 void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) {
233 PROCESS_NODE(stmt);
234 if (stmt->init() != NULL) {
235 RECURSE(Visit(stmt->init()));
236 }
237 if (stmt->cond() != NULL) {
238 RECURSE(Visit(stmt->cond()));
239 }
240 if (stmt->next() != NULL) {
241 RECURSE(Visit(stmt->next()));
242 }
243 RECURSE(Visit(stmt->body()));
244 }
245
246 template <class Subclass>
247 void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
248 PROCESS_NODE(stmt);
249 RECURSE(Visit(stmt->enumerable()));
250 RECURSE(Visit(stmt->body()));
251 }
252
253 template <class Subclass>
254 void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* stmt) {
255 PROCESS_NODE(stmt);
256 RECURSE(Visit(stmt->assign_iterator()));
257 RECURSE(Visit(stmt->next_result()));
258 RECURSE(Visit(stmt->result_done()));
259 RECURSE(Visit(stmt->assign_each()));
260 RECURSE(Visit(stmt->body()));
261 }
262
263 template <class Subclass>
264 void AstTraversalVisitor<Subclass>::VisitTryCatchStatement(
265 TryCatchStatement* stmt) {
266 PROCESS_NODE(stmt);
267 RECURSE(Visit(stmt->try_block()));
268 RECURSE(Visit(stmt->catch_block()));
269 }
270
271 template <class Subclass>
272 void AstTraversalVisitor<Subclass>::VisitTryFinallyStatement(
273 TryFinallyStatement* stmt) {
274 PROCESS_NODE(stmt);
275 RECURSE(Visit(stmt->try_block()));
276 RECURSE(Visit(stmt->finally_block()));
277 }
278
279 template <class Subclass>
280 void AstTraversalVisitor<Subclass>::VisitDebuggerStatement(
281 DebuggerStatement* stmt) {
282 PROCESS_NODE(stmt);
283 }
284
285 template <class Subclass>
286 void AstTraversalVisitor<Subclass>::VisitFunctionLiteral(
287 FunctionLiteral* expr) {
288 PROCESS_EXPRESSION(expr);
289 Scope* scope = expr->scope();
290 RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
291 RECURSE_EXPRESSION(VisitStatements(expr->body()));
292 }
293
294 template <class Subclass>
295 void AstTraversalVisitor<Subclass>::VisitNativeFunctionLiteral(
296 NativeFunctionLiteral* expr) {
297 PROCESS_EXPRESSION(expr);
298 }
299
300 template <class Subclass>
301 void AstTraversalVisitor<Subclass>::VisitDoExpression(DoExpression* expr) {
302 PROCESS_EXPRESSION(expr);
303 RECURSE(VisitBlock(expr->block()));
304 RECURSE(VisitVariableProxy(expr->result()));
305 }
306
307 template <class Subclass>
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()));
313 }
314
315 template <class Subclass>
316 void AstTraversalVisitor<Subclass>::VisitVariableProxy(VariableProxy* expr) {
317 PROCESS_EXPRESSION(expr);
318 }
319
320 template <class Subclass>
321 void AstTraversalVisitor<Subclass>::VisitLiteral(Literal* expr) {
322 PROCESS_EXPRESSION(expr);
323 }
324
325 template <class Subclass>
326 void AstTraversalVisitor<Subclass>::VisitRegExpLiteral(RegExpLiteral* expr) {
327 PROCESS_EXPRESSION(expr);
328 }
329
330 template <class Subclass>
331 void AstTraversalVisitor<Subclass>::VisitObjectLiteral(ObjectLiteral* expr) {
332 PROCESS_EXPRESSION(expr);
333 ZoneList<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()));
338 }
339 }
340
341 template <class Subclass>
342 void AstTraversalVisitor<Subclass>::VisitArrayLiteral(ArrayLiteral* expr) {
343 PROCESS_EXPRESSION(expr);
344 ZoneList<Expression*>* values = expr->values();
345 for (int i = 0; i < values->length(); ++i) {
346 Expression* value = values->at(i);
347 RECURSE_EXPRESSION(Visit(value));
348 }
349 }
350
351 template <class Subclass>
352 void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
353 PROCESS_EXPRESSION(expr);
354 RECURSE_EXPRESSION(Visit(expr->target()));
355 RECURSE_EXPRESSION(Visit(expr->value()));
356 }
357
358 template <class Subclass>
359 void AstTraversalVisitor<Subclass>::VisitYield(Yield* expr) {
360 PROCESS_EXPRESSION(expr);
361 RECURSE_EXPRESSION(Visit(expr->generator_object()));
362 RECURSE_EXPRESSION(Visit(expr->expression()));
363 }
364
365 template <class Subclass>
366 void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
367 PROCESS_EXPRESSION(expr);
368 RECURSE_EXPRESSION(Visit(expr->exception()));
369 }
370
371 template <class Subclass>
372 void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
373 PROCESS_EXPRESSION(expr);
374 RECURSE_EXPRESSION(Visit(expr->obj()));
375 RECURSE_EXPRESSION(Visit(expr->key()));
376 }
377
378 template <class Subclass>
379 void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
380 PROCESS_EXPRESSION(expr);
381 RECURSE_EXPRESSION(Visit(expr->expression()));
382 ZoneList<Expression*>* args = expr->arguments();
383 for (int i = 0; i < args->length(); ++i) {
384 Expression* arg = args->at(i);
385 RECURSE_EXPRESSION(Visit(arg));
386 }
387 }
388
389 template <class Subclass>
390 void AstTraversalVisitor<Subclass>::VisitCallNew(CallNew* expr) {
391 PROCESS_EXPRESSION(expr);
392 RECURSE_EXPRESSION(Visit(expr->expression()));
393 ZoneList<Expression*>* args = expr->arguments();
394 for (int i = 0; i < args->length(); ++i) {
395 Expression* arg = args->at(i);
396 RECURSE_EXPRESSION(Visit(arg));
397 }
398 }
399
400 template <class Subclass>
401 void AstTraversalVisitor<Subclass>::VisitCallRuntime(CallRuntime* expr) {
402 PROCESS_EXPRESSION(expr);
403 ZoneList<Expression*>* args = expr->arguments();
404 for (int i = 0; i < args->length(); ++i) {
405 Expression* arg = args->at(i);
406 RECURSE_EXPRESSION(Visit(arg));
407 }
408 }
409
410 template <class Subclass>
411 void AstTraversalVisitor<Subclass>::VisitUnaryOperation(UnaryOperation* expr) {
412 PROCESS_EXPRESSION(expr);
413 RECURSE_EXPRESSION(Visit(expr->expression()));
414 }
415
416 template <class Subclass>
417 void AstTraversalVisitor<Subclass>::VisitCountOperation(CountOperation* expr) {
418 PROCESS_EXPRESSION(expr);
419 RECURSE_EXPRESSION(Visit(expr->expression()));
420 }
421
422 template <class Subclass>
423 void AstTraversalVisitor<Subclass>::VisitBinaryOperation(
424 BinaryOperation* expr) {
425 PROCESS_EXPRESSION(expr);
426 RECURSE_EXPRESSION(Visit(expr->left()));
427 RECURSE_EXPRESSION(Visit(expr->right()));
428 }
429
430 template <class Subclass>
431 void AstTraversalVisitor<Subclass>::VisitCompareOperation(
432 CompareOperation* expr) {
433 PROCESS_EXPRESSION(expr);
434 RECURSE_EXPRESSION(Visit(expr->left()));
435 RECURSE_EXPRESSION(Visit(expr->right()));
436 }
437
438 template <class Subclass>
439 void AstTraversalVisitor<Subclass>::VisitThisFunction(ThisFunction* expr) {
440 PROCESS_EXPRESSION(expr);
441 }
442
443 template <class Subclass>
444 void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) {
445 PROCESS_EXPRESSION(expr);
446 if (expr->extends() != nullptr) {
447 RECURSE_EXPRESSION(Visit(expr->extends()));
448 }
449 RECURSE_EXPRESSION(Visit(expr->constructor()));
450 ZoneList<ObjectLiteralProperty*>* props = expr->properties();
451 for (int i = 0; i < props->length(); ++i) {
452 ObjectLiteralProperty* prop = props->at(i);
453 if (!prop->key()->IsLiteral()) {
454 RECURSE_EXPRESSION(Visit(prop->key()));
455 }
456 RECURSE_EXPRESSION(Visit(prop->value()));
457 }
458 }
459
460 template <class Subclass>
461 void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
462 PROCESS_EXPRESSION(expr);
463 RECURSE_EXPRESSION(Visit(expr->expression()));
464 }
465
466 template <class Subclass>
467 void AstTraversalVisitor<Subclass>::VisitEmptyParentheses(
468 EmptyParentheses* expr) {
469 PROCESS_EXPRESSION(expr);
470 }
471
472 template <class Subclass>
473 void AstTraversalVisitor<Subclass>::VisitSuperPropertyReference(
474 SuperPropertyReference* expr) {
475 PROCESS_EXPRESSION(expr);
476 RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
477 RECURSE_EXPRESSION(Visit(expr->home_object()));
478 }
479
480 template <class Subclass>
481 void AstTraversalVisitor<Subclass>::VisitSuperCallReference(
482 SuperCallReference* expr) {
483 PROCESS_EXPRESSION(expr);
484 RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
485 RECURSE_EXPRESSION(VisitVariableProxy(expr->new_target_var()));
486 RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var()));
487 }
488
489 template <class Subclass>
490 void AstTraversalVisitor<Subclass>::VisitRewritableExpression(
491 RewritableExpression* expr) {
492 PROCESS_EXPRESSION(expr);
493 RECURSE(Visit(expr->expression()));
494 }
495
496 #undef PROCESS_NODE
497 #undef PROCESS_EXPRESSION
498 #undef RECURSE_EXPRESSION
499 #undef RECURSE
500
501 } // namespace internal
502 } // namespace v8
503
504 #endif // V8_AST_AST_TRAVERSAL_VISITOR_H_
OLDNEW
« no previous file with comments | « src/ast/ast-expression-visitor.cc ('k') | src/debug/liveedit.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698