Home | History | Annotate | Download | only in parsing
      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/parsing/parameter-initializer-rewriter.h"
      6 
      7 #include "src/ast/ast.h"
      8 #include "src/ast/ast-expression-visitor.h"
      9 #include "src/ast/scopes.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 namespace {
     15 
     16 
     17 class Rewriter final : public AstExpressionVisitor {
     18  public:
     19   Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* old_scope,
     20            Scope* new_scope)
     21       : AstExpressionVisitor(stack_limit, initializer),
     22         old_scope_(old_scope),
     23         new_scope_(new_scope) {}
     24 
     25  private:
     26   void VisitExpression(Expression* expr) override {}
     27 
     28   void VisitFunctionLiteral(FunctionLiteral* expr) override;
     29   void VisitClassLiteral(ClassLiteral* expr) override;
     30   void VisitVariableProxy(VariableProxy* expr) override;
     31 
     32   Scope* old_scope_;
     33   Scope* new_scope_;
     34 };
     35 
     36 
     37 void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) {
     38   function_literal->scope()->ReplaceOuterScope(new_scope_);
     39 }
     40 
     41 
     42 void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) {
     43   class_literal->scope()->ReplaceOuterScope(new_scope_);
     44   if (class_literal->extends() != nullptr) {
     45     Visit(class_literal->extends());
     46   }
     47   // No need to visit the constructor since it will have the class
     48   // scope on its scope chain.
     49   ZoneList<ObjectLiteralProperty*>* props = class_literal->properties();
     50   for (int i = 0; i < props->length(); ++i) {
     51     ObjectLiteralProperty* prop = props->at(i);
     52     if (!prop->key()->IsLiteral()) {
     53       Visit(prop->key());
     54     }
     55     // No need to visit the values, since all values are functions with
     56     // the class scope on their scope chain.
     57     DCHECK(prop->value()->IsFunctionLiteral());
     58   }
     59 }
     60 
     61 
     62 void Rewriter::VisitVariableProxy(VariableProxy* proxy) {
     63   if (proxy->is_resolved()) {
     64     Variable* var = proxy->var();
     65     DCHECK_EQ(var->mode(), TEMPORARY);
     66     if (old_scope_->RemoveTemporary(var)) {
     67       var->set_scope(new_scope_);
     68       new_scope_->AddTemporary(var);
     69     }
     70   } else if (old_scope_->RemoveUnresolved(proxy)) {
     71     new_scope_->AddUnresolved(proxy);
     72   }
     73 }
     74 
     75 
     76 }  // anonymous namespace
     77 
     78 
     79 void RewriteParameterInitializerScope(uintptr_t stack_limit,
     80                                       Expression* initializer, Scope* old_scope,
     81                                       Scope* new_scope) {
     82   Rewriter rewriter(stack_limit, initializer, old_scope, new_scope);
     83   rewriter.Run();
     84 }
     85 
     86 
     87 }  // namespace internal
     88 }  // namespace v8
     89