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 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 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 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 53 void AstExpressionRewriter::VisitVariableDeclaration( 54 VariableDeclaration* node) { 55 // Not visiting `proxy_`. 56 NOTHING(); 57 } 58 59 60 void AstExpressionRewriter::VisitFunctionDeclaration( 61 FunctionDeclaration* node) { 62 // Not visiting `proxy_`. 63 AST_REWRITE_PROPERTY(FunctionLiteral, node, fun); 64 } 65 66 67 void AstExpressionRewriter::VisitImportDeclaration(ImportDeclaration* node) { 68 // Not visiting `proxy_`. 69 NOTHING(); 70 } 71 72 73 void AstExpressionRewriter::VisitExportDeclaration(ExportDeclaration* node) { 74 // Not visiting `proxy_`. 75 NOTHING(); 76 } 77 78 79 void AstExpressionRewriter::VisitBlock(Block* node) { 80 VisitStatements(node->statements()); 81 } 82 83 84 void AstExpressionRewriter::VisitExpressionStatement( 85 ExpressionStatement* node) { 86 AST_REWRITE_PROPERTY(Expression, node, expression); 87 } 88 89 90 void AstExpressionRewriter::VisitEmptyStatement(EmptyStatement* node) { 91 NOTHING(); 92 } 93 94 95 void AstExpressionRewriter::VisitSloppyBlockFunctionStatement( 96 SloppyBlockFunctionStatement* node) { 97 AST_REWRITE_PROPERTY(Statement, node, statement); 98 } 99 100 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 108 void AstExpressionRewriter::VisitContinueStatement(ContinueStatement* node) { 109 NOTHING(); 110 } 111 112 113 void AstExpressionRewriter::VisitBreakStatement(BreakStatement* node) { 114 NOTHING(); 115 } 116 117 118 void AstExpressionRewriter::VisitReturnStatement(ReturnStatement* node) { 119 AST_REWRITE_PROPERTY(Expression, node, expression); 120 } 121 122 123 void AstExpressionRewriter::VisitWithStatement(WithStatement* node) { 124 AST_REWRITE_PROPERTY(Expression, node, expression); 125 AST_REWRITE_PROPERTY(Statement, node, statement); 126 } 127 128 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 138 void AstExpressionRewriter::VisitDoWhileStatement(DoWhileStatement* node) { 139 AST_REWRITE_PROPERTY(Expression, node, cond); 140 AST_REWRITE_PROPERTY(Statement, node, body); 141 } 142 143 144 void AstExpressionRewriter::VisitWhileStatement(WhileStatement* node) { 145 AST_REWRITE_PROPERTY(Expression, node, cond); 146 AST_REWRITE_PROPERTY(Statement, node, body); 147 } 148 149 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 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 171 void AstExpressionRewriter::VisitForOfStatement(ForOfStatement* node) { 172 AST_REWRITE_PROPERTY(Expression, node, assign_iterator); 173 AST_REWRITE_PROPERTY(Expression, node, next_result); 174 AST_REWRITE_PROPERTY(Expression, node, result_done); 175 AST_REWRITE_PROPERTY(Expression, node, assign_each); 176 AST_REWRITE_PROPERTY(Statement, node, body); 177 } 178 179 180 void AstExpressionRewriter::VisitTryCatchStatement(TryCatchStatement* node) { 181 AST_REWRITE_PROPERTY(Block, node, try_block); 182 // Not visiting the variable. 183 AST_REWRITE_PROPERTY(Block, node, catch_block); 184 } 185 186 187 void AstExpressionRewriter::VisitTryFinallyStatement( 188 TryFinallyStatement* node) { 189 AST_REWRITE_PROPERTY(Block, node, try_block); 190 AST_REWRITE_PROPERTY(Block, node, finally_block); 191 } 192 193 194 void AstExpressionRewriter::VisitDebuggerStatement(DebuggerStatement* node) { 195 NOTHING(); 196 } 197 198 199 void AstExpressionRewriter::VisitFunctionLiteral(FunctionLiteral* node) { 200 REWRITE_THIS(node); 201 VisitDeclarations(node->scope()->declarations()); 202 ZoneList<Statement*>* body = node->body(); 203 if (body != nullptr) VisitStatements(body); 204 } 205 206 207 void AstExpressionRewriter::VisitClassLiteral(ClassLiteral* node) { 208 REWRITE_THIS(node); 209 // Not visiting `class_variable_proxy_`. 210 if (node->extends() != nullptr) { 211 AST_REWRITE_PROPERTY(Expression, node, extends); 212 } 213 AST_REWRITE_PROPERTY(FunctionLiteral, node, constructor); 214 ZoneList<typename ClassLiteral::Property*>* properties = node->properties(); 215 for (int i = 0; i < properties->length(); i++) { 216 VisitObjectLiteralProperty(properties->at(i)); 217 } 218 } 219 220 221 void AstExpressionRewriter::VisitNativeFunctionLiteral( 222 NativeFunctionLiteral* node) { 223 REWRITE_THIS(node); 224 NOTHING(); 225 } 226 227 228 void AstExpressionRewriter::VisitConditional(Conditional* node) { 229 REWRITE_THIS(node); 230 AST_REWRITE_PROPERTY(Expression, node, condition); 231 AST_REWRITE_PROPERTY(Expression, node, then_expression); 232 AST_REWRITE_PROPERTY(Expression, node, else_expression); 233 } 234 235 236 void AstExpressionRewriter::VisitVariableProxy(VariableProxy* node) { 237 REWRITE_THIS(node); 238 NOTHING(); 239 } 240 241 242 void AstExpressionRewriter::VisitLiteral(Literal* node) { 243 REWRITE_THIS(node); 244 NOTHING(); 245 } 246 247 248 void AstExpressionRewriter::VisitRegExpLiteral(RegExpLiteral* node) { 249 REWRITE_THIS(node); 250 NOTHING(); 251 } 252 253 254 void AstExpressionRewriter::VisitObjectLiteral(ObjectLiteral* node) { 255 REWRITE_THIS(node); 256 ZoneList<typename ObjectLiteral::Property*>* properties = node->properties(); 257 for (int i = 0; i < properties->length(); i++) { 258 VisitObjectLiteralProperty(properties->at(i)); 259 } 260 } 261 262 263 void AstExpressionRewriter::VisitObjectLiteralProperty( 264 ObjectLiteralProperty* property) { 265 if (property == nullptr) return; 266 AST_REWRITE_PROPERTY(Expression, property, key); 267 AST_REWRITE_PROPERTY(Expression, property, value); 268 } 269 270 271 void AstExpressionRewriter::VisitArrayLiteral(ArrayLiteral* node) { 272 REWRITE_THIS(node); 273 VisitExpressions(node->values()); 274 } 275 276 277 void AstExpressionRewriter::VisitAssignment(Assignment* node) { 278 REWRITE_THIS(node); 279 AST_REWRITE_PROPERTY(Expression, node, target); 280 AST_REWRITE_PROPERTY(Expression, node, value); 281 } 282 283 284 void AstExpressionRewriter::VisitYield(Yield* node) { 285 REWRITE_THIS(node); 286 AST_REWRITE_PROPERTY(Expression, node, generator_object); 287 AST_REWRITE_PROPERTY(Expression, node, expression); 288 } 289 290 291 void AstExpressionRewriter::VisitThrow(Throw* node) { 292 REWRITE_THIS(node); 293 AST_REWRITE_PROPERTY(Expression, node, exception); 294 } 295 296 297 void AstExpressionRewriter::VisitProperty(Property* node) { 298 REWRITE_THIS(node); 299 if (node == nullptr) return; 300 AST_REWRITE_PROPERTY(Expression, node, obj); 301 AST_REWRITE_PROPERTY(Expression, node, key); 302 } 303 304 305 void AstExpressionRewriter::VisitCall(Call* node) { 306 REWRITE_THIS(node); 307 AST_REWRITE_PROPERTY(Expression, node, expression); 308 VisitExpressions(node->arguments()); 309 } 310 311 312 void AstExpressionRewriter::VisitCallNew(CallNew* node) { 313 REWRITE_THIS(node); 314 AST_REWRITE_PROPERTY(Expression, node, expression); 315 VisitExpressions(node->arguments()); 316 } 317 318 319 void AstExpressionRewriter::VisitCallRuntime(CallRuntime* node) { 320 REWRITE_THIS(node); 321 VisitExpressions(node->arguments()); 322 } 323 324 325 void AstExpressionRewriter::VisitUnaryOperation(UnaryOperation* node) { 326 REWRITE_THIS(node); 327 AST_REWRITE_PROPERTY(Expression, node, expression); 328 } 329 330 331 void AstExpressionRewriter::VisitCountOperation(CountOperation* node) { 332 REWRITE_THIS(node); 333 AST_REWRITE_PROPERTY(Expression, node, expression); 334 } 335 336 337 void AstExpressionRewriter::VisitBinaryOperation(BinaryOperation* node) { 338 REWRITE_THIS(node); 339 AST_REWRITE_PROPERTY(Expression, node, left); 340 AST_REWRITE_PROPERTY(Expression, node, right); 341 } 342 343 344 void AstExpressionRewriter::VisitCompareOperation(CompareOperation* node) { 345 REWRITE_THIS(node); 346 AST_REWRITE_PROPERTY(Expression, node, left); 347 AST_REWRITE_PROPERTY(Expression, node, right); 348 } 349 350 351 void AstExpressionRewriter::VisitSpread(Spread* node) { 352 REWRITE_THIS(node); 353 AST_REWRITE_PROPERTY(Expression, node, expression); 354 } 355 356 357 void AstExpressionRewriter::VisitThisFunction(ThisFunction* node) { 358 REWRITE_THIS(node); 359 NOTHING(); 360 } 361 362 363 void AstExpressionRewriter::VisitSuperPropertyReference( 364 SuperPropertyReference* node) { 365 REWRITE_THIS(node); 366 AST_REWRITE_PROPERTY(VariableProxy, node, this_var); 367 AST_REWRITE_PROPERTY(Expression, node, home_object); 368 } 369 370 371 void AstExpressionRewriter::VisitSuperCallReference(SuperCallReference* node) { 372 REWRITE_THIS(node); 373 AST_REWRITE_PROPERTY(VariableProxy, node, this_var); 374 AST_REWRITE_PROPERTY(VariableProxy, node, new_target_var); 375 AST_REWRITE_PROPERTY(VariableProxy, node, this_function_var); 376 } 377 378 379 void AstExpressionRewriter::VisitCaseClause(CaseClause* node) { 380 if (!node->is_default()) { 381 AST_REWRITE_PROPERTY(Expression, node, label); 382 } 383 VisitStatements(node->statements()); 384 } 385 386 387 void AstExpressionRewriter::VisitEmptyParentheses(EmptyParentheses* node) { 388 NOTHING(); 389 } 390 391 392 void AstExpressionRewriter::VisitDoExpression(DoExpression* node) { 393 REWRITE_THIS(node); 394 AST_REWRITE_PROPERTY(Block, node, block); 395 AST_REWRITE_PROPERTY(VariableProxy, node, result); 396 } 397 398 399 void AstExpressionRewriter::VisitRewritableExpression( 400 RewritableExpression* node) { 401 REWRITE_THIS(node); 402 AST_REWRITE(Expression, node->expression(), node->Rewrite(replacement)); 403 } 404 405 406 } // namespace internal 407 } // namespace v8 408