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