Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: test/cctest/test-parsing.cc

Issue 160073006: Implement handling of arrow functions in the parser (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed ParamListFinder Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/preparser.cc ('K') | « src/token.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-parsing.cc
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 857089ea0662ca374051c07ae000c8da59a04a77..76cff1311f70da0d2fc094f6accb1e26f1e3e94c 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -155,6 +155,7 @@ TEST(ScanHTMLEndComments) {
scanner.Initialize(&stream);
i::PreParser preparser(&scanner, &log, stack_limit);
preparser.set_allow_lazy(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
i::ScriptData data(log.ExtractData());
@@ -170,6 +171,7 @@ TEST(ScanHTMLEndComments) {
scanner.Initialize(&stream);
i::PreParser preparser(&scanner, &log, stack_limit);
preparser.set_allow_lazy(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@@ -194,6 +196,7 @@ class ScriptResource : public v8::String::ExternalAsciiStringResource {
TEST(UsingCachedData) {
+ i::FLAG_harmony_arrow_functions = true;
marja 2014/06/26 14:38:14 I don't think you need to add this to existing tes
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
@@ -241,6 +244,7 @@ TEST(PreparseFunctionDataIsUsed) {
// Make preparsing work for short scripts.
i::FLAG_min_preparse_length = 0;
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
@@ -250,31 +254,38 @@ TEST(PreparseFunctionDataIsUsed) {
CcTest::i_isolate()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
- const char* good_code =
- "function this_is_lazy() { var a; } function foo() { return 25; } foo();";
+ const char* good_code[] = {
marja 2014/06/26 14:38:14 I whined about this change before, I'm still whini
+ "function this_is_lazy() { var a; } function foo() { return 25; } foo();",
+ NULL
+ };
// Insert a syntax error inside the lazy function.
- const char* bad_code =
- "function this_is_lazy() { if ( } function foo() { return 25; } foo();";
+ const char* bad_code[] = {
+ "function this_is_lazy() { if ( } function foo() { return 25; } foo();",
+ NULL
+ };
- v8::ScriptCompiler::Source good_source(v8_str(good_code));
- v8::ScriptCompiler::Compile(isolate, &good_source,
- v8::ScriptCompiler::kProduceDataToCache);
+ for (int i = 0; good_code[i]; i++) {
+ v8::ScriptCompiler::Source good_source(v8_str(good_code[i]));
+ v8::ScriptCompiler::Compile(isolate, &good_source,
+ v8::ScriptCompiler::kProduceDataToCache);
- const v8::ScriptCompiler::CachedData* cached_data =
- good_source.GetCachedData();
- CHECK(cached_data->data != NULL);
- CHECK_GT(cached_data->length, 0);
+ const v8::ScriptCompiler::CachedData* cached_data =
+ good_source.GetCachedData();
+ CHECK(cached_data->data != NULL);
+ CHECK_GT(cached_data->length, 0);
- // Now compile the erroneous code with the good preparse data. If the preparse
- // data is used, the lazy function is skipped and it should compile fine.
- v8::ScriptCompiler::Source bad_source(
- v8_str(bad_code), new v8::ScriptCompiler::CachedData(
- cached_data->data, cached_data->length));
- v8::Local<v8::Value> result =
- v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
- CHECK(result->IsInt32());
- CHECK_EQ(25, result->Int32Value());
+ // Now compile the erroneous code with the good preparse data. If the
+ // preparse data is used, the lazy function is skipped and it should
+ // compile fine.
+ v8::ScriptCompiler::Source bad_source(
+ v8_str(bad_code[i]), new v8::ScriptCompiler::CachedData(
+ cached_data->data, cached_data->length));
+ v8::Local<v8::Value> result =
+ v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
+ CHECK(result->IsInt32());
+ CHECK_EQ(25, result->Int32Value());
+ }
}
@@ -291,6 +302,7 @@ TEST(StandAlonePreParser) {
"function foo(x, y) { return x + y; }",
"%ArgleBargle(glop);",
"var x = new new Function('this.x = 42');",
+ "var f = (x, y) => x + y;",
NULL
};
@@ -307,6 +319,7 @@ TEST(StandAlonePreParser) {
i::PreParser preparser(&scanner, &log, stack_limit);
preparser.set_allow_lazy(true);
preparser.set_allow_natives_syntax(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
i::ScriptData data(log.ExtractData());
@@ -341,6 +354,7 @@ TEST(StandAlonePreParserNoNatives) {
// Preparser defaults to disallowing natives syntax.
i::PreParser preparser(&scanner, &log, stack_limit);
preparser.set_allow_lazy(true);
+ preparser.set_allow_arrow_functions(true);
marja 2014/06/26 14:38:14 And these shouldn't be needed either. For these te
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
i::ScriptData data(log.ExtractData());
@@ -353,6 +367,7 @@ TEST(StandAlonePreParserNoNatives) {
TEST(PreparsingObjectLiterals) {
// Regression test for a bug where the symbol stream produced by PreParser
// didn't match what Parser wanted to consume.
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
@@ -411,6 +426,7 @@ TEST(RegressChromium62639) {
i::PreParser preparser(&scanner, &log,
CcTest::i_isolate()->stack_guard()->real_climit());
preparser.set_allow_lazy(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@@ -445,6 +461,7 @@ TEST(Regress928) {
i::PreParser preparser(&scanner, &log,
CcTest::i_isolate()->stack_guard()->real_climit());
preparser.set_allow_lazy(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
i::ScriptData data(log.ExtractData());
@@ -492,6 +509,7 @@ TEST(PreParseOverflow) {
i::PreParser preparser(&scanner, &log, stack_limit);
preparser.set_allow_lazy(true);
+ preparser.set_allow_arrow_functions(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
}
@@ -913,8 +931,6 @@ static int Utf8LengthHelper(const char* s) {
TEST(ScopePositions) {
- v8::internal::FLAG_harmony_scoping = true;
marja 2014/06/26 14:38:14 Why this change?
-
// Test the parser for correctly setting the start and end positions
// of a scope. We check the scope positions of exactly one scope
// nested in the global scope of a program. 'inner source' is the
@@ -969,7 +985,8 @@ TEST(ScopePositions) {
" infunction;\n"
" }", "\n"
" more;", i::FUNCTION_SCOPE, i::SLOPPY },
- { " (function fun", "(a,b) { infunction; }", ")();",
+ { " start;\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
i::FUNCTION_SCOPE, i::SLOPPY },
{ " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
i::BLOCK_SCOPE, i::STRICT },
@@ -1124,6 +1141,7 @@ TEST(ScopePositions) {
i::Parser parser(&info);
parser.set_allow_lazy(true);
parser.set_allow_harmony_scoping(true);
+ parser.set_allow_arrow_functions(true);
info.MarkAsGlobal();
info.SetStrictMode(source_data[i].strict_mode);
parser.Parse();
@@ -1180,7 +1198,8 @@ enum ParserFlag {
kAllowModules,
kAllowGenerators,
kAllowForOf,
- kAllowHarmonyNumericLiterals
+ kAllowHarmonyNumericLiterals,
+ kAllowArrowFunctions
};
@@ -1201,6 +1220,7 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
parser->set_allow_for_of(flags.Contains(kAllowForOf));
parser->set_allow_harmony_numeric_literals(
flags.Contains(kAllowHarmonyNumericLiterals));
+ parser->set_allow_arrow_functions(flags.Contains(kAllowArrowFunctions));
}
@@ -1403,6 +1423,7 @@ TEST(ParserSync) {
CcTest::i_isolate()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ static const ParserFlag always_flags[] = { kAllowArrowFunctions };
marja 2014/06/26 14:38:14 Instead of this, you should add the flag to flags1
static const ParserFlag flags1[] = {
kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
kAllowForOf
@@ -1426,7 +1447,8 @@ TEST(ParserSync) {
termination_data[k],
context_data[i][1]);
CHECK(length == kProgramSize);
- TestParserSync(program.start(), flags1, ARRAY_SIZE(flags1));
+ TestParserSync(program.start(), flags1, ARRAY_SIZE(flags1),
+ kSuccessOrError, always_flags, ARRAY_SIZE(always_flags));
}
}
}
@@ -1435,11 +1457,14 @@ TEST(ParserSync) {
// interaction with the flags above, so test these separately to reduce
// the combinatorial explosion.
static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals };
- TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2));
- TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2));
+ TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2),
+ kSuccessOrError, always_flags, ARRAY_SIZE(always_flags));
+ TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2),
+ kSuccessOrError, always_flags, ARRAY_SIZE(always_flags));
static const ParserFlag flags3[] = { kAllowNativesSyntax };
- TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3));
+ TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3),
+ kSuccessOrError, always_flags, ARRAY_SIZE(always_flags));
}
@@ -1447,6 +1472,8 @@ TEST(StrictOctal) {
// Test that syntax error caused by octal literal is reported correctly as
// such (issue 2220).
v8::V8::Initialize();
+ i::FLAG_harmony_arrow_functions = true;
+
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(
v8::Context::New(CcTest::isolate()));
@@ -1483,7 +1510,7 @@ void RunParserSyncTest(const char* context_data[][2],
static const ParserFlag default_flags[] = {
kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
- kAllowForOf, kAllowNativesSyntax
+ kAllowForOf, kAllowNativesSyntax, kAllowArrowFunctions
};
ParserFlag* generated_flags = NULL;
if (flags == NULL) {
@@ -1560,6 +1587,10 @@ TEST(ErrorsEvalAndArguments) {
"function foo(arguments) { }",
"function foo(bar, eval) { }",
"function foo(bar, arguments) { }",
+ "(eval) => { }",
+ "(arguments) => { }",
+ "(foo, eval) => { }",
+ "(foo, arguments) => { }",
"eval = 1;",
"arguments = 1;",
"var foo = eval = 1;",
@@ -1616,6 +1647,7 @@ TEST(NoErrorsEvalAndArgumentsStrict) {
const char* context_data[][2] = {
{ "\"use strict\";", "" },
{ "function test_func() { \"use strict\";", "}" },
+ { "() => { \"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1631,7 +1663,9 @@ TEST(NoErrorsEvalAndArgumentsStrict) {
NULL
};
- RunParserSyncTest(context_data, statement_data, kSuccess);
+ static const ParserFlag always_flags[] = { kAllowArrowFunctions };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
}
@@ -1643,6 +1677,7 @@ TEST(ErrorsFutureStrictReservedWords) {
const char* context_data[][2] = {
{ "\"use strict\";", "" },
{ "function test_func() {\"use strict\"; ", "}"},
+ { "() => { \"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1653,6 +1688,8 @@ TEST(ErrorsFutureStrictReservedWords) {
"function interface() { }",
"function foo(interface) { }",
"function foo(bar, interface) { }",
+ "(interface) => { }",
+ "(bar, interface) => { }",
"interface = 1;",
"var foo = interface = 1;",
"++interface;",
@@ -1660,6 +1697,7 @@ TEST(ErrorsFutureStrictReservedWords) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
marja 2014/06/26 14:38:13 Instead of this, you should use always_true_flags.
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -1668,6 +1706,7 @@ TEST(NoErrorsFutureStrictReservedWords) {
const char* context_data[][2] = {
{ "", "" },
{ "function test_func() {", "}"},
+ { "() => {", "}" },
{ NULL, NULL }
};
@@ -1685,7 +1724,10 @@ TEST(NoErrorsFutureStrictReservedWords) {
NULL
};
- RunParserSyncTest(context_data, statement_data, kSuccess);
+ static const ParserFlag always_flags[] = { kAllowArrowFunctions };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
+
}
@@ -1698,6 +1740,8 @@ TEST(ErrorsReservedWords) {
{ "\"use strict\";", "" },
{ "var eval; function test_func() {", "}"},
{ "var eval; function test_func() {\"use strict\"; ", "}"},
+ { "var eval; () => {", "}" },
+ { "var eval; () => {\"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1708,6 +1752,8 @@ TEST(ErrorsReservedWords) {
"function super() { }",
"function foo(super) { }",
"function foo(bar, super) { }",
+ "(super) => { }",
+ "(bar, super) => { }",
"super = 1;",
"var foo = super = 1;",
"++super;",
@@ -1716,6 +1762,7 @@ TEST(ErrorsReservedWords) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
marja 2014/06/26 14:38:14 Here too... in all places, where you need the flag
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -1726,6 +1773,7 @@ TEST(NoErrorsYieldSloppy) {
const char* context_data[][2] = {
{ "", "" },
{ "function is_not_gen() {", "}" },
+ { "() => {", "}" },
{ NULL, NULL }
};
@@ -1743,7 +1791,9 @@ TEST(NoErrorsYieldSloppy) {
NULL
};
- RunParserSyncTest(context_data, statement_data, kSuccess);
+ static const ParserFlag always_flags[] = { kAllowArrowFunctions };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
}
@@ -1771,6 +1821,7 @@ TEST(ErrorsYieldSloppyGenerator) {
// If generators are not allowed, the error will be produced at the '*' token,
// so this test works both with and without the kAllowGenerators flag.
+ i::FLAG_harmony_arrow_functions = true;
marja 2014/06/26 14:38:14 And this is completely unnecessary; the test shoul
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -1780,6 +1831,7 @@ TEST(ErrorsYieldStrict) {
{ "\"use strict\";", "" },
{ "\"use strict\"; function is_not_gen() {", "}" },
{ "function test_func() {\"use strict\"; ", "}"},
+ { "() => {\"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1790,6 +1842,8 @@ TEST(ErrorsYieldStrict) {
"function yield() { }",
"function foo(yield) { }",
"function foo(bar, yield) { }",
+ "(yield) => { }",
+ "(bar, yield) => { }",
"yield = 1;",
"var foo = yield = 1;",
"++yield;",
@@ -1797,6 +1851,7 @@ TEST(ErrorsYieldStrict) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -1817,6 +1872,7 @@ TEST(NoErrorsYield) {
static const ParserFlag always_true_flags[] = {
kAllowGenerators
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
always_true_flags, 1);
}
@@ -1842,6 +1898,7 @@ TEST(ErrorsNameOfStrictFunction) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -1860,6 +1917,7 @@ TEST(NoErrorsNameOfStrictFunction) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -1870,6 +1928,7 @@ TEST(ErrorsIllegalWordsAsLabelsSloppy) {
const char* context_data[][2] = {
{ "", ""},
{ "function test_func() {", "}" },
+ { "() => {", "}" },
{ NULL, NULL }
};
@@ -1887,6 +1946,7 @@ TEST(ErrorsIllegalWordsAsLabelsStrict) {
const char* context_data[][2] = {
{ "\"use strict\";", "" },
{ "function test_func() {\"use strict\"; ", "}"},
+ { "() => {\"use strict\"; ", "}" },
{ NULL, NULL }
};
@@ -1906,8 +1966,10 @@ TEST(NoErrorsIllegalWordsAsLabels) {
const char* context_data[][2] = {
{ "", ""},
{ "function test_func() {", "}" },
+ { "() => {", "}" },
{ "\"use strict\";", "" },
{ "\"use strict\"; function test_func() {", "}" },
+ { "\"use strict\"; () => {", "}" },
{ NULL, NULL }
};
@@ -1918,7 +1980,9 @@ TEST(NoErrorsIllegalWordsAsLabels) {
NULL
};
- RunParserSyncTest(context_data, statement_data, kSuccess);
+ static const ParserFlag always_flags[] = { kAllowArrowFunctions };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
}
@@ -1927,6 +1991,7 @@ TEST(ErrorsParenthesizedLabels) {
const char* context_data[][2] = {
{ "", ""},
{ "function test_func() {", "}" },
+ { "() => {", "}" },
{ NULL, NULL }
};
@@ -1951,6 +2016,7 @@ TEST(NoErrorsParenthesizedDirectivePrologue) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -1972,6 +2038,7 @@ TEST(ErrorsNotAnIdentifierName) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -1994,6 +2061,7 @@ TEST(NoErrorsIdentifierNames) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -2002,6 +2070,7 @@ TEST(DontRegressPreParserDataSizes) {
// These tests make sure that Parser doesn't start producing less "preparse
// data" (data which the embedder can cache).
v8::V8::Initialize();
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
@@ -2085,6 +2154,7 @@ TEST(FunctionDeclaresItselfStrict) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, strict_statement_data, kError);
RunParserSyncTest(context_data, non_strict_statement_data, kSuccess);
}
@@ -2105,6 +2175,7 @@ TEST(ErrorsTryWithoutCatchOrFinally) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -2122,6 +2193,7 @@ TEST(NoErrorsTryCatchFinally) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -2137,6 +2209,7 @@ TEST(ErrorsRegexpLiteral) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -2154,6 +2227,7 @@ TEST(NoErrorsRegexpLiteral) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -2174,8 +2248,10 @@ TEST(Intrinsics) {
kAllowNativesSyntax
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
always_true_flags, 1);
+ RunParserSyncTest(context_data, statement_data, kSuccessOrError);
}
@@ -2214,6 +2290,7 @@ TEST(NoErrorsNewExpression) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -2233,6 +2310,7 @@ TEST(ErrorsNewExpression) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -2261,6 +2339,7 @@ TEST(StrictObjectLiteralChecking) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(non_strict_context_data, statement_data, kSuccess);
RunParserSyncTest(strict_context_data, statement_data, kError);
}
@@ -2303,6 +2382,7 @@ TEST(ErrorsObjectLiteralChecking) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kError);
}
@@ -2348,6 +2428,7 @@ TEST(NoErrorsObjectLiteralChecking) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -2372,6 +2453,7 @@ TEST(TooManyArguments) {
};
// The test is quite slow, so run it with a reduced set of flags.
+ i::FLAG_harmony_arrow_functions = true;
static const ParserFlag empty_flags[] = {kAllowLazy};
RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1);
}
@@ -2420,6 +2502,8 @@ TEST(StrictDelete) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
+
RunParserSyncTest(strict_context_data, sloppy_statement_data, kError);
RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess);
@@ -2496,6 +2580,8 @@ TEST(InvalidLeftHandSide) {
NULL
};
+ i::FLAG_harmony_arrow_functions = true;
+
RunParserSyncTest(assignment_context_data, good_statement_data, kSuccess);
RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError);
RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment,
@@ -2512,6 +2598,7 @@ TEST(InvalidLeftHandSide) {
TEST(FuncNameInferrerBasic) {
// Tests that function names are inferred properly.
i::FLAG_allow_natives_syntax = true;
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
@@ -2553,6 +2640,7 @@ TEST(FuncNameInferrerTwoByte) {
// Tests function name inferring in cases where some parts of the inferred
// function name are two-byte strings.
i::FLAG_allow_natives_syntax = true;
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
@@ -2578,6 +2666,7 @@ TEST(FuncNameInferrerEscaped) {
// The same as FuncNameInferrerTwoByte, except that we express the two-byte
// character as a unicode escape.
i::FLAG_allow_natives_syntax = true;
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
@@ -2614,3 +2703,168 @@ TEST(RegressionLazyFunctionWithErrorWithArg) {
"}\n"
"this_is_lazy();\n");
}
+
+
+TEST(ErrorsArrowFunctions) {
+ // Tests that parser and preparser generate the same kind of errors
+ // on invalid arrow function syntax.
+ const char* context_data[][2] = {
+ {"", ";"},
+ {"v = ", ";"},
+ {"bar ? (", ") : baz;"},
+ {"bar ? baz : (", ");"},
+ {"bar[", "];"},
+ {"bar, ", ";"},
+ {"", ", bar;"},
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "=> 0",
+ "=>",
+ "() =>",
+ "=> {}",
+ ") => {}",
+ ", => {}",
+ "(,) => {}",
+ "return => {}",
+ "() => {'value': 42}",
+
+ // Check that the early return introduced in ParsePrimaryExpression
+ // does not accept stray closing parentheses.
+ ")",
+ ") => 0",
+ "foo[()]",
+ "()",
+
+ // Parameter lists with extra parens should be recognized as errors.
+ "(()) => 0",
+ "((x)) => 0",
+ "((x, y)) => 0",
+ "(x, (y)) => 0",
+ "((x, y, z)) => 0",
+ "(x, (y, z)) => 0",
+ "((x, y), z) => 0",
+
+ // Parameter lists are always validated as strict, so those are errors.
+ "eval => {}",
+ "arguments => {}",
+ "yield => {}",
+ "interface => {}",
+ "(eval) => {}",
+ "(arguments) => {}",
+ "(yield) => {}",
+ "(interface) => {}",
+ "(eval, bar) => {}",
+ "(bar, eval) => {}",
+ "(bar, arguments) => {}",
+ "(bar, yield) => {}",
+ "(bar, interface) => {}",
+ // TODO(aperez): Detecting duplicates does not work in PreParser.
+ //"(bar, bar) => {}",
+
+ // The parameter list is parsed as an expression, but only
+ // a comma-separated list of identifier is valid.
+ "32 => {}",
+ "(32) => {}",
+ "(a, 32) => {}",
+ "if => {}",
+ "(if) => {}",
+ "(a, if) => {}",
+ "a + b => {}",
+ "(a + b) => {}",
+ "(a + b, c) => {}",
+ "(a, b - c) => {}",
+ "\"a\" => {}",
+ "(\"a\") => {}",
+ "(\"a\", b) => {}",
+ "(a, \"b\") => {}",
+ "-a => {}",
+ "(-a) => {}",
+ "(-a, b) => {}",
+ "(a, -b) => {}",
+ "{} => {}",
+ "({}) => {}",
+ "(a, {}) => {}",
+ "({}, a) => {}",
+ "a++ => {}",
+ "(a++) => {}",
+ "(a++, b) => {}",
+ "(a, b++) => {}",
+ "[] => {}",
+ "([]) => {}",
+ "(a, []) => {}",
+ "([], a) => {}",
+ "(a = b) => {}",
+ "(a = b, c) => {}",
+ "(a, b = c) => {}",
+ "(foo ? bar : baz) => {}",
+ "(a, foo ? bar : baz) => {}",
+ "(foo ? bar : baz, a) => {}",
+
+ NULL
+ };
+
+ RunParserSyncTest(context_data, statement_data, kError);
+}
+
+
+TEST(NoErrorsArrowFunctions) {
+ // Tests that parser and preparser accept valid arrow functions syntax.
+ const char* context_data[][2] = {
+ {"", ";"},
+ // TODO(aperez): Uncomment this when ParseArrowFunctionLiteral()
+ // generates code and returns a non-NULL expression. Currently it
+ // crashes when expression->set_is_parenthesized(true) is called.
+ //{"bar ? (", ") : baz;"},
+ //{"bar ? baz : (", ");"},
+ {"bar, ", ";"},
+ {"", ", bar;"},
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "() => {}",
+ "() => { return 42 }",
+ "x => { return x; }",
+ "(x) => { return x; }",
+ "(x, y) => { return x + y; }",
+ "(x, y, z) => { return x + y + z; }",
+ "(x, y) => { x.a = y; }",
+ "() => 42",
+ "x => x",
+ "x => x * x",
+ "(x) => x",
+ "(x) => x * x",
+ "(x, y) => x + y",
+ "(x, y, z) => x, y, z",
+ "(x, y) => x.a = y",
+ "() => ({'value': 42})",
+ "x => y => x + y",
+ "(x, y) => (u, v) => x*u + y*v",
+ "(x, y) => z => z * (x + y)",
+ "x => (y, z) => z * (x + y)",
+
+ // Those are comma-separated expressions, with arrow functions as items.
+ // They stress the code for validating arrow function parameter lists.
+ "a, b => 0",
+ "a, b, (c, d) => 0",
+ "(a, b, (c, d) => 0)",
+ "(a, b) => 0, (c, d) => 1",
+ "(a, b => {}, a => a + 1)",
+ // TODO(aperez): Uncomment this when ParseArrowFunctionLiteral()
+ // generates code and returns a non-NULL expression. Currently it
+ // crashes when expression->set_is_parenthesized(true) is called.
+ //"((a, b) => {}, (a => a + 1))",
+ //"(a, (a, (b, c) => 0))",
+
+ // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
+ "foo ? bar : baz => {}",
+
+ NULL
+ };
+
+ static const ParserFlag always_flags[] = { kAllowArrowFunctions };
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+ always_flags, ARRAY_SIZE(always_flags));
+}
« src/preparser.cc ('K') | « src/token.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698