Index: test/cctest/test-parsing.cc |
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc |
index 8066f8052a83dd02586575cf694a268d9aeef17e..af553ed6bb87c3fa1e323fe86ec38a4399746d20 100644 |
--- a/test/cctest/test-parsing.cc |
+++ b/test/cctest/test-parsing.cc |
@@ -1658,6 +1658,7 @@ TEST(ErrorsFutureStrictReservedWords) { |
"var foo = interface = 1;", |
"++interface;", |
"interface++;", |
+ "var yield = 13;", |
NULL |
}; |
@@ -1683,6 +1684,7 @@ TEST(NoErrorsFutureStrictReservedWords) { |
"var foo = interface = 1;", |
"++interface;", |
"interface++;", |
+ "var yield = 13;", |
NULL |
}; |
@@ -1721,12 +1723,13 @@ TEST(ErrorsReservedWords) { |
} |
-TEST(NoErrorsYieldSloppy) { |
+TEST(NoErrorsYieldSloppyAllModes) { |
// In sloppy mode, it's okay to use "yield" as identifier, *except* inside a |
// generator (see next test). |
const char* context_data[][2] = { |
{ "", "" }, |
- { "function is_not_gen() {", "}" }, |
+ { "function not_gen() {", "}" }, |
+ { "(function not_gen() {", "})" }, |
{ NULL, NULL } |
}; |
@@ -1735,12 +1738,18 @@ TEST(NoErrorsYieldSloppy) { |
"var foo, yield;", |
"try { } catch (yield) { }", |
"function yield() { }", |
+ "(function yield() { })", |
"function foo(yield) { }", |
"function foo(bar, yield) { }", |
"yield = 1;", |
"var foo = yield = 1;", |
"++yield;", |
"yield++;", |
+ "yield: 34", |
+ "function yield(yield) { yield: yield (yield + yield (0)); }", |
+ "({ yield: 1 })", |
+ "({ get yield() { 1 } })", |
+ "yield (100)", |
NULL |
}; |
@@ -1748,9 +1757,15 @@ TEST(NoErrorsYieldSloppy) { |
} |
-TEST(ErrorsYieldSloppyGenerator) { |
+TEST(NoErrorsYieldSloppyGeneratorsEnabled) { |
+ // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a |
+ // generator (see next test). |
const char* context_data[][2] = { |
- { "function * is_gen() {", "}" }, |
+ { "", "" }, |
+ { "function not_gen() {", "}" }, |
+ { "function * gen() { function not_gen() {", "} }" }, |
+ { "(function not_gen() {", "})" }, |
+ { "(function * gen() { (function not_gen() {", "}) })" }, |
{ NULL, NULL } |
}; |
@@ -1759,28 +1774,40 @@ TEST(ErrorsYieldSloppyGenerator) { |
"var foo, yield;", |
"try { } catch (yield) { }", |
"function yield() { }", |
- // BUG: These should not be allowed, but they are (if kAllowGenerators is |
- // set) |
- // "function foo(yield) { }", |
- // "function foo(bar, yield) { }", |
+ "(function yield() { })", |
+ "function foo(yield) { }", |
+ "function foo(bar, yield) { }", |
+ "function * yield() { }", |
+ "(function * yield() { })", |
"yield = 1;", |
"var foo = yield = 1;", |
"++yield;", |
"yield++;", |
+ "yield: 34", |
+ "function yield(yield) { yield: yield (yield + yield (0)); }", |
+ "({ yield: 1 })", |
+ "({ get yield() { 1 } })", |
+ "yield (100)", |
NULL |
}; |
- // If generators are not allowed, the error will be produced at the '*' token, |
- // so this test works both with and without the kAllowGenerators flag. |
- RunParserSyncTest(context_data, statement_data, kError); |
+ // This test requires kAllowGenerators to succeed. |
+ static const ParserFlag always_true_flags[] = { |
+ kAllowGenerators |
+ }; |
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, |
+ always_true_flags, 1); |
} |
TEST(ErrorsYieldStrict) { |
const char* context_data[][2] = { |
{ "\"use strict\";", "" }, |
- { "\"use strict\"; function is_not_gen() {", "}" }, |
+ { "\"use strict\"; function not_gen() {", "}" }, |
{ "function test_func() {\"use strict\"; ", "}"}, |
+ { "\"use strict\"; function * gen() { function not_gen() {", "} }" }, |
+ { "\"use strict\"; (function not_gen() {", "})" }, |
+ { "\"use strict\"; (function * gen() { (function not_gen() {", "}) })" }, |
{ NULL, NULL } |
}; |
@@ -1789,12 +1816,16 @@ TEST(ErrorsYieldStrict) { |
"var foo, yield;", |
"try { } catch (yield) { }", |
"function yield() { }", |
+ "(function yield() { })", |
"function foo(yield) { }", |
"function foo(bar, yield) { }", |
+ "function * yield() { }", |
+ "(function * yield() { })", |
"yield = 1;", |
"var foo = yield = 1;", |
"++yield;", |
"yield++;", |
+ "yield: 34;", |
NULL |
}; |
@@ -1802,15 +1833,41 @@ TEST(ErrorsYieldStrict) { |
} |
-TEST(NoErrorsYield) { |
+TEST(NoErrorsGenerator) { |
const char* context_data[][2] = { |
- { "function * is_gen() {", "}" }, |
+ { "function * gen() {", "}" }, |
+ { "(function * gen() {", "})" }, |
+ { "(function * () {", "})" }, |
{ NULL, NULL } |
}; |
const char* statement_data[] = { |
- "yield 2;", // this is legal inside generator |
- "yield * 2;", // this is legal inside generator |
+ // A generator without a body is valid. |
+ "" |
+ // Valid yield expressions inside generators. |
+ "yield 2;", |
+ "yield * 2;", |
+ "yield * \n 2;", |
+ "yield yield 1;", |
+ "yield * yield * 1;", |
+ "yield 3 + (yield 4);", |
+ "yield * 3 + (yield * 4);", |
+ "(yield * 3) + (yield * 4);", |
+ "yield 3; yield 4;", |
+ "yield * 3; yield * 4;", |
+ "(function (yield) { })", |
+ // You can return in a generator. |
+ "yield 1; return", |
+ "yield * 1; return", |
+ "yield 1; return 37", |
+ "yield * 1; return 37", |
+ "yield 1; return 37; yield 'dead';", |
+ "yield * 1; return 37; yield * 'dead';", |
+ // Yield is still a valid key in object literals. |
+ "({ yield: 1 })", |
+ "({ get yield() { } })", |
+ // TODO(348893007): Invalid (no newline allowed between yield and *). |
+ "yield\n*3", |
NULL |
}; |
@@ -1823,20 +1880,75 @@ TEST(NoErrorsYield) { |
} |
+TEST(ErrorsYieldGenerator) { |
+ const char* context_data[][2] = { |
+ { "function * gen() {", "}" }, |
+ { "\"use strict\"; function * gen() {", "}" }, |
+ { NULL, NULL } |
+ }; |
+ |
+ const char* statement_data[] = { |
+ // Invalid yield expressions inside generators. |
+ "var yield;", |
+ "var foo, yield;", |
+ "try { } catch (yield) { }", |
+ "function yield() { }", |
+ // The name of the NFE is let-bound in the generator, which does not permit |
+ // yield to be an identifier. |
+ "(function yield() { })", |
+ "(function * yield() { })", |
+ // Yield isn't valid as a formal parameter for generators. |
+ "function * foo(yield) { }", |
+ "(function * foo(yield) { })", |
+ "yield = 1;", |
+ "var foo = yield = 1;", |
+ "++yield;", |
+ "yield++;", |
+ "yield *", |
+ "(yield *)", |
+ // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which |
+ // is invalid. |
+ "yield 3 + yield 4;", |
+ "yield: 34", |
+ "yield ? 1 : 2", |
+ // Parses as yield (/ yield): invalid. |
+ "yield / yield", |
+ // TODO(348893007): The rest of these should be valid. |
+ "yield;", |
+ "yield", |
+ "yield\n", |
+ "(yield)", |
+ "[yield]", |
+ "{yield}", |
+ "yield, yield", |
+ "yield; yield", |
+ "(yield) ? yield : yield", |
+ "(yield) \n ? yield : yield", |
+ // Parses as yield (+ yield). |
+ "yield + yield", |
+ NULL |
+ }; |
+ |
+ RunParserSyncTest(context_data, statement_data, kError); |
+} |
+ |
+ |
TEST(ErrorsNameOfStrictFunction) { |
// Tests that illegal tokens as names of a strict function produce the correct |
// errors. |
const char* context_data[][2] = { |
- { "", ""}, |
- { "\"use strict\";", ""}, |
+ { "function ", ""}, |
+ { "\"use strict\"; function", ""}, |
+ { "function * ", ""}, |
+ { "\"use strict\"; function * ", ""}, |
{ NULL, NULL } |
}; |
const char* statement_data[] = { |
- "function eval() {\"use strict\";}", |
- "function arguments() {\"use strict\";}", |
- "function interface() {\"use strict\";}", |
- "function yield() {\"use strict\";}", |
+ "eval() {\"use strict\";}", |
+ "arguments() {\"use strict\";}", |
+ "interface() {\"use strict\";}", |
+ "yield() {\"use strict\";}", |
// Future reserved words are always illegal |
"function super() { }", |
"function super() {\"use strict\";}", |
@@ -1849,15 +1961,15 @@ TEST(ErrorsNameOfStrictFunction) { |
TEST(NoErrorsNameOfStrictFunction) { |
const char* context_data[][2] = { |
- { "", ""}, |
+ { "function ", ""}, |
{ NULL, NULL } |
}; |
const char* statement_data[] = { |
- "function eval() { }", |
- "function arguments() { }", |
- "function interface() { }", |
- "function yield() { }", |
+ "eval() { }", |
+ "arguments() { }", |
+ "interface() { }", |
+ "yield() { }", |
NULL |
}; |
@@ -1865,6 +1977,28 @@ TEST(NoErrorsNameOfStrictFunction) { |
} |
+TEST(NoErrorsNameOfStrictGenerator) { |
+ const char* context_data[][2] = { |
+ { "function * ", ""}, |
+ { NULL, NULL } |
+ }; |
+ |
+ const char* statement_data[] = { |
+ "eval() { }", |
+ "arguments() { }", |
+ "interface() { }", |
+ "yield() { }", |
+ NULL |
+ }; |
+ |
+ // This test requires kAllowGenerators to succeed. |
+ static const ParserFlag always_true_flags[] = { |
+ kAllowGenerators |
+ }; |
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, |
+ always_true_flags, 1); |
+} |
+ |
TEST(ErrorsIllegalWordsAsLabelsSloppy) { |
// Using future reserved words as labels is always an error. |