From 09660b00ebe8db421598bfb4e23c641cdcc86a89 Mon Sep 17 00:00:00 2001 From: "wingo@igalia.com" Date: Wed, 2 Jul 2014 12:27:34 +0000 Subject: [PATCH] Add more generator/yield parsing tests R=marja@chromium.org BUG= Review URL: https://codereview.chromium.org/362963002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22155 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- test/cctest/test-parsing.cc | 188 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 161 insertions(+), 27 deletions(-) diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 8066f80..af553ed 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. -- 2.7.4