LibJS: Reject unparenthesized await before exponentiation
Parse await through the unary-expression path so the existing exponentiation early error also applies to AwaitExpression. This keeps parenthesized await expressions valid while rejecting await on the left-hand side of **. Add parser coverage for the async-function constructor case.
This commit is contained in:
parent
72876d8b93
commit
45bd4087c4
2 changed files with 6 additions and 11 deletions
|
|
@ -81,7 +81,7 @@ impl Parser<'_> {
|
|||
| TokenType::Typeof
|
||||
| TokenType::Void
|
||||
| TokenType::Delete
|
||||
)
|
||||
) || (self.flags.await_expression_is_valid && self.current_token_type() == TokenType::Await)
|
||||
}
|
||||
|
||||
pub(crate) fn match_secondary_expression(&self, forbidden: &ForbiddenTokens) -> bool {
|
||||
|
|
@ -546,16 +546,6 @@ impl Parser<'_> {
|
|||
(expression, false)
|
||||
}
|
||||
|
||||
// https://tc39.es/ecma262/#sec-async-function-definitions
|
||||
// AwaitExpression : `await` UnaryExpression
|
||||
// NB: Unlike yield (AssignmentExpression level), await is at
|
||||
// UnaryExpression level, so `await 1 + 2` is `(await 1) + 2`.
|
||||
// We set should_continue=true to allow binary operators.
|
||||
TokenType::Await if self.flags.await_expression_is_valid => {
|
||||
let expression = self.parse_await_expression();
|
||||
(expression, true)
|
||||
}
|
||||
|
||||
TokenType::PrivateIdentifier => {
|
||||
let id = self.parse_private_identifier(start);
|
||||
(
|
||||
|
|
@ -1069,6 +1059,7 @@ impl Parser<'_> {
|
|||
let tt = self.current_token_type();
|
||||
|
||||
match tt {
|
||||
TokenType::Await if self.flags.await_expression_is_valid => self.parse_await_expression(),
|
||||
TokenType::PlusPlus => {
|
||||
self.consume();
|
||||
let expression = self.parse_expression(PRECEDENCE_UNARY, Associativity::Right, ForbiddenTokens::none());
|
||||
|
|
|
|||
|
|
@ -6,4 +6,8 @@ test("syntax error for an unary expression before exponentiation", () => {
|
|||
expect(`typeof 5 ** 2`).not.toEval();
|
||||
expect(`void 5 ** 2`).not.toEval();
|
||||
expect(`delete 5 ** 2`).not.toEval();
|
||||
|
||||
const AsyncFunction = async function () {}.constructor;
|
||||
expect(() => AsyncFunction("await 5 ** 2")).toThrow(SyntaxError);
|
||||
expect(() => AsyncFunction("(await 5) ** 2")).not.toThrow();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue