parameter-initializer-rewriter.cc 2.27 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
// 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/parameter-initializer-rewriter.h"

#include "src/ast.h"
#include "src/ast-expression-visitor.h"
#include "src/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) {
  DCHECK(!proxy->is_resolved());
  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