diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 7263eb140c8fb..88101e35b9de6 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -1136,11 +1136,10 @@ impl<'a> ParserImpl<'a> { /// await `UnaryExpression`[?Yield, +Await] fn parse_await_expression(&mut self, lhs_span: Span) -> Result> { let span = self.start_span(); - self.bump_any(); - let has_await = self.ctx.has_await(); - if !has_await { - self.error(diagnostics::await_expression(Span::new(span.start, span.start + 5))); + if !self.ctx.has_await() { + self.error(diagnostics::await_expression(self.cur_token().span())); } + self.bump_any(); let argument = self.context(Context::Await, Context::empty(), |p| { p.parse_simple_unary_expression(lhs_span) })?; diff --git a/crates/oxc_parser/src/js/statement.rs b/crates/oxc_parser/src/js/statement.rs index 680916159d61e..4add19cd8203c 100644 --- a/crates/oxc_parser/src/js/statement.rs +++ b/crates/oxc_parser/src/js/statement.rs @@ -241,7 +241,15 @@ impl<'a> ParserImpl<'a> { self.bump_any(); // bump `for` // [+Await] - let r#await = self.ctx.has_await() && self.eat(Kind::Await); + let r#await = if self.at(Kind::Await) { + if !self.ctx.has_await() { + self.error(diagnostics::await_expression(self.cur_token().span())); + } + self.bump_any(); + true + } else { + false + }; self.expect(Kind::LParen)?; diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 7c5369c5e1cea..5ec4f1590b5b0 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -942,11 +942,10 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ────── ╰──── - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[babel/packages/babel-parser/test/fixtures/core/opts/allowAwaitOutsideFunction-false/input.js:1:5] 1 │ for await (const i of imports) {} - · ──┬── - · ╰── `(` expected + · ───── ╰──── × Unexpected new.target expression @@ -5370,12 +5369,11 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ╰── `)` expected ╰──── - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[babel/packages/babel-parser/test/fixtures/es2018/async-generators/for-await-async-context/input.js:2:7] 1 │ function f() { 2 │ for await (let x of y); - · ──┬── - · ╰── `(` expected + · ───── 3 │ } ╰──── @@ -8317,11 +8315,10 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc 3 │ } ╰──── - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[babel/packages/babel-parser/test/fixtures/es2022/top-level-await-script/for-await/input.js:1:5] 1 │ for await (const a of b); - · ──┬── - · ╰── `(` expected + · ───── ╰──── × `await` is only allowed within async functions and at the top levels of modules diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index c7ec8727aa29a..130019b60c928 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -1,7 +1,7 @@ commit: d85767ab parser_typescript Summary: -AST Parsed : 6494/6503 (99.86%) +AST Parsed : 6495/6503 (99.88%) Positive Passed: 6483/6503 (99.69%) Negative Passed: 1239/5747 (21.56%) Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration10.ts @@ -4514,14 +4514,92 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/typings/t Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/typings/typingsSuggestionBun2.ts Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/arrayFromAsync.ts - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:22:5] 21 │ const arr : number[] = []; 22 │ for await (const v of asyncGen(4)) { - · ──┬── - · ╰── `(` expected + · ───── 23 │ arr.push(v); ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:26:18] + 25 │ + 26 │ const sameArr1 = await Array.fromAsync(arrLike); + · ───── + 27 │ const sameArr2 = await Array.fromAsync([Promise.resolve(0), Promise.resolve(2), Promise.resolve(4), Promise.resolve(6)]); + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:27:18] + 26 │ const sameArr1 = await Array.fromAsync(arrLike); + 27 │ const sameArr2 = await Array.fromAsync([Promise.resolve(0), Promise.resolve(2), Promise.resolve(4), Promise.resolve(6)]); + · ───── + 28 │ const sameArr3 = await Array.fromAsync(genPromises(4)); + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:28:18] + 27 │ const sameArr2 = await Array.fromAsync([Promise.resolve(0), Promise.resolve(2), Promise.resolve(4), Promise.resolve(6)]); + 28 │ const sameArr3 = await Array.fromAsync(genPromises(4)); + · ───── + 29 │ const sameArr4 = await Array.fromAsync(asyncGen(4)); + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:29:18] + 28 │ const sameArr3 = await Array.fromAsync(genPromises(4)); + 29 │ const sameArr4 = await Array.fromAsync(asyncGen(4)); + · ───── + 30 │ + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:33:18] + 32 │ Data.fromAsync = Array.fromAsync; + 33 │ const sameArr5 = await Data.fromAsync(asyncGen(4)); + · ───── + 34 │ + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:35:17] + 34 │ + 35 │ const mapArr1 = await Array.fromAsync(asyncGen(4), v => v ** 2); + · ───── + 36 │ const mapArr2 = await Array.fromAsync([0,2,4,6], v => Promise.resolve(v ** 2)); + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:36:17] + 35 │ const mapArr1 = await Array.fromAsync(asyncGen(4), v => v ** 2); + 36 │ const mapArr2 = await Array.fromAsync([0,2,4,6], v => Promise.resolve(v ** 2)); + · ───── + 37 │ const mapArr3 = await Array.fromAsync([0,2,4,6], v => v ** 2); + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:37:17] + 36 │ const mapArr2 = await Array.fromAsync([0,2,4,6], v => Promise.resolve(v ** 2)); + 37 │ const mapArr3 = await Array.fromAsync([0,2,4,6], v => v ** 2); + · ───── + 38 │ + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:42:18] + 41 │ // This returns a promise that will reject with `err`. + 42 │ const badArray = await Array.fromAsync(badIterable); + · ───── + 43 │ + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/arrayFromAsync.ts:44:25] + 43 │ + 44 │ const withIndexResult = await Array.fromAsync(["a", "b"], (str, index) => ({ index, str })); + · ───── + ╰──── Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/bom-utf16be.ts × Invalid Character `￾` @@ -5514,15 +5592,133 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private ╰──── help: Try insert a semicolon here - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:4:7] 3 │ function normalFunc(p: Promise) { 4 │ for await (const _ of []); - · ──┬── - · ╰── `(` expected + · ───── 5 │ return await p; ╰──── + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:5:10] + 4 │ for await (const _ of []); + 5 │ return await p; + · ───── + 6 │ } + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:9:7] + 8 │ export function exportedFunc(p: Promise) { + 9 │ for await (const _ of []); + · ───── + 10 │ return await p; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:10:10] + 9 │ for await (const _ of []); + 10 │ return await p; + · ───── + 11 │ } + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:14:7] + 13 │ const functionExpression = function(p: Promise) { + 14 │ for await (const _ of []); + · ───── + 15 │ await p; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:15:3] + 14 │ for await (const _ of []); + 15 │ await p; + · ───── + 16 │ } + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:19:7] + 18 │ const arrowFunc = (p: Promise) => { + 19 │ for await (const _ of []); + · ───── + 20 │ return await p; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:20:10] + 19 │ for await (const _ of []); + 20 │ return await p; + · ───── + 21 │ }; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:24:7] + 23 │ function* generatorFunc(p: Promise) { + 24 │ for await (const _ of []); + · ───── + 25 │ yield await p; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:25:9] + 24 │ for await (const _ of []); + 25 │ yield await p; + · ───── + 26 │ } + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:30:9] + 29 │ constructor(p: Promise) { + 30 │ for await (const _ of []); + · ───── + 31 │ await p; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:31:5] + 30 │ for await (const _ of []); + 31 │ await p; + · ───── + 32 │ } + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:34:7] + 33 │ method(p: Promise) { + 34 │ for await (const _ of []); + · ───── + 35 │ await p; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:35:5] + 34 │ for await (const _ of []); + 35 │ await p; + · ───── + 36 │ } + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:39:5] + 38 │ + 39 │ for await (const _ of []); + · ───── + 40 │ await null; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInNonAsyncFunction.ts:40:1] + 39 │ for await (const _ of []); + 40 │ await null; + · ───── + ╰──── + × `await` is only allowed within async functions and at the top levels of modules ╭─[typescript/tests/cases/compiler/awaitLiteralValues.ts:2:5] 1 │ function awaitString() { @@ -9387,14 +9583,21 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private ╰──── help: Try insert a semicolon here - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[typescript/tests/cases/compiler/modulePreserveTopLevelAwait1.ts:1:5] 1 │ for await (const x of []) {} - · ──┬── - · ╰── `(` expected + · ───── 2 │ await Promise.resolve(); ╰──── + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/modulePreserveTopLevelAwait1.ts:2:1] + 1 │ for await (const x of []) {} + 2 │ await Promise.resolve(); + · ───── + 3 │ + ╰──── + × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[typescript/tests/cases/compiler/moduleProperty1.ts:9:12] 8 │ var x = 10; // variable local to this module body @@ -19129,12 +19332,11 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 2 │ ╰──── - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[typescript/tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts:5:5] 4 │ 5 │ for await (const item of arr) { - · ──┬── - · ╰── `(` expected + · ───── 6 │ item; ╰──── @@ -22808,12 +23010,20 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 3 │ } ╰──── - × Expected `(` but found `await` + × `await` is only allowed within async functions and at the top levels of modules ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsInForAwaitOf.3.ts:5:5] 4 │ 5 │ for await (await using of x); - · ──┬── - · ╰── `(` expected + · ───── + 6 │ + ╰──── + + × Expected `;` but found `Identifier` + ╭─[typescript/tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsInForAwaitOf.3.ts:5:27] + 4 │ + 5 │ for await (await using of x); + · ┬ + · ╰── `;` expected 6 │ ╰──── diff --git a/tasks/coverage/snapshots/semantic_typescript.snap b/tasks/coverage/snapshots/semantic_typescript.snap index a92c966d0f7d6..c5a21e11ed067 100644 --- a/tasks/coverage/snapshots/semantic_typescript.snap +++ b/tasks/coverage/snapshots/semantic_typescript.snap @@ -987,7 +987,17 @@ after transform: ScopeId(1): ["T", "arr", "depth"] rebuilt : ScopeId(1): ["arr", "depth"] tasks/coverage/typescript/tests/cases/compiler/arrayFromAsync.ts -semantic error: Expected `(` but found `await` +semantic error: `await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules +`await` is only allowed within async functions and at the top levels of modules tasks/coverage/typescript/tests/cases/compiler/arrayLiteralContextualType.ts semantic error: Bindings mismatch: