// Copyright 2011 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/func-name-inferrer.h"

#include "src/ast/ast-value-factory.h"
#include "src/ast/ast.h"
#include "src/objects-inl.h"

namespace v8 {
namespace internal {

FuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory)
    : ast_value_factory_(ast_value_factory) {}

void FuncNameInferrer::PushEnclosingName(const AstRawString* name) {
  // Enclosing name is a name of a constructor function. To check
  // that it is really a constructor, we check that it is not empty
  // and starts with a capital letter.
  if (!name->IsEmpty() && unibrow::Uppercase::Is(name->FirstCharacter())) {
    names_stack_.push_back(Name(name, kEnclosingConstructorName));
  }
}


void FuncNameInferrer::PushLiteralName(const AstRawString* name) {
  if (IsOpen() && name != ast_value_factory_->prototype_string()) {
    names_stack_.push_back(Name(name, kLiteralName));
  }
}


void FuncNameInferrer::PushVariableName(const AstRawString* name) {
  if (IsOpen() && name != ast_value_factory_->dot_result_string()) {
    names_stack_.push_back(Name(name, kVariableName));
  }
}

void FuncNameInferrer::RemoveAsyncKeywordFromEnd() {
  if (IsOpen()) {
    CHECK_GT(names_stack_.size(), 0);
    CHECK(names_stack_.back().name()->IsOneByteEqualTo("async"));
    names_stack_.pop_back();
  }
}

const AstConsString* FuncNameInferrer::MakeNameFromStack() {
  if (names_stack_.size() == 0) {
    return ast_value_factory_->empty_cons_string();
  }
  AstConsString* result = ast_value_factory_->NewConsString();
  auto it = names_stack_.begin();
  while (it != names_stack_.end()) {
    // Advance the iterator to be able to peek the next value.
    auto current = it++;
    // Skip consecutive variable declarations.
    if (it != names_stack_.end() && current->type() == kVariableName &&
        it->type() == kVariableName) {
      continue;
    }
    // Add name. Separate names with ".".
    Zone* zone = ast_value_factory_->zone();
    if (!result->IsEmpty()) {
      result->AddString(zone, ast_value_factory_->dot_string());
    }
    result->AddString(zone, current->name());
  }
  return result;
}

void FuncNameInferrer::InferFunctionsNames() {
  const AstConsString* func_name = MakeNameFromStack();
  for (FunctionLiteral* func : funcs_to_infer_) {
    func->set_raw_inferred_name(func_name);
  }
  funcs_to_infer_.resize(0);
}


}  // namespace internal
}  // namespace v8
