11cb0ef41Sopenharmony_ci// Copyright 2011 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/parsing/func-name-inferrer.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/ast/ast-value-factory.h"
81cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
91cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cinamespace v8 {
121cb0ef41Sopenharmony_cinamespace internal {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciFuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory)
151cb0ef41Sopenharmony_ci    : ast_value_factory_(ast_value_factory) {}
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_civoid FuncNameInferrer::PushEnclosingName(const AstRawString* name) {
181cb0ef41Sopenharmony_ci  // Enclosing name is a name of a constructor function. To check
191cb0ef41Sopenharmony_ci  // that it is really a constructor, we check that it is not empty
201cb0ef41Sopenharmony_ci  // and starts with a capital letter.
211cb0ef41Sopenharmony_ci  if (!name->IsEmpty() && unibrow::Uppercase::Is(name->FirstCharacter())) {
221cb0ef41Sopenharmony_ci    names_stack_.push_back(Name(name, kEnclosingConstructorName));
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci}
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_civoid FuncNameInferrer::PushLiteralName(const AstRawString* name) {
281cb0ef41Sopenharmony_ci  if (IsOpen() && name != ast_value_factory_->prototype_string()) {
291cb0ef41Sopenharmony_ci    names_stack_.push_back(Name(name, kLiteralName));
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci}
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_civoid FuncNameInferrer::PushVariableName(const AstRawString* name) {
351cb0ef41Sopenharmony_ci  if (IsOpen() && name != ast_value_factory_->dot_result_string()) {
361cb0ef41Sopenharmony_ci    names_stack_.push_back(Name(name, kVariableName));
371cb0ef41Sopenharmony_ci  }
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_civoid FuncNameInferrer::RemoveAsyncKeywordFromEnd() {
411cb0ef41Sopenharmony_ci  if (IsOpen()) {
421cb0ef41Sopenharmony_ci    CHECK_GT(names_stack_.size(), 0);
431cb0ef41Sopenharmony_ci    CHECK(names_stack_.back().name()->IsOneByteEqualTo("async"));
441cb0ef41Sopenharmony_ci    names_stack_.pop_back();
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci}
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ciAstConsString* FuncNameInferrer::MakeNameFromStack() {
491cb0ef41Sopenharmony_ci  if (names_stack_.size() == 0) {
501cb0ef41Sopenharmony_ci    return ast_value_factory_->empty_cons_string();
511cb0ef41Sopenharmony_ci  }
521cb0ef41Sopenharmony_ci  AstConsString* result = ast_value_factory_->NewConsString();
531cb0ef41Sopenharmony_ci  auto it = names_stack_.begin();
541cb0ef41Sopenharmony_ci  while (it != names_stack_.end()) {
551cb0ef41Sopenharmony_ci    // Advance the iterator to be able to peek the next value.
561cb0ef41Sopenharmony_ci    auto current = it++;
571cb0ef41Sopenharmony_ci    // Skip consecutive variable declarations.
581cb0ef41Sopenharmony_ci    if (it != names_stack_.end() && current->type() == kVariableName &&
591cb0ef41Sopenharmony_ci        it->type() == kVariableName) {
601cb0ef41Sopenharmony_ci      continue;
611cb0ef41Sopenharmony_ci    }
621cb0ef41Sopenharmony_ci    // Add name. Separate names with ".".
631cb0ef41Sopenharmony_ci    Zone* zone = ast_value_factory_->single_parse_zone();
641cb0ef41Sopenharmony_ci    if (!result->IsEmpty()) {
651cb0ef41Sopenharmony_ci      result->AddString(zone, ast_value_factory_->dot_string());
661cb0ef41Sopenharmony_ci    }
671cb0ef41Sopenharmony_ci    result->AddString(zone, current->name());
681cb0ef41Sopenharmony_ci  }
691cb0ef41Sopenharmony_ci  return result;
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_civoid FuncNameInferrer::InferFunctionsNames() {
731cb0ef41Sopenharmony_ci  AstConsString* func_name = MakeNameFromStack();
741cb0ef41Sopenharmony_ci  for (FunctionLiteral* func : funcs_to_infer_) {
751cb0ef41Sopenharmony_ci    func->set_raw_inferred_name(func_name);
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci  funcs_to_infer_.resize(0);
781cb0ef41Sopenharmony_ci}
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci}  // namespace internal
821cb0ef41Sopenharmony_ci}  // namespace v8
83