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