[parser] classify binding pattern errors when parsing await expression
await expressions are an invalid destructuring target, and should result in a SyntaxError when used in a position where a destructuring target is expected. BUG=v8:7173 R=marja@chromium.org, adamk@chromium.org Change-Id: I1bdb4bc13cb2e3e904fc4389a6e0abca1e0ed17f Reviewed-on: https://chromium-review.googlesource.com/811946 Reviewed-by: Sathya Gunasekaran (ooo until 12/12) <gsathya@chromium.org> Commit-Queue: Caitlin Potter <caitp@igalia.com> Cr-Commit-Position: refs/heads/master@{#49977}
This commit is contained in:
parent
ff3d8321d5
commit
84a71a585a
@ -3211,12 +3211,15 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
|
||||
classifier()->RecordFormalParameterInitializerError(
|
||||
scanner()->peek_location(),
|
||||
MessageTemplate::kAwaitExpressionFormalParameter);
|
||||
|
||||
int await_pos = peek_position();
|
||||
Consume(Token::AWAIT);
|
||||
|
||||
ExpressionT value = ParseUnaryExpression(CHECK_OK);
|
||||
|
||||
classifier()->RecordBindingPatternError(
|
||||
Scanner::Location(await_pos, scanner()->location().end_pos),
|
||||
MessageTemplate::kInvalidDestructuringTarget);
|
||||
|
||||
ExpressionT expr = factory()->NewAwait(value, await_pos);
|
||||
impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
|
||||
return expr;
|
||||
|
@ -8570,6 +8570,64 @@ TEST(AsyncAwaitErrors) {
|
||||
RunParserSyncTest(async_body_context_data, async_body_error_data, kError);
|
||||
}
|
||||
|
||||
TEST(Regress7173) {
|
||||
// Await expression is an invalid destructuring target, and should not crash
|
||||
|
||||
// clang-format off
|
||||
const char* error_context_data[][2] = {
|
||||
{ "'use strict'; async function f() {", "}" },
|
||||
{ "async function f() {", "}" },
|
||||
{ "'use strict'; function f() {", "}" },
|
||||
{ "function f() {", "}" },
|
||||
{ "let f = async() => {", "}" },
|
||||
{ "let f = () => {", "}" },
|
||||
{ "'use strict'; async function* f() {", "}" },
|
||||
{ "async function* f() {", "}" },
|
||||
{ "'use strict'; function* f() {", "}" },
|
||||
{ "function* f() {", "}" },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
const char* error_data[] = {
|
||||
"var [await f] = [];",
|
||||
"let [await f] = [];",
|
||||
"const [await f] = [];",
|
||||
|
||||
"var [...await f] = [];",
|
||||
"let [...await f] = [];",
|
||||
"const [...await f] = [];",
|
||||
|
||||
"var { await f } = {};",
|
||||
"let { await f } = {};",
|
||||
"const { await f } = {};",
|
||||
|
||||
"var { ...await f } = {};",
|
||||
"let { ...await f } = {};",
|
||||
"const { ...await f } = {};",
|
||||
|
||||
"var { f: await f } = {};",
|
||||
"let { f: await f } = {};",
|
||||
"const { f: await f } = {};"
|
||||
|
||||
"var { f: ...await f } = {};",
|
||||
"let { f: ...await f } = {};",
|
||||
"const { f: ...await f } = {};"
|
||||
|
||||
"var { [f]: await f } = {};",
|
||||
"let { [f]: await f } = {};",
|
||||
"const { [f]: await f } = {};",
|
||||
|
||||
"var { [f]: ...await f } = {};",
|
||||
"let { [f]: ...await f } = {};",
|
||||
"const { [f]: ...await f } = {};",
|
||||
|
||||
nullptr
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RunParserSyncTest(error_context_data, error_data, kError);
|
||||
}
|
||||
|
||||
TEST(AsyncAwaitFormalParameters) {
|
||||
// clang-format off
|
||||
const char* context_for_formal_parameters[][2] = {
|
||||
|
9
test/message/fail/array-binding-pattern-await1.js
Normal file
9
test/message/fail/array-binding-pattern-await1.js
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
async function f() {
|
||||
let [await b] = [];
|
||||
return b;
|
||||
}
|
||||
f();
|
4
test/message/fail/array-binding-pattern-await1.out
Normal file
4
test/message/fail/array-binding-pattern-await1.out
Normal file
@ -0,0 +1,4 @@
|
||||
*%(basename)s:6: SyntaxError: Invalid destructuring assignment target
|
||||
let [await b] = [];
|
||||
^^^^^^^
|
||||
SyntaxError: Invalid destructuring assignment target
|
9
test/message/fail/object-binding-pattern-await1.js
Normal file
9
test/message/fail/object-binding-pattern-await1.js
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
async function f() {
|
||||
let { a: await b } = { a: 1 };
|
||||
return b;
|
||||
}
|
||||
f();
|
4
test/message/fail/object-binding-pattern-await1.out
Normal file
4
test/message/fail/object-binding-pattern-await1.out
Normal file
@ -0,0 +1,4 @@
|
||||
*%(basename)s:6: SyntaxError: Invalid destructuring assignment target
|
||||
let { a: await b } = { a: 1 };
|
||||
^^^^^^^
|
||||
SyntaxError: Invalid destructuring assignment target
|
@ -0,0 +1,9 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
async function f() {
|
||||
let { [await "a"]: a } = { a: 1 };
|
||||
return a;
|
||||
}
|
||||
f();
|
Loading…
Reference in New Issue
Block a user