1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/func-name-inferrer.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast-value-factory.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/list-inl.h" 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFuncNameInferrer::FuncNameInferrer(AstValueFactory* ast_value_factory, 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : ast_value_factory_(ast_value_factory), 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch entries_stack_(10, zone), 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch names_stack_(5, zone), 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch funcs_to_infer_(4, zone), 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone_(zone) { 213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FuncNameInferrer::PushEnclosingName(const AstRawString* name) { 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enclosing name is a name of a constructor function. To check 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that it is really a constructor, we check that it is not empty 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and starts with a capital letter. 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!name->IsEmpty() && unibrow::Uppercase::Is(name->FirstCharacter())) { 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch names_stack_.Add(Name(name, kEnclosingConstructorName), zone()); 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FuncNameInferrer::PushLiteralName(const AstRawString* name) { 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsOpen() && name != ast_value_factory_->prototype_string()) { 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch names_stack_.Add(Name(name, kLiteralName), zone()); 3780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 3880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 3980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 4080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FuncNameInferrer::PushVariableName(const AstRawString* name) { 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsOpen() && name != ast_value_factory_->dot_result_string()) { 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch names_stack_.Add(Name(name, kVariableName), zone()); 4480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 4580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 4680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid FuncNameInferrer::RemoveAsyncKeywordFromEnd() { 48f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (IsOpen()) { 49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(names_stack_.length() > 0); 50f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(names_stack_.last().name->IsOneByteEqualTo("async")); 51f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch names_stack_.RemoveLast(); 52f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 5480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst AstString* FuncNameInferrer::MakeNameFromStack() { 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MakeNameFromStackHelper(0, ast_value_factory_->empty_string()); 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst AstString* FuncNameInferrer::MakeNameFromStackHelper( 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int pos, const AstString* prev) { 613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (pos >= names_stack_.length()) return prev; 623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (pos < names_stack_.length() - 1 && 633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch names_stack_.at(pos).type == kVariableName && 643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch names_stack_.at(pos + 1).type == kVariableName) { 653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Skip consecutive variable declarations. 663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return MakeNameFromStackHelper(pos + 1, prev); 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (prev->length() > 0) { 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const AstRawString* name = names_stack_.at(pos).name; 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prev->length() + name->length() + 1 > String::kMaxLength) return prev; 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const AstConsString* curr = ast_value_factory_->NewConsString( 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ast_value_factory_->dot_string(), name); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch curr = ast_value_factory_->NewConsString(prev, curr); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MakeNameFromStackHelper(pos + 1, curr); 753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return MakeNameFromStackHelper(pos + 1, names_stack_.at(pos).name); 773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FuncNameInferrer::InferFunctionsNames() { 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const AstString* func_name = MakeNameFromStack(); 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < funcs_to_infer_.length(); ++i) { 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch funcs_to_infer_[i]->set_raw_inferred_name(func_name); 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block funcs_to_infer_.Rewind(0); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 93