[parser] Allow yield in for-in var initializer.

As specified in Annex B.3.6., initializers are allowed in sloppy mode var
declarations in for-in loops.

As a consequence, "in" is one of the tokens that can follow an
AssignmentExpression - this was not recognized before.

BUG=v8:6715

Change-Id: Idbf79bda39beef4e568d630e0b5e239a34397952
Reviewed-on: https://chromium-review.googlesource.com/620728
Reviewed-by: Adam Klein <adamk@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47463}
This commit is contained in:
Marja Hölttä 2017-08-18 13:46:05 +02:00 committed by Commit Bot
parent 21183dd19c
commit e49accd97a
2 changed files with 44 additions and 50 deletions

View File

@ -2949,6 +2949,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
case Token::RPAREN:
case Token::COLON:
case Token::COMMA:
case Token::IN:
// The above set of tokens is the complete set of tokens that can appear
// after an AssignmentExpression, and none of them can start an
// AssignmentExpression. This allows us to avoid looking for an RHS for

View File

@ -5642,67 +5642,60 @@ TEST(ConstParsingInForInError) {
RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0);
}
TEST(InitializedDeclarationsInForInOf) {
// https://tc39.github.io/ecma262/#sec-initializers-in-forin-statement-heads
TEST(InitializedDeclarationsInStrictForInError) {
const char* context_data[][2] = {{"'use strict';", ""},
{"function foo(){ 'use strict';", "}"},
{NULL, NULL}};
// Initialized declarations only allowed for
// - sloppy mode (not strict mode)
// - for-in (not for-of)
// - var (not let / const)
const char* data[] = {
"for (var i = 1 in {}) {}",
"for (var i = void 0 in [1, 2, 3]) {}",
"for (let i = 1 in {}) {}",
"for (let i = void 0 in [1, 2, 3]) {}",
"for (const i = 1 in {}) {}",
"for (const i = void 0 in [1, 2, 3]) {}",
NULL};
RunParserSyncTest(context_data, data, kError);
}
// clang-format off
const char* strict_context[][2] = {{"'use strict';", ""},
{"function foo(){ 'use strict';", "}"},
{"function* foo(){ 'use strict';", "}"},
{nullptr, nullptr}};
const char* sloppy_context[][2] = {{"", ""},
{"function foo(){ ", "}"},
{"function* foo(){ ", "}"},
{"function foo(){ var yield = 0; ", "}"},
{nullptr, nullptr}};
TEST(InitializedDeclarationsInStrictForOfError) {
const char* context_data[][2] = {{"'use strict';", ""},
{"function foo(){ 'use strict';", "}"},
{NULL, NULL}};
const char* data[] = {
"for (var i = 1 of {}) {}",
"for (var i = void 0 of [1, 2, 3]) {}",
const char* let_const_var_for_of[] = {
"for (let i = 1 of {}) {}",
"for (let i = void 0 of [1, 2, 3]) {}",
"for (const i = 1 of {}) {}",
"for (const i = void 0 of [1, 2, 3]) {}",
NULL};
RunParserSyncTest(context_data, data, kError);
}
TEST(InitializedDeclarationsInSloppyForInError) {
const char* context_data[][2] = {{"", ""},
{"function foo(){", "}"},
{NULL, NULL}};
const char* data[] = {
"for (var i = 1 in {}) {}",
"for (var i = void 0 in [1, 2, 3]) {}",
NULL};
// TODO(caitp): This should be an error in sloppy mode.
RunParserSyncTest(context_data, data, kSuccess);
}
TEST(InitializedDeclarationsInSloppyForOfError) {
const char* context_data[][2] = {{"", ""},
{"function foo(){", "}"},
{NULL, NULL}};
const char* data[] = {
"for (var i = 1 of {}) {}",
"for (var i = void 0 of [1, 2, 3]) {}",
NULL};
RunParserSyncTest(context_data, data, kError);
}
nullptr};
const char* let_const_for_in[] = {
"for (let i = 1 in {}) {}",
"for (let i = void 0 in [1, 2, 3]) {}",
"for (const i = 1 in {}) {}",
"for (const i = void 0 in [1, 2, 3]) {}",
nullptr};
const char* var_for_in[] = {
"for (var i = 1 in {}) {}",
"for (var i = void 0 in [1, 2, 3]) {}",
"for (var i = yield in [1, 2, 3]) {}",
nullptr};
// clang-format on
// The only allowed case is sloppy + var + for-in.
RunParserSyncTest(sloppy_context, var_for_in, kSuccess);
// Everything else is disallowed.
RunParserSyncTest(sloppy_context, let_const_var_for_of, kError);
RunParserSyncTest(sloppy_context, let_const_for_in, kError);
RunParserSyncTest(strict_context, let_const_var_for_of, kError);
RunParserSyncTest(strict_context, let_const_for_in, kError);
RunParserSyncTest(strict_context, var_for_in, kError);
}
TEST(ForInMultipleDeclarationsError) {
const char* context_data[][2] = {{"", ""},