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

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: Version with parsing code only, tests into test-parsing.cc 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/scanner.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 e26ad03dd3878d029c647151f5db6f9fe8a5566b..efbbc94414a6cf886f249a5ccb8da5681009196e 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -194,6 +194,7 @@ class ScriptResource : public v8::String::ExternalAsciiStringResource {
TEST(UsingCachedData) {
+ i::FLAG_harmony_arrow_functions = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
@@ -242,6 +243,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);
v8::Local<v8::Context> context = v8::Context::New(isolate);
@@ -250,31 +252,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[] = {
+ "function this_is_lazy() { var a; } function foo() { return 25; } foo();",
+ NULL
marja 2014/06/17 11:47:38 What, why? What are the changes in this test?
+ };
// 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++) {
marja 2014/06/17 11:47:38 Looping over an array that has only 1 non-trivial
+ 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 +300,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 +317,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());
@@ -967,7 +978,13 @@ TEST(ScopePositions) {
" infunction;\n"
" }", "\n"
" more;", i::FUNCTION_SCOPE, i::SLOPPY },
- { " (function fun", "(a,b) { infunction; }", ")();",
+ // TODO(aperez): Change to use i::ARROW_SCOPE when implemented
+ { " start;\n", "(a,b) => a + b", "; more;",
+ i::FUNCTION_SCOPE, i::SLOPPY },
+ { " start;\n", "(a,b) => { return a+b; }", "\nmore;",
+ i::FUNCTION_SCOPE, i::SLOPPY },
+ { " 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 },
@@ -1122,6 +1139,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();
@@ -1199,6 +1217,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(i::FLAG_harmony_arrow_functions);
marja 2014/06/17 11:47:38 We'd probably like to run each existing ParserSync
}
@@ -1526,6 +1545,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;",
@@ -2018,6 +2041,7 @@ TEST(DontRegressPreParserDataSizes) {
TEST(FunctionDeclaresItselfStrict) {
+ i::FLAG_harmony_arrow_functions = true;
// Tests that we produce the right kinds of errors when a function declares
// itself strict (we cannot produce there errors as soon as we see the
// offending identifiers, because we don't know at that point whether the
@@ -2036,6 +2060,20 @@ TEST(FunctionDeclaresItselfStrict) {
{"function foo(bar, yield) {", "}"},
{"function foo(bar, interface) {", "}"},
{"function foo(bar, bar) {", "}"},
+ {"eval => {", "}"},
marja 2014/06/17 11:47:38 You could have a separate test case for these, and
+ {"arguments => {", "}"},
+ {"yield => {", "}"},
+ {"interface => {", "}"},
+ {"(eval) => {", "}"},
+ {"(arguments) => {", "}"},
+ {"(yield) => {", "}"},
+ {"(interface) => {", "}"},
+ {"(eval, bar) => {", "}"},
+ {"(bar, eval) => {", "}"},
+ {"(bar, arguments) => {", "}"},
+ {"(bar, yield) => {", "}"},
+ {"(bar, interface) => {", "}"},
+ {"(bar, bar) => {", "}"},
{ NULL, NULL }
};
@@ -2550,3 +2588,96 @@ TEST(FuncNameInferrerEscaped) {
i::DeleteArray(two_byte_source);
i::DeleteArray(two_byte_name);
}
+
+
+TEST(ErrorsArrowFunctions) {
+ // Tests that parser and preparser generate the same kind of errors
+ // on invalid arrow function syntax.
+ i::FLAG_harmony_arrow_functions = true;
+
+ const char* context_data[][2] = {
+ {"", ";"},
+ {"v = ", ";"},
+ {"bar ? (", ") : baz;"},
+ {"bar ? baz : (", ");"},
+ {"bar[", "];"},
+ {"bar, ", ";"},
+ {"", ", bar;"},
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "=> 0",
+ "=>",
+ "() =>",
+ "=> {}",
+ ") => {}",
+ ", => {}",
+ "(,) => {}",
+ "return => {}",
+ "(a, if) => {}",
+ "(a * b) => {}",
+ "() => {'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",
+
marja 2014/06/17 11:47:38 Do any of the cases bump into the "is not a variab
+ NULL
+ };
+
+ RunParserSyncTest(context_data, statement_data, kError);
+}
+
+
+TEST(NoErrorsArrowFunctions) {
+ // Tests that parser and preparser accept valid arrow functions syntax.
+ i::FLAG_harmony_arrow_functions = true;
+
+ const char* context_data[][2] = {
+ {"", ";"},
+ {"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)",
+ NULL
+ };
+
+ RunParserSyncTest(context_data, statement_data, kSuccess);
+}
« src/scanner.cc ('K') | « src/token.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698