// 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/expression-scope-reparenter.h"

#include "src/ast/ast-traversal-visitor.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/objects/objects-inl.h"

namespace v8 {
namespace internal {

namespace {

class Reparenter final : public AstTraversalVisitor<Reparenter> {
 public:
  Reparenter(uintptr_t stack_limit, Expression* initializer, Scope* scope)
      : AstTraversalVisitor(stack_limit, initializer), scope_(scope) {}

 private:
  // This is required so that the overriden Visit* methods can be
  // called by the base class (template).
  friend class AstTraversalVisitor<Reparenter>;

  void VisitFunctionLiteral(FunctionLiteral* expr);
  void VisitClassLiteral(ClassLiteral* expr);
  void VisitVariableProxy(VariableProxy* expr);

  void VisitBlock(Block* stmt);
  void VisitTryCatchStatement(TryCatchStatement* stmt);
  void VisitWithStatement(WithStatement* stmt);

  Scope* scope_;
};

void Reparenter::VisitFunctionLiteral(FunctionLiteral* function_literal) {
  function_literal->scope()->ReplaceOuterScope(scope_);
}

void Reparenter::VisitClassLiteral(ClassLiteral* class_literal) {
  class_literal->scope()->ReplaceOuterScope(scope_);
  // No need to visit the constructor since it will have the class
  // scope on its scope chain.
  DCHECK_EQ(class_literal->constructor()->scope()->outer_scope(),
            class_literal->scope());

  if (class_literal->static_fields_initializer() != nullptr) {
    DCHECK_EQ(
        class_literal->static_fields_initializer()->scope()->outer_scope(),
        class_literal->scope());
  }
#if DEBUG
  // The same goes for the rest of the class, but we do some
  // sanity checking in debug mode.
  for (ClassLiteralProperty* prop : *class_literal->properties()) {
    // No need to visit the values, since all values are functions with
    // the class scope on their scope chain.
    DCHECK(prop->value()->IsFunctionLiteral());
    DCHECK_EQ(prop->value()->AsFunctionLiteral()->scope()->outer_scope(),
              class_literal->scope());
  }
#endif
}

void Reparenter::VisitVariableProxy(VariableProxy* proxy) {
  if (!proxy->is_resolved()) {
    if (scope_->outer_scope()->RemoveUnresolved(proxy)) {
      scope_->AddUnresolved(proxy);
    }
  } else {
    // Ensure that temporaries we find are already in the correct scope.
    DCHECK(proxy->var()->mode() != VariableMode::kTemporary ||
           proxy->var()->scope() == scope_->GetClosureScope());
  }
}

void Reparenter::VisitBlock(Block* stmt) {
  if (stmt->scope())
    stmt->scope()->ReplaceOuterScope(scope_);
  else
    VisitStatements(stmt->statements());
}

void Reparenter::VisitTryCatchStatement(TryCatchStatement* stmt) {
  Visit(stmt->try_block());
  if (stmt->scope()) {
    stmt->scope()->ReplaceOuterScope(scope_);
  } else {
    Visit(stmt->catch_block());
  }
}

void Reparenter::VisitWithStatement(WithStatement* stmt) {
  Visit(stmt->expression());
  stmt->scope()->ReplaceOuterScope(scope_);
}

}  // anonymous namespace

void ReparentExpressionScope(uintptr_t stack_limit, Expression* expr,
                             Scope* scope) {
  // The only case that uses this code is block scopes for parameters containing
  // sloppy eval.
  DCHECK(scope->is_block_scope());
  DCHECK(scope->is_declaration_scope());
  DCHECK(scope->AsDeclarationScope()->calls_sloppy_eval());
  DCHECK(scope->outer_scope()->is_function_scope());

  Reparenter r(stack_limit, expr, scope);
  r.Run();
}

}  // namespace internal
}  // namespace v8
