}
-void FuncNameInferrer::MaybeInferFunctionName() {
- if (func_to_infer_ != NULL) {
- func_to_infer_->set_inferred_name(MakeNameFromStack());
- func_to_infer_ = NULL;
+void FuncNameInferrer::InferFunctionsNames() {
+ Handle<String> func_name = MakeNameFromStack();
+ for (int i = 0; i < funcs_to_infer_.length(); ++i) {
+ funcs_to_infer_[i]->set_inferred_name(func_name);
}
+ funcs_to_infer_.Rewind(0);
}
FuncNameInferrer() :
entries_stack_(10),
names_stack_(5),
- func_to_infer_(NULL),
+ funcs_to_infer_(4),
dot_(Factory::NewStringFromAscii(CStrVector("."))) {
}
entries_stack_.Add(names_stack_.length());
}
- void Leave() {
- ASSERT(IsOpen());
- names_stack_.Rewind(entries_stack_.RemoveLast());
- }
-
void PushName(Handle<String> name) {
if (IsOpen()) {
names_stack_.Add(name);
}
}
- void SetFuncToInfer(FunctionLiteral* func_to_infer) {
+ void AddFunction(FunctionLiteral* func_to_infer) {
if (IsOpen()) {
- // If we encounter another function literal after already having
- // encountered one, the second one replaces the first.
- func_to_infer_ = func_to_infer;
+ funcs_to_infer_.Add(func_to_infer);
}
}
void InferAndLeave() {
ASSERT(IsOpen());
- MaybeInferFunctionName();
- Leave();
+ if (!funcs_to_infer_.is_empty()) {
+ InferFunctionsNames();
+ }
+ names_stack_.Rewind(entries_stack_.RemoveLast());
}
private:
Handle<String> MakeNameFromStack();
Handle<String> MakeNameFromStackHelper(int pos, Handle<String> prev);
- void MaybeInferFunctionName();
+ void InferFunctionsNames();
List<int> entries_stack_;
List<Handle<String> > names_stack_;
- FunctionLiteral* func_to_infer_;
+ List<FunctionLiteral*> funcs_to_infer_;
Handle<String> dot_;
DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
if (node->name()->length() == 0) {
// Anonymous function.
- func_name_inferrer_.SetFuncToInfer(node);
+ func_name_inferrer_.AddFunction(node);
}
}
case Token::ASSIGN:
// No type can be infered from the general assignment.
- if (node->value()->AsFunctionLiteral() != NULL ||
- node->value()->AsObjectLiteral() != NULL) {
- scoped_fni.Enter();
- }
+ scoped_fni.Enter();
break;
case Token::ASSIGN_BIT_OR:
case Token::ASSIGN_BIT_XOR:
CheckFunctionName(script, "return 2", "");
CheckFunctionName(script, "return 3", "");
}
+
+
+TEST(MultipleFuncsConditional) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::Script> script = Compile(
+ "fun1 = 0 ?\n"
+ " function() { return 1; } :\n"
+ " function() { return 2; }");
+ CheckFunctionName(script, "return 1", "fun1");
+ CheckFunctionName(script, "return 2", "fun1");
+}
+
+
+TEST(MultipleFuncsInLiteral) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ v8::Handle<v8::Script> script = Compile(
+ "function MyClass() {}\n"
+ "MyClass.prototype = {\n"
+ " method1: 0 ? function() { return 1; } :\n"
+ " function() { return 2; } }");
+ CheckFunctionName(script, "return 1", "MyClass.method1");
+ CheckFunctionName(script, "return 2", "MyClass.method1");
+}