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

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

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

Powered by Google App Engine
This is Rietveld 408576698