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:
Andreas Kling 2026-05-21 16:42:41 +02:00 committed by Andreas Kling
parent 72876d8b93
commit 45bd4087c4
2 changed files with 6 additions and 11 deletions

View file

@ -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());

View file

@ -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();
});