1 // Copyright 2015 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 #include "src/ast/ast.h"
6 #include "src/ast/ast-expression-rewriter.h"
7 
8 namespace v8 {
9 namespace internal {
10 
11 // ----------------------------------------------------------------------------
12 // Implementation of AstExpressionRewriter
13 // The AST is traversed but no actual rewriting takes place, unless the
14 // Visit methods are overriden in subclasses.
15 
16 #define REWRITE_THIS(node)                \
17   do {                                    \
18     if (!RewriteExpression(node)) return; \
19   } while (false)
20 #define NOTHING() DCHECK_NULL(replacement_)
21 
22 
VisitDeclarations(ZoneList<Declaration * > * declarations)23 void AstExpressionRewriter::VisitDeclarations(
24     ZoneList<Declaration*>* declarations) {
25   for (int i = 0; i < declarations->length(); i++) {
26     AST_REWRITE_LIST_ELEMENT(Declaration, declarations, i);
27   }
28 }
29 
30 
VisitStatements(ZoneList<Statement * > * statements)31 void AstExpressionRewriter::VisitStatements(ZoneList<Statement*>* statements) {
32   for (int i = 0; i < statements->length(); i++) {
33     AST_REWRITE_LIST_ELEMENT(Statement, statements, i);
34     // Not stopping when a jump statement is found.
35   }
36 }
37 
38 
VisitExpressions(ZoneList<Expression * > * expressions)39 void AstExpressionRewriter::VisitExpressions(
40     ZoneList<Expression*>* expressions) {
41   for (int i = 0; i < expressions->length(); i++) {
42     // The variable statement visiting code may pass NULL expressions
43     // to this code. Maybe this should be handled by introducing an
44     // undefined expression or literal?  Revisit this code if this
45     // changes
46     if (expressions->at(i) != nullptr) {
47       AST_REWRITE_LIST_ELEMENT(Expression, expressions, i);
48     }
49   }
50 }
51 
52 
VisitVariableDeclaration(VariableDeclaration * node)53 void AstExpressionRewriter::VisitVariableDeclaration(
54     VariableDeclaration* node) {
55   // Not visiting `proxy_`.
56   NOTHING();
57 }
58 
59 
VisitFunctionDeclaration(FunctionDeclaration * node)60 void AstExpressionRewriter::VisitFunctionDeclaration(
61     FunctionDeclaration* node) {
62   // Not visiting `proxy_`.
63   AST_REWRITE_PROPERTY(FunctionLiteral, node, fun);
64 }
65 
66 
VisitImportDeclaration(ImportDeclaration * node)67 void AstExpressionRewriter::VisitImportDeclaration(ImportDeclaration* node) {
68   // Not visiting `proxy_`.
69   NOTHING();
70 }
71 
72 
VisitExportDeclaration(ExportDeclaration * node)73 void AstExpressionRewriter::VisitExportDeclaration(ExportDeclaration* node) {
74   // Not visiting `proxy_`.
75   NOTHING();
76 }
77 
78 
VisitBlock(Block * node)79 void AstExpressionRewriter::VisitBlock(Block* node) {
80   VisitStatements(node->statements());
81 }
82 
83 
VisitExpressionStatement(ExpressionStatement * node)84 void AstExpressionRewriter::VisitExpressionStatement(
85     ExpressionStatement* node) {
86   AST_REWRITE_PROPERTY(Expression, node, expression);
87 }
88 
89 
VisitEmptyStatement(EmptyStatement * node)90 void AstExpressionRewriter::VisitEmptyStatement(EmptyStatement* node) {
91   NOTHING();
92 }
93 
94 
VisitSloppyBlockFunctionStatement(SloppyBlockFunctionStatement * node)95 void AstExpressionRewriter::VisitSloppyBlockFunctionStatement(
96     SloppyBlockFunctionStatement* node) {
97   AST_REWRITE_PROPERTY(Statement, node, statement);
98 }
99 
100 
VisitIfStatement(IfStatement * node)101 void AstExpressionRewriter::VisitIfStatement(IfStatement* node) {
102   AST_REWRITE_PROPERTY(Expression, node, condition);
103   AST_REWRITE_PROPERTY(Statement, node, then_statement);
104   AST_REWRITE_PROPERTY(Statement, node, else_statement);
105 }
106 
107 
VisitContinueStatement(ContinueStatement * node)108 void AstExpressionRewriter::VisitContinueStatement(ContinueStatement* node) {
109   NOTHING();
110 }
111 
112 
VisitBreakStatement(BreakStatement * node)113 void AstExpressionRewriter::VisitBreakStatement(BreakStatement* node) {
114   NOTHING();
115 }
116 
117 
VisitReturnStatement(ReturnStatement * node)118 void AstExpressionRewriter::VisitReturnStatement(ReturnStatement* node) {
119   AST_REWRITE_PROPERTY(Expression, node, expression);
120 }
121 
122 
VisitWithStatement(WithStatement * node)123 void AstExpressionRewriter::VisitWithStatement(WithStatement* node) {
124   AST_REWRITE_PROPERTY(Expression, node, expression);
125   AST_REWRITE_PROPERTY(Statement, node, statement);
126 }
127 
128 
VisitSwitchStatement(SwitchStatement * node)129 void AstExpressionRewriter::VisitSwitchStatement(SwitchStatement* node) {
130   AST_REWRITE_PROPERTY(Expression, node, tag);
131   ZoneList<CaseClause*>* clauses = node->cases();
132   for (int i = 0; i < clauses->length(); i++) {
133     AST_REWRITE_LIST_ELEMENT(CaseClause, clauses, i);
134   }
135 }
136 
137 
VisitDoWhileStatement(DoWhileStatement * node)138 void AstExpressionRewriter::VisitDoWhileStatement(DoWhileStatement* node) {
139   AST_REWRITE_PROPERTY(Expression, node, cond);
140   AST_REWRITE_PROPERTY(Statement, node, body);
141 }
142 
143 
VisitWhileStatement(WhileStatement * node)144 void AstExpressionRewriter::VisitWhileStatement(WhileStatement* node) {
145   AST_REWRITE_PROPERTY(Expression, node, cond);
146   AST_REWRITE_PROPERTY(Statement, node, body);
147 }
148 
149 
VisitForStatement(ForStatement * node)150 void AstExpressionRewriter::VisitForStatement(ForStatement* node) {
151   if (node->init() != nullptr) {
152     AST_REWRITE_PROPERTY(Statement, node, init);
153   }
154   if (node->cond() != nullptr) {
155     AST_REWRITE_PROPERTY(Expression, node, cond);
156   }
157   if (node->next() != nullptr) {
158     AST_REWRITE_PROPERTY(Statement, node, next);
159   }
160   AST_REWRITE_PROPERTY(Statement, node, body);
161 }
162 
163 
VisitForInStatement(ForInStatement * node)164 void AstExpressionRewriter::VisitForInStatement(ForInStatement* node) {
165   AST_REWRITE_PROPERTY(Expression, node, each);
166   AST_REWRITE_PROPERTY(Expression, node, subject);
167   AST_REWRITE_PROPERTY(Statement, node, body);
168 }
169 
170 
VisitForOfStatement(ForOfStatement * node)171 void AstExpressionRewriter::VisitForOfStatement(ForOfStatement* node) {
172   AST_REWRITE_PROPERTY(Expression, node, each);
173   AST_REWRITE_PROPERTY(Expression, node, assign_iterator);
174   AST_REWRITE_PROPERTY(Expression, node, next_result);
175   AST_REWRITE_PROPERTY(Expression, node, result_done);
176   AST_REWRITE_PROPERTY(Expression, node, assign_each);
177   AST_REWRITE_PROPERTY(Expression, node, subject);
178   AST_REWRITE_PROPERTY(Statement, node, body);
179 }
180 
181 
VisitTryCatchStatement(TryCatchStatement * node)182 void AstExpressionRewriter::VisitTryCatchStatement(TryCatchStatement* node) {
183   AST_REWRITE_PROPERTY(Block, node, try_block);
184   // Not visiting the variable.
185   AST_REWRITE_PROPERTY(Block, node, catch_block);
186 }
187 
188 
VisitTryFinallyStatement(TryFinallyStatement * node)189 void AstExpressionRewriter::VisitTryFinallyStatement(
190     TryFinallyStatement* node) {
191   AST_REWRITE_PROPERTY(Block, node, try_block);
192   AST_REWRITE_PROPERTY(Block, node, finally_block);
193 }
194 
195 
VisitDebuggerStatement(DebuggerStatement * node)196 void AstExpressionRewriter::VisitDebuggerStatement(DebuggerStatement* node) {
197   NOTHING();
198 }
199 
200 
VisitFunctionLiteral(FunctionLiteral * node)201 void AstExpressionRewriter::VisitFunctionLiteral(FunctionLiteral* node) {
202   REWRITE_THIS(node);
203   VisitDeclarations(node->scope()->declarations());
204   ZoneList<Statement*>* body = node->body();
205   if (body != nullptr) VisitStatements(body);
206 }
207 
208 
VisitClassLiteral(ClassLiteral * node)209 void AstExpressionRewriter::VisitClassLiteral(ClassLiteral* node) {
210   REWRITE_THIS(node);
211   // Not visiting `class_variable_proxy_`.
212   if (node->extends() != nullptr) {
213     AST_REWRITE_PROPERTY(Expression, node, extends);
214   }
215   AST_REWRITE_PROPERTY(FunctionLiteral, node, constructor);
216   ZoneList<typename ClassLiteral::Property*>* properties = node->properties();
217   for (int i = 0; i < properties->length(); i++) {
218     VisitObjectLiteralProperty(properties->at(i));
219   }
220 }
221 
222 
VisitNativeFunctionLiteral(NativeFunctionLiteral * node)223 void AstExpressionRewriter::VisitNativeFunctionLiteral(
224     NativeFunctionLiteral* node) {
225   REWRITE_THIS(node);
226   NOTHING();
227 }
228 
229 
VisitConditional(Conditional * node)230 void AstExpressionRewriter::VisitConditional(Conditional* node) {
231   REWRITE_THIS(node);
232   AST_REWRITE_PROPERTY(Expression, node, condition);
233   AST_REWRITE_PROPERTY(Expression, node, then_expression);
234   AST_REWRITE_PROPERTY(Expression, node, else_expression);
235 }
236 
237 
VisitVariableProxy(VariableProxy * node)238 void AstExpressionRewriter::VisitVariableProxy(VariableProxy* node) {
239   REWRITE_THIS(node);
240   NOTHING();
241 }
242 
243 
VisitLiteral(Literal * node)244 void AstExpressionRewriter::VisitLiteral(Literal* node) {
245   REWRITE_THIS(node);
246   NOTHING();
247 }
248 
249 
VisitRegExpLiteral(RegExpLiteral * node)250 void AstExpressionRewriter::VisitRegExpLiteral(RegExpLiteral* node) {
251   REWRITE_THIS(node);
252   NOTHING();
253 }
254 
255 
VisitObjectLiteral(ObjectLiteral * node)256 void AstExpressionRewriter::VisitObjectLiteral(ObjectLiteral* node) {
257   REWRITE_THIS(node);
258   ZoneList<typename ObjectLiteral::Property*>* properties = node->properties();
259   for (int i = 0; i < properties->length(); i++) {
260     VisitObjectLiteralProperty(properties->at(i));
261   }
262 }
263 
264 
VisitObjectLiteralProperty(ObjectLiteralProperty * property)265 void AstExpressionRewriter::VisitObjectLiteralProperty(
266     ObjectLiteralProperty* property) {
267   if (property == nullptr) return;
268   AST_REWRITE_PROPERTY(Expression, property, key);
269   AST_REWRITE_PROPERTY(Expression, property, value);
270 }
271 
272 
VisitArrayLiteral(ArrayLiteral * node)273 void AstExpressionRewriter::VisitArrayLiteral(ArrayLiteral* node) {
274   REWRITE_THIS(node);
275   VisitExpressions(node->values());
276 }
277 
278 
VisitAssignment(Assignment * node)279 void AstExpressionRewriter::VisitAssignment(Assignment* node) {
280   REWRITE_THIS(node);
281   AST_REWRITE_PROPERTY(Expression, node, target);
282   AST_REWRITE_PROPERTY(Expression, node, value);
283 }
284 
285 
VisitYield(Yield * node)286 void AstExpressionRewriter::VisitYield(Yield* node) {
287   REWRITE_THIS(node);
288   AST_REWRITE_PROPERTY(Expression, node, generator_object);
289   AST_REWRITE_PROPERTY(Expression, node, expression);
290 }
291 
292 
VisitThrow(Throw * node)293 void AstExpressionRewriter::VisitThrow(Throw* node) {
294   REWRITE_THIS(node);
295   AST_REWRITE_PROPERTY(Expression, node, exception);
296 }
297 
298 
VisitProperty(Property * node)299 void AstExpressionRewriter::VisitProperty(Property* node) {
300   REWRITE_THIS(node);
301   if (node == nullptr) return;
302   AST_REWRITE_PROPERTY(Expression, node, obj);
303   AST_REWRITE_PROPERTY(Expression, node, key);
304 }
305 
306 
VisitCall(Call * node)307 void AstExpressionRewriter::VisitCall(Call* node) {
308   REWRITE_THIS(node);
309   AST_REWRITE_PROPERTY(Expression, node, expression);
310   VisitExpressions(node->arguments());
311 }
312 
313 
VisitCallNew(CallNew * node)314 void AstExpressionRewriter::VisitCallNew(CallNew* node) {
315   REWRITE_THIS(node);
316   AST_REWRITE_PROPERTY(Expression, node, expression);
317   VisitExpressions(node->arguments());
318 }
319 
320 
VisitCallRuntime(CallRuntime * node)321 void AstExpressionRewriter::VisitCallRuntime(CallRuntime* node) {
322   REWRITE_THIS(node);
323   VisitExpressions(node->arguments());
324 }
325 
326 
VisitUnaryOperation(UnaryOperation * node)327 void AstExpressionRewriter::VisitUnaryOperation(UnaryOperation* node) {
328   REWRITE_THIS(node);
329   AST_REWRITE_PROPERTY(Expression, node, expression);
330 }
331 
332 
VisitCountOperation(CountOperation * node)333 void AstExpressionRewriter::VisitCountOperation(CountOperation* node) {
334   REWRITE_THIS(node);
335   AST_REWRITE_PROPERTY(Expression, node, expression);
336 }
337 
338 
VisitBinaryOperation(BinaryOperation * node)339 void AstExpressionRewriter::VisitBinaryOperation(BinaryOperation* node) {
340   REWRITE_THIS(node);
341   AST_REWRITE_PROPERTY(Expression, node, left);
342   AST_REWRITE_PROPERTY(Expression, node, right);
343 }
344 
345 
VisitCompareOperation(CompareOperation * node)346 void AstExpressionRewriter::VisitCompareOperation(CompareOperation* node) {
347   REWRITE_THIS(node);
348   AST_REWRITE_PROPERTY(Expression, node, left);
349   AST_REWRITE_PROPERTY(Expression, node, right);
350 }
351 
352 
VisitSpread(Spread * node)353 void AstExpressionRewriter::VisitSpread(Spread* node) {
354   REWRITE_THIS(node);
355   AST_REWRITE_PROPERTY(Expression, node, expression);
356 }
357 
358 
VisitThisFunction(ThisFunction * node)359 void AstExpressionRewriter::VisitThisFunction(ThisFunction* node) {
360   REWRITE_THIS(node);
361   NOTHING();
362 }
363 
364 
VisitSuperPropertyReference(SuperPropertyReference * node)365 void AstExpressionRewriter::VisitSuperPropertyReference(
366     SuperPropertyReference* node) {
367   REWRITE_THIS(node);
368   AST_REWRITE_PROPERTY(VariableProxy, node, this_var);
369   AST_REWRITE_PROPERTY(Expression, node, home_object);
370 }
371 
372 
VisitSuperCallReference(SuperCallReference * node)373 void AstExpressionRewriter::VisitSuperCallReference(SuperCallReference* node) {
374   REWRITE_THIS(node);
375   AST_REWRITE_PROPERTY(VariableProxy, node, this_var);
376   AST_REWRITE_PROPERTY(VariableProxy, node, new_target_var);
377   AST_REWRITE_PROPERTY(VariableProxy, node, this_function_var);
378 }
379 
380 
VisitCaseClause(CaseClause * node)381 void AstExpressionRewriter::VisitCaseClause(CaseClause* node) {
382   if (!node->is_default()) {
383     AST_REWRITE_PROPERTY(Expression, node, label);
384   }
385   VisitStatements(node->statements());
386 }
387 
388 
VisitEmptyParentheses(EmptyParentheses * node)389 void AstExpressionRewriter::VisitEmptyParentheses(EmptyParentheses* node) {
390   NOTHING();
391 }
392 
393 
VisitDoExpression(DoExpression * node)394 void AstExpressionRewriter::VisitDoExpression(DoExpression* node) {
395   REWRITE_THIS(node);
396   AST_REWRITE_PROPERTY(Block, node, block);
397   AST_REWRITE_PROPERTY(VariableProxy, node, result);
398 }
399 
400 
VisitRewritableAssignmentExpression(RewritableAssignmentExpression * node)401 void AstExpressionRewriter::VisitRewritableAssignmentExpression(
402     RewritableAssignmentExpression* node) {
403   REWRITE_THIS(node);
404   AST_REWRITE_PROPERTY(Expression, node, expression);
405 }
406 
407 
408 }  // namespace internal
409 }  // namespace v8
410