1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/parsing/func-name-inferrer.h" 6 7 #include "src/ast/ast-value-factory.h" 8 #include "src/ast/ast.h" 9 #include "src/objects/objects-inl.h" 10 11 namespace v8 { 12 namespace internal { 13 FuncNameInferrer(AstValueFactory * ast_value_factory)14FuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory) 15 : ast_value_factory_(ast_value_factory) {} 16 PushEnclosingName(const AstRawString * name)17void FuncNameInferrer::PushEnclosingName(const AstRawString* name) { 18 // Enclosing name is a name of a constructor function. To check 19 // that it is really a constructor, we check that it is not empty 20 // and starts with a capital letter. 21 if (!name->IsEmpty() && unibrow::Uppercase::Is(name->FirstCharacter())) { 22 names_stack_.push_back(Name(name, kEnclosingConstructorName)); 23 } 24 } 25 26 PushLiteralName(const AstRawString * name)27void FuncNameInferrer::PushLiteralName(const AstRawString* name) { 28 if (IsOpen() && name != ast_value_factory_->prototype_string()) { 29 names_stack_.push_back(Name(name, kLiteralName)); 30 } 31 } 32 33 PushVariableName(const AstRawString * name)34void FuncNameInferrer::PushVariableName(const AstRawString* name) { 35 if (IsOpen() && name != ast_value_factory_->dot_result_string()) { 36 names_stack_.push_back(Name(name, kVariableName)); 37 } 38 } 39 RemoveAsyncKeywordFromEnd()40void FuncNameInferrer::RemoveAsyncKeywordFromEnd() { 41 if (IsOpen()) { 42 CHECK_GT(names_stack_.size(), 0); 43 CHECK(names_stack_.back().name()->IsOneByteEqualTo("async")); 44 names_stack_.pop_back(); 45 } 46 } 47 MakeNameFromStack()48AstConsString* FuncNameInferrer::MakeNameFromStack() { 49 if (names_stack_.size() == 0) { 50 return ast_value_factory_->empty_cons_string(); 51 } 52 AstConsString* result = ast_value_factory_->NewConsString(); 53 auto it = names_stack_.begin(); 54 while (it != names_stack_.end()) { 55 // Advance the iterator to be able to peek the next value. 56 auto current = it++; 57 // Skip consecutive variable declarations. 58 if (it != names_stack_.end() && current->type() == kVariableName && 59 it->type() == kVariableName) { 60 continue; 61 } 62 // Add name. Separate names with ".". 63 Zone* zone = ast_value_factory_->single_parse_zone(); 64 if (!result->IsEmpty()) { 65 result->AddString(zone, ast_value_factory_->dot_string()); 66 } 67 result->AddString(zone, current->name()); 68 } 69 return result; 70 } 71 InferFunctionsNames()72void FuncNameInferrer::InferFunctionsNames() { 73 AstConsString* func_name = MakeNameFromStack(); 74 for (FunctionLiteral* func : funcs_to_infer_) { 75 func->set_raw_inferred_name(func_name); 76 } 77 funcs_to_infer_.resize(0); 78 } 79 80 81 } // namespace internal 82 } // namespace v8 83