| Index: src/ast/ast-expression-rewriter.cc
|
| diff --git a/src/ast/ast-expression-rewriter.cc b/src/ast/ast-expression-rewriter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b9e451c0b6f0f6b7d40afdf38c2f99c1d98aee62
|
| --- /dev/null
|
| +++ b/src/ast/ast-expression-rewriter.cc
|
| @@ -0,0 +1,436 @@
|
| +// Copyright 2015 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "src/ast/ast.h"
|
| +#include "src/ast/ast-expression-rewriter.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +// Implementation of AstExpressionRewriter
|
| +// The AST is traversed but no actual rewriting takes place, unless the
|
| +// Visit methods are overriden in subclasses.
|
| +
|
| +#define REWRITE_THIS(node) \
|
| + do { \
|
| + if (!RewriteExpression(node)) return; \
|
| + } while (false)
|
| +#define NOTHING() DCHECK_NULL(replacement_)
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitDeclarations(
|
| + ZoneList<Declaration*>* declarations) {
|
| + for (int i = 0; i < declarations->length(); i++) {
|
| + AST_REWRITE(Declaration, declarations->at(i),
|
| + declarations->Set(i, replacement));
|
| + }
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitStatements(ZoneList<Statement*>* statements) {
|
| + for (int i = 0; i < statements->length(); i++) {
|
| + AST_REWRITE(Statement, statements->at(i), statements->Set(i, replacement));
|
| + // Not stopping when a jump statement is found.
|
| + }
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitExpressions(
|
| + ZoneList<Expression*>* expressions) {
|
| + for (int i = 0; i < expressions->length(); i++) {
|
| + // The variable statement visiting code may pass NULL expressions
|
| + // to this code. Maybe this should be handled by introducing an
|
| + // undefined expression or literal? Revisit this code if this
|
| + // changes
|
| + Expression* expression = expressions->at(i);
|
| + if (expression != nullptr) {
|
| + AST_REWRITE(Expression, expression, expressions->Set(i, replacement));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitVariableDeclaration(
|
| + VariableDeclaration* node) {
|
| + // Not visiting `proxy_`.
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitFunctionDeclaration(
|
| + FunctionDeclaration* node) {
|
| + // Not visiting `proxy_`.
|
| + AST_REWRITE(FunctionLiteral, node->fun(), node->set_fun(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitImportDeclaration(ImportDeclaration* node) {
|
| + // Not visiting `proxy_`.
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitExportDeclaration(ExportDeclaration* node) {
|
| + // Not visiting `proxy_`.
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitBlock(Block* node) {
|
| + VisitStatements(node->statements());
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitExpressionStatement(
|
| + ExpressionStatement* node) {
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitEmptyStatement(EmptyStatement* node) {
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitSloppyBlockFunctionStatement(
|
| + SloppyBlockFunctionStatement* node) {
|
| + AST_REWRITE(Statement, node->statement(), node->set_statement(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitIfStatement(IfStatement* node) {
|
| + AST_REWRITE(Expression, node->condition(), node->set_condition(replacement));
|
| + AST_REWRITE(Statement, node->then_statement(),
|
| + node->set_then_statement(replacement));
|
| + AST_REWRITE(Statement, node->else_statement(),
|
| + node->set_else_statement(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitContinueStatement(ContinueStatement* node) {
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitBreakStatement(BreakStatement* node) {
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitReturnStatement(ReturnStatement* node) {
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitWithStatement(WithStatement* node) {
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| + AST_REWRITE(Statement, node->statement(), node->set_statement(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitSwitchStatement(SwitchStatement* node) {
|
| + AST_REWRITE(Expression, node->tag(), node->set_tag(replacement));
|
| + ZoneList<CaseClause*>* clauses = node->cases();
|
| + for (int i = 0; i < clauses->length(); i++) {
|
| + AST_REWRITE(CaseClause, clauses->at(i), clauses->Set(i, replacement));
|
| + }
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitDoWhileStatement(DoWhileStatement* node) {
|
| + AST_REWRITE(Expression, node->cond(), node->set_cond(replacement));
|
| + AST_REWRITE(Statement, node->body(), node->set_body(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitWhileStatement(WhileStatement* node) {
|
| + AST_REWRITE(Expression, node->cond(), node->set_cond(replacement));
|
| + AST_REWRITE(Statement, node->body(), node->set_body(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitForStatement(ForStatement* node) {
|
| + if (node->init() != nullptr) {
|
| + AST_REWRITE(Statement, node->init(), node->set_init(replacement));
|
| + }
|
| + if (node->cond() != nullptr) {
|
| + AST_REWRITE(Expression, node->cond(), node->set_cond(replacement));
|
| + }
|
| + if (node->next() != nullptr) {
|
| + AST_REWRITE(Statement, node->next(), node->set_next(replacement));
|
| + }
|
| + AST_REWRITE(Statement, node->body(), node->set_body(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitForInStatement(ForInStatement* node) {
|
| + AST_REWRITE(Expression, node->each(), node->set_each(replacement));
|
| + AST_REWRITE(Expression, node->subject(), node->set_subject(replacement));
|
| + AST_REWRITE(Statement, node->body(), node->set_body(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitForOfStatement(ForOfStatement* node) {
|
| + AST_REWRITE(Expression, node->each(), node->set_each(replacement));
|
| + AST_REWRITE(Expression, node->assign_iterator(),
|
| + node->set_assign_iterator(replacement));
|
| + AST_REWRITE(Expression, node->next_result(),
|
| + node->set_next_result(replacement));
|
| + AST_REWRITE(Expression, node->result_done(),
|
| + node->set_result_done(replacement));
|
| + AST_REWRITE(Expression, node->assign_each(),
|
| + node->set_assign_each(replacement));
|
| + AST_REWRITE(Expression, node->subject(), node->set_subject(replacement));
|
| + AST_REWRITE(Statement, node->body(), node->set_body(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitTryCatchStatement(TryCatchStatement* node) {
|
| + AST_REWRITE(Block, node->try_block(), node->set_try_block(replacement));
|
| + // Not visiting the variable.
|
| + AST_REWRITE(Block, node->catch_block(), node->set_catch_block(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitTryFinallyStatement(
|
| + TryFinallyStatement* node) {
|
| + AST_REWRITE(Block, node->try_block(), node->set_try_block(replacement));
|
| + AST_REWRITE(Block, node->finally_block(),
|
| + node->set_finally_block(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitDebuggerStatement(DebuggerStatement* node) {
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitFunctionLiteral(FunctionLiteral* node) {
|
| + REWRITE_THIS(node);
|
| + VisitDeclarations(node->scope()->declarations());
|
| + ZoneList<Statement*>* body = node->body();
|
| + if (body != nullptr) VisitStatements(body);
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitClassLiteral(ClassLiteral* node) {
|
| + REWRITE_THIS(node);
|
| + // Not visiting `class_variable_proxy_`.
|
| + Expression* extends = node->extends();
|
| + if (extends != nullptr) {
|
| + AST_REWRITE(Expression, extends, node->set_extends(replacement));
|
| + }
|
| + AST_REWRITE(FunctionLiteral, node->constructor(),
|
| + node->set_constructor(replacement));
|
| + ZoneList<typename ClassLiteral::Property*>* properties = node->properties();
|
| + for (int i = 0; i < properties->length(); i++) {
|
| + VisitObjectLiteralProperty(properties->at(i));
|
| + }
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitNativeFunctionLiteral(
|
| + NativeFunctionLiteral* node) {
|
| + REWRITE_THIS(node);
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitConditional(Conditional* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->condition(), node->set_condition(replacement));
|
| + AST_REWRITE(Expression, node->then_expression(),
|
| + node->set_then_expression(replacement));
|
| + AST_REWRITE(Expression, node->else_expression(),
|
| + node->set_else_expression(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitVariableProxy(VariableProxy* node) {
|
| + REWRITE_THIS(node);
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitLiteral(Literal* node) {
|
| + REWRITE_THIS(node);
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitRegExpLiteral(RegExpLiteral* node) {
|
| + REWRITE_THIS(node);
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitObjectLiteral(ObjectLiteral* node) {
|
| + REWRITE_THIS(node);
|
| + ZoneList<typename ObjectLiteral::Property*>* properties = node->properties();
|
| + for (int i = 0; i < properties->length(); i++) {
|
| + VisitObjectLiteralProperty(properties->at(i));
|
| + }
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitObjectLiteralProperty(
|
| + ObjectLiteralProperty* property) {
|
| + if (property == nullptr) return;
|
| + AST_REWRITE(Expression, property->key(), property->set_key(replacement));
|
| + AST_REWRITE(Expression, property->value(), property->set_value(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitArrayLiteral(ArrayLiteral* node) {
|
| + REWRITE_THIS(node);
|
| + VisitExpressions(node->values());
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitAssignment(Assignment* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->target(), node->set_target(replacement));
|
| + AST_REWRITE(Expression, node->value(), node->set_value(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitYield(Yield* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->generator_object(),
|
| + node->set_generator_object(replacement));
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitThrow(Throw* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->exception(), node->set_exception(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitProperty(Property* node) {
|
| + REWRITE_THIS(node);
|
| + if (node == nullptr) return;
|
| + AST_REWRITE(Expression, node->obj(), node->set_obj(replacement));
|
| + AST_REWRITE(Expression, node->key(), node->set_key(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitCall(Call* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| + VisitExpressions(node->arguments());
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitCallNew(CallNew* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| + VisitExpressions(node->arguments());
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitCallRuntime(CallRuntime* node) {
|
| + REWRITE_THIS(node);
|
| + VisitExpressions(node->arguments());
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitUnaryOperation(UnaryOperation* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitCountOperation(CountOperation* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitBinaryOperation(BinaryOperation* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->left(), node->set_left(replacement));
|
| + AST_REWRITE(Expression, node->right(), node->set_right(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitCompareOperation(CompareOperation* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->left(), node->set_left(replacement));
|
| + AST_REWRITE(Expression, node->right(), node->set_right(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitSpread(Spread* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitThisFunction(ThisFunction* node) {
|
| + REWRITE_THIS(node);
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitSuperPropertyReference(
|
| + SuperPropertyReference* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(VariableProxy, node->this_var(), node->set_this_var(replacement));
|
| + AST_REWRITE(Expression, node->home_object(),
|
| + node->set_home_object(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitSuperCallReference(SuperCallReference* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(VariableProxy, node->this_var(), node->set_this_var(replacement));
|
| + AST_REWRITE(VariableProxy, node->new_target_var(),
|
| + node->set_new_target_var(replacement));
|
| + AST_REWRITE(VariableProxy, node->this_function_var(),
|
| + node->set_this_function_var(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitCaseClause(CaseClause* node) {
|
| + if (!node->is_default()) {
|
| + AST_REWRITE(Expression, node->label(), node->set_label(replacement));
|
| + }
|
| + VisitStatements(node->statements());
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitEmptyParentheses(EmptyParentheses* node) {
|
| + NOTHING();
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitDoExpression(DoExpression* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Block, node->block(), node->set_block(replacement));
|
| + AST_REWRITE(VariableProxy, node->result(), node->set_result(replacement));
|
| +}
|
| +
|
| +
|
| +void AstExpressionRewriter::VisitRewritableAssignmentExpression(
|
| + RewritableAssignmentExpression* node) {
|
| + REWRITE_THIS(node);
|
| + AST_REWRITE(Expression, node->expression(),
|
| + node->set_expression(replacement));
|
| +}
|
| +
|
| +
|
| +} // namespace internal
|
| +} // namespace v8
|
|
|