// 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/parsing/parameter-initializer-rewriter.h" #include "src/ast/ast.h" #include "src/ast/ast-expression-visitor.h" #include "src/ast/scopes.h" namespace v8 { namespace internal { namespace { class Rewriter final : public AstExpressionVisitor { public: Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* old_scope, Scope* new_scope) : AstExpressionVisitor(stack_limit, initializer), old_scope_(old_scope), new_scope_(new_scope) {} private: void VisitExpression(Expression* expr) override {} void VisitFunctionLiteral(FunctionLiteral* expr) override; void VisitClassLiteral(ClassLiteral* expr) override; void VisitVariableProxy(VariableProxy* expr) override; Scope* old_scope_; Scope* new_scope_; }; void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) { function_literal->scope()->ReplaceOuterScope(new_scope_); } void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) { class_literal->scope()->ReplaceOuterScope(new_scope_); if (class_literal->extends() != nullptr) { Visit(class_literal->extends()); } // No need to visit the constructor since it will have the class // scope on its scope chain. ZoneList<ObjectLiteralProperty*>* props = class_literal->properties(); for (int i = 0; i < props->length(); ++i) { ObjectLiteralProperty* prop = props->at(i); if (!prop->key()->IsLiteral()) { Visit(prop->key()); } // No need to visit the values, since all values are functions with // the class scope on their scope chain. DCHECK(prop->value()->IsFunctionLiteral()); } } void Rewriter::VisitVariableProxy(VariableProxy* proxy) { if (proxy->is_resolved()) { Variable* var = proxy->var(); DCHECK_EQ(var->mode(), TEMPORARY); if (old_scope_->RemoveTemporary(var)) { var->set_scope(new_scope_); new_scope_->AddTemporary(var); } } else if (old_scope_->RemoveUnresolved(proxy)) { new_scope_->AddUnresolved(proxy); } } } // anonymous namespace void RewriteParameterInitializerScope(uintptr_t stack_limit, Expression* initializer, Scope* old_scope, Scope* new_scope) { Rewriter rewriter(stack_limit, initializer, old_scope, new_scope); rewriter.Run(); } } // namespace internal } // namespace v8