// 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.h"
#include "src/messages.h"
#include "src/parser.h"

namespace v8 {

namespace internal {


void Parser::PatternRewriter::DeclareAndInitializeVariables(
    Block* block, const DeclarationDescriptor* declaration_descriptor,
    const DeclarationParsingResult::Declaration* declaration,
    ZoneList<const AstRawString*>* names, bool* ok) {
  PatternRewriter rewriter;

  rewriter.pattern_ = declaration->pattern;
  rewriter.initializer_position_ = declaration->initializer_position;
  rewriter.block_ = block;
  rewriter.descriptor_ = declaration_descriptor;
  rewriter.names_ = names;
  rewriter.ok_ = ok;

  rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
}


void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
  Expression* value = current_value_;
  descriptor_->scope->RemoveUnresolved(pattern);

  // Declare variable.
  // Note that we *always* must treat the initial value via a separate init
  // assignment for variables and constants because the value must be assigned
  // when the variable is encountered in the source. But the variable/constant
  // is declared (and set to 'undefined') upon entering the function within
  // which the variable or constant is declared. Only function variables have
  // an initial value in the declaration (because they are initialized upon
  // entering the function).
  //
  // If we have a legacy const declaration, in an inner scope, the proxy
  // is always bound to the declared variable (independent of possibly
  // surrounding 'with' statements).
  // For let/const declarations in harmony mode, we can also immediately
  // pre-resolve the proxy because it resides in the same scope as the
  // declaration.
  Parser* parser = descriptor_->parser;
  const AstRawString* name = pattern->raw_name();
  VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode);
  Declaration* declaration = factory()->NewVariableDeclaration(
      proxy, descriptor_->mode, descriptor_->scope,
      descriptor_->declaration_pos);
  Variable* var = parser->Declare(declaration, descriptor_->declaration_kind,
                                  descriptor_->mode != VAR, ok_,
                                  descriptor_->hoist_scope);
  if (!*ok_) return;
  DCHECK_NOT_NULL(var);
  DCHECK(!proxy->is_resolved() || proxy->var() == var);
  var->set_initializer_position(initializer_position_);

  DCHECK(initializer_position_ != RelocInfo::kNoPosition);

  if (descriptor_->declaration_scope->num_var_or_const() >
      kMaxNumFunctionLocals) {
    parser->ReportMessage(MessageTemplate::kTooManyVariables);
    *ok_ = false;
    return;
  }
  if (names_) {
    names_->Add(name, zone());
  }

  // Initialize variables if needed. A
  // declaration of the form:
  //
  //    var v = x;
  //
  // is syntactic sugar for:
  //
  //    var v; v = x;
  //
  // In particular, we need to re-lookup 'v' (in scope_, not
  // declaration_scope) as it may be a different 'v' than the 'v' in the
  // declaration (e.g., if we are inside a 'with' statement or 'catch'
  // block).
  //
  // However, note that const declarations are different! A const
  // declaration of the form:
  //
  //   const c = x;
  //
  // is *not* syntactic sugar for:
  //
  //   const c; c = x;
  //
  // The "variable" c initialized to x is the same as the declared
  // one - there is no re-lookup (see the last parameter of the
  // Declare() call above).
  Scope* initialization_scope = descriptor_->is_const
                                    ? descriptor_->declaration_scope
                                    : descriptor_->scope;


  // Global variable declarations must be compiled in a specific
  // way. When the script containing the global variable declaration
  // is entered, the global variable must be declared, so that if it
  // doesn't exist (on the global object itself, see ES5 errata) it
  // gets created with an initial undefined value. This is handled
  // by the declarations part of the function representing the
  // top-level global code; see Runtime::DeclareGlobalVariable. If
  // it already exists (in the object or in a prototype), it is
  // *not* touched until the variable declaration statement is
  // executed.
  //
  // Executing the variable declaration statement will always
  // guarantee to give the global object an own property.
  // This way, global variable declarations can shadow
  // properties in the prototype chain, but only after the variable
  // declaration statement has been executed. This is important in
  // browsers where the global object (window) has lots of
  // properties defined in prototype objects.
  if (initialization_scope->is_script_scope() &&
      !IsLexicalVariableMode(descriptor_->mode)) {
    // Compute the arguments for the runtime
    // call.test-parsing/InitializedDeclarationsInStrictForOfError
    ZoneList<Expression*>* arguments =
        new (zone()) ZoneList<Expression*>(3, zone());
    // We have at least 1 parameter.
    arguments->Add(
        factory()->NewStringLiteral(name, descriptor_->declaration_pos),
        zone());
    CallRuntime* initialize;

    if (descriptor_->is_const) {
      arguments->Add(value, zone());
      value = NULL;  // zap the value to avoid the unnecessary assignment

      // Construct the call to Runtime_InitializeConstGlobal
      // and add it to the initialization statement block.
      // Note that the function does different things depending on
      // the number of arguments (1 or 2).
      initialize =
          factory()->NewCallRuntime(Runtime::kInitializeConstGlobal, arguments,
                                    descriptor_->initialization_pos);
    } else {
      // Add language mode.
      // We may want to pass singleton to avoid Literal allocations.
      LanguageMode language_mode = initialization_scope->language_mode();
      arguments->Add(factory()->NewNumberLiteral(language_mode,
                                                 descriptor_->declaration_pos),
                     zone());

      // Be careful not to assign a value to the global variable if
      // we're in a with. The initialization value should not
      // necessarily be stored in the global object in that case,
      // which is why we need to generate a separate assignment node.
      if (value != NULL && !inside_with()) {
        arguments->Add(value, zone());
        value = NULL;  // zap the value to avoid the unnecessary assignment
        // Construct the call to Runtime_InitializeVarGlobal
        // and add it to the initialization statement block.
        initialize =
            factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments,
                                      descriptor_->declaration_pos);
      } else {
        initialize = NULL;
      }
    }

    if (initialize != NULL) {
      block_->statements()->Add(
          factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
          zone());
    }
  } else if (value != nullptr && (descriptor_->needs_init ||
                                  IsLexicalVariableMode(descriptor_->mode))) {
    // Constant initializations always assign to the declared constant which
    // is always at the function scope level. This is only relevant for
    // dynamically looked-up variables and constants (the
    // start context for constant lookups is always the function context,
    // while it is the top context for var declared variables). Sigh...
    // For 'let' and 'const' declared variables in harmony mode the
    // initialization also always assigns to the declared variable.
    DCHECK_NOT_NULL(proxy);
    DCHECK_NOT_NULL(proxy->var());
    DCHECK_NOT_NULL(value);
    Assignment* assignment = factory()->NewAssignment(
        descriptor_->init_op, proxy, value, descriptor_->initialization_pos);
    block_->statements()->Add(
        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
        zone());
    value = NULL;
  }

  // Add an assignment node to the initialization statement block if we still
  // have a pending initialization value.
  if (value != NULL) {
    DCHECK(descriptor_->mode == VAR);
    // 'var' initializations are simply assignments (with all the consequences
    // if they are inside a 'with' statement - they may change a 'with' object
    // property).
    VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
    Assignment* assignment = factory()->NewAssignment(
        descriptor_->init_op, proxy, value, descriptor_->initialization_pos);
    block_->statements()->Add(
        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
        zone());
  }
}


Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
  auto temp = descriptor_->parser->scope_->NewTemporary(
      ast_value_factory()->empty_string());
  if (value != nullptr) {
    auto assignment = factory()->NewAssignment(
        Token::ASSIGN, factory()->NewVariableProxy(temp), value,
        RelocInfo::kNoPosition);

    block_->statements()->Add(
        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
        zone());
  }
  return temp;
}


void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) {
  auto temp = CreateTempVar(current_value_);

  block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
                            zone());

  for (ObjectLiteralProperty* property : *pattern->properties()) {
    RecurseIntoSubpattern(
        property->value(),
        factory()->NewProperty(factory()->NewVariableProxy(temp),
                               property->key(), RelocInfo::kNoPosition));
  }
}


void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
  auto iterator = CreateTempVar(
      descriptor_->parser->GetIterator(current_value_, factory()));
  auto done = CreateTempVar(
      factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
  auto result = CreateTempVar();
  auto v = CreateTempVar();

  Spread* spread = nullptr;
  for (Expression* value : *node->values()) {
    if (value->IsSpread()) {
      spread = value->AsSpread();
      break;
    }

    // if (!done) {
    //   result = IteratorNext(iterator);
    //   v = (done = result.done) ? undefined : result.value;
    // }
    auto next_block =
        factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
    next_block->statements()->Add(
        factory()->NewExpressionStatement(
            descriptor_->parser->BuildIteratorNextResult(
                factory()->NewVariableProxy(iterator), result,
                RelocInfo::kNoPosition),
            RelocInfo::kNoPosition),
        zone());

    auto assign_to_done = factory()->NewAssignment(
        Token::ASSIGN, factory()->NewVariableProxy(done),
        factory()->NewProperty(
            factory()->NewVariableProxy(result),
            factory()->NewStringLiteral(ast_value_factory()->done_string(),
                                        RelocInfo::kNoPosition),
            RelocInfo::kNoPosition),
        RelocInfo::kNoPosition);
    auto next_value = factory()->NewConditional(
        assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
        factory()->NewProperty(
            factory()->NewVariableProxy(result),
            factory()->NewStringLiteral(ast_value_factory()->value_string(),
                                        RelocInfo::kNoPosition),
            RelocInfo::kNoPosition),
        RelocInfo::kNoPosition);
    next_block->statements()->Add(
        factory()->NewExpressionStatement(
            factory()->NewAssignment(Token::ASSIGN,
                                     factory()->NewVariableProxy(v), next_value,
                                     RelocInfo::kNoPosition),
            RelocInfo::kNoPosition),
        zone());

    auto if_statement = factory()->NewIfStatement(
        factory()->NewUnaryOperation(Token::NOT,
                                     factory()->NewVariableProxy(done),
                                     RelocInfo::kNoPosition),
        next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
        RelocInfo::kNoPosition);
    block_->statements()->Add(if_statement, zone());

    if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
      RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
    }
  }

  if (spread != nullptr) {
    // array = [];
    // if (!done) %concat_iterable_to_array(array, iterator);
    auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
    auto array = CreateTempVar(factory()->NewArrayLiteral(
        empty_exprs,
        // Reuse pattern's literal index - it is unused since there is no
        // actual literal allocated.
        node->literal_index(), is_strong(descriptor_->parser->language_mode()),
        RelocInfo::kNoPosition));

    auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
    arguments->Add(factory()->NewVariableProxy(array), zone());
    arguments->Add(factory()->NewVariableProxy(iterator), zone());
    auto spread_into_array_call =
        factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
                                  arguments, RelocInfo::kNoPosition);

    auto if_statement = factory()->NewIfStatement(
        factory()->NewUnaryOperation(Token::NOT,
                                     factory()->NewVariableProxy(done),
                                     RelocInfo::kNoPosition),
        factory()->NewExpressionStatement(spread_into_array_call,
                                          RelocInfo::kNoPosition),
        factory()->NewEmptyStatement(RelocInfo::kNoPosition),
        RelocInfo::kNoPosition);
    block_->statements()->Add(if_statement, zone());

    RecurseIntoSubpattern(spread->expression(),
                          factory()->NewVariableProxy(array));
  }
}


void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
  // let {<pattern> = <init>} = <value>
  //   becomes
  // temp = <value>;
  // <pattern> = temp === undefined ? <init> : temp;
  DCHECK(node->op() == Token::ASSIGN);
  auto temp = CreateTempVar(current_value_);
  Expression* is_undefined = factory()->NewCompareOperation(
      Token::EQ_STRICT, factory()->NewVariableProxy(temp),
      factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
      RelocInfo::kNoPosition);
  Expression* value = factory()->NewConditional(
      is_undefined, node->value(), factory()->NewVariableProxy(temp),
      RelocInfo::kNoPosition);
  RecurseIntoSubpattern(node->target(), value);
}


// =============== UNREACHABLE =============================

void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); }

#define NOT_A_PATTERN(Node)                                        \
  void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \
    UNREACHABLE();                                                 \
  }

NOT_A_PATTERN(BinaryOperation)
NOT_A_PATTERN(Block)
NOT_A_PATTERN(BreakStatement)
NOT_A_PATTERN(Call)
NOT_A_PATTERN(CallNew)
NOT_A_PATTERN(CallRuntime)
NOT_A_PATTERN(CaseClause)
NOT_A_PATTERN(ClassLiteral)
NOT_A_PATTERN(CompareOperation)
NOT_A_PATTERN(Conditional)
NOT_A_PATTERN(ContinueStatement)
NOT_A_PATTERN(CountOperation)
NOT_A_PATTERN(DebuggerStatement)
NOT_A_PATTERN(DoWhileStatement)
NOT_A_PATTERN(EmptyStatement)
NOT_A_PATTERN(EmptyParentheses)
NOT_A_PATTERN(ExportDeclaration)
NOT_A_PATTERN(ExpressionStatement)
NOT_A_PATTERN(ForInStatement)
NOT_A_PATTERN(ForOfStatement)
NOT_A_PATTERN(ForStatement)
NOT_A_PATTERN(FunctionDeclaration)
NOT_A_PATTERN(FunctionLiteral)
NOT_A_PATTERN(IfStatement)
NOT_A_PATTERN(ImportDeclaration)
NOT_A_PATTERN(Literal)
NOT_A_PATTERN(NativeFunctionLiteral)
NOT_A_PATTERN(Property)
NOT_A_PATTERN(RegExpLiteral)
NOT_A_PATTERN(ReturnStatement)
NOT_A_PATTERN(SloppyBlockFunctionStatement)
NOT_A_PATTERN(Spread)
NOT_A_PATTERN(SuperPropertyReference)
NOT_A_PATTERN(SuperCallReference)
NOT_A_PATTERN(SwitchStatement)
NOT_A_PATTERN(ThisFunction)
NOT_A_PATTERN(Throw)
NOT_A_PATTERN(TryCatchStatement)
NOT_A_PATTERN(TryFinallyStatement)
NOT_A_PATTERN(UnaryOperation)
NOT_A_PATTERN(VariableDeclaration)
NOT_A_PATTERN(WhileStatement)
NOT_A_PATTERN(WithStatement)
NOT_A_PATTERN(Yield)

#undef NOT_A_PATTERN
}  // namespace internal
}  // namespace v8
