From 88fd0a05ec69cb0e99b0fec7d66f4a5b644c83e2 Mon Sep 17 00:00:00 2001 From: Boshen Date: Sun, 12 Mar 2023 23:37:21 +0800 Subject: [PATCH] feat(parser): check `AwaitExpression` --- crates/oxc_parser/src/diagnostics.rs | 5 +-- crates/oxc_parser/src/js/expression.rs | 3 ++ tasks/coverage/babel.snap | 43 ++++++++++++++++++++++---- tasks/coverage/test262.snap | 37 +++++++++++++++++++--- tasks/coverage/typescript.snap | 11 +++++-- 5 files changed, 82 insertions(+), 17 deletions(-) diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index eb6222005..26fb00582 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -277,10 +277,7 @@ pub struct FunctionDeclarationNonStrict( #[derive(Debug, Error, Diagnostic)] #[error("`await` is only allowed within async functions and at the top levels of modules")] #[diagnostic()] -pub struct AwaitExpression( - #[label("`await` is only allowed within async functions and at the top levels of modules")] - pub Span, -); +pub struct AwaitExpression(#[label] pub Span); #[derive(Debug, Error, Diagnostic)] #[error("A 'yield' expression is only allowed in a generator body.")] diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 307f98de0..196bfe1d2 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -997,6 +997,9 @@ impl<'a> Parser<'a> { let span = self.start_span(); self.bump_any(); let has_await = self.ctx.has_await(); + if !has_await { + self.error(diagnostics::AwaitExpression(Span::new(span.start, span.start + 5))); + } self.ctx = self.ctx.and_await(true); let argument = self.parse_unary_expression_base(lhs_span)?; self.ctx = self.ctx.and_await(has_await); diff --git a/tasks/coverage/babel.snap b/tasks/coverage/babel.snap index 8aa1b4e10..64741a422 100644 --- a/tasks/coverage/babel.snap +++ b/tasks/coverage/babel.snap @@ -1,7 +1,7 @@ Babel Summary: AST Parsed : 2051/2069 (99.13%) Positive Passed: 2051/2069 (99.13%) -Negative Passed: 1063/1502 (70.77%) +Negative Passed: 1068/1502 (71.11%) Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js" Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-multiple-labels/input.js" @@ -162,17 +162,13 @@ Expect Syntax Error: "es2016/simple-parameter-list/method/input.js" Expect Syntax Error: "es2016/simple-parameter-list/object-pattern-default/input.js" Expect Syntax Error: "es2016/simple-parameter-list/object-pattern/input.js" Expect Syntax Error: "es2016/simple-parameter-list/rest/input.js" -Expect Syntax Error: "es2017/async-functions/9/input.js" -Expect Syntax Error: "es2017/async-functions/allow-await-outside-function-throw/input.js" Expect Syntax Error: "es2017/async-functions/await-async-function-expression-name/input.js" Expect Syntax Error: "es2017/async-functions/await-binding-inside-arrow-params-inside-async-arrow-params/input.js" Expect Syntax Error: "es2017/async-functions/await-function-declaration-name-inside-async-function/input.js" Expect Syntax Error: "es2017/async-functions/await-inside-arguments-of-async-call-inside-parameters-of-async-arrow-function/input.js" -Expect Syntax Error: "es2017/async-functions/await-inside-arrow-expression-disallowed/input.js" Expect Syntax Error: "es2017/async-functions/await-inside-parameters-of-async-arrow-function/input.js" Expect Syntax Error: "es2017/async-functions/await-inside-parameters-of-nested-arrow-function/input.js" Expect Syntax Error: "es2017/async-functions/await-inside-parameters-of-nested-async-arrow-function/input.js" -Expect Syntax Error: "es2017/async-functions/await-inside-parameters-of-nested-function/input.js" Expect Syntax Error: "es2017/async-functions/await-inside-parameters/input.js" Expect Syntax Error: "es2017/trailing-function-commas/7/input.js" Expect Syntax Error: "es2018/object-rest-spread/24/input.js" @@ -382,7 +378,6 @@ Expect Syntax Error: "typescript/interface/get-set-invalid-reset-parameter/input Expect Syntax Error: "typescript/interface/invalid-modifiers-method-babel-7/input.ts" Expect Syntax Error: "typescript/interface/invalid-modifiers-method/input.ts" Expect Syntax Error: "typescript/interface/invalid-modifiers-property/input.ts" -Expect Syntax Error: "typescript/module-namespace/top-level-await/input.ts" Expect Syntax Error: "typescript/regression/keyword-qualified-type-disallowed/input.ts" Expect Syntax Error: "typescript/scope/redeclaration-class-enum/input.ts" Expect Syntax Error: "typescript/scope/redeclaration-class-type/input.ts" @@ -4018,6 +4013,20 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts" ╰──── help: Try insert a semicolon here + × `await` is only allowed within async functions and at the top levels of modules + ╭─[es2017/async-functions/9/input.js:1:1] + 1 │ function foo(promise) { await promise; } + · ───── + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[es2017/async-functions/allow-await-outside-function-throw/input.js:1:1] + 1 │ function a() { + 2 │ return await 1 + · ───── + 3 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[es2017/async-functions/async-await-as-arrow-binding-identifier/input.js:1:1] 1 │ async await => {} @@ -4032,6 +4041,20 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts" ╰──── help: Try insert a semicolon here + × `await` is only allowed within async functions and at the top levels of modules + ╭─[es2017/async-functions/await-inside-arrow-expression-disallowed/input.js:1:1] + 1 │ () => { await x } + · ───── + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[es2017/async-functions/await-inside-parameters-of-nested-function/input.js:1:1] + 1 │ async function foo() { + 2 │ function bar(x = await 2) {} + · ───── + 3 │ } + ╰──── + × Unexpected token ╭─[es2017/async-functions/export-async/input.js:1:1] 1 │ export async; @@ -8711,6 +8734,14 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts" ╰──── help: Try insert a semicolon here + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/module-namespace/top-level-await/input.ts:1:1] + 1 │ namespace N { + 2 │ const x = await 42; + · ───── + 3 │ } + ╰──── + × Identifier `A` has already been declared ╭─[typescript/scope/redeclaration-class-class/input.ts:1:1] 1 │ class A {} diff --git a/tasks/coverage/test262.snap b/tasks/coverage/test262.snap index 3489d0f31..893edfa16 100644 --- a/tasks/coverage/test262.snap +++ b/tasks/coverage/test262.snap @@ -1,7 +1,7 @@ Test262 Summary: AST Parsed : 44015/44034 (99.96%) Positive Passed: 44015/44034 (99.96%) -Negative Passed: 3315/3917 (84.63%) +Negative Passed: 3319/3917 (84.73%) Expect Syntax Error: "language/block-scope/syntax/function-declarations/in-statement-position-do-statement-while-expression.js" Expect Syntax Error: "language/block-scope/syntax/function-declarations/in-statement-position-for-statement.js" Expect Syntax Error: "language/block-scope/syntax/function-declarations/in-statement-position-if-expression-statement-else-statement.js" @@ -322,10 +322,6 @@ Expect Syntax Error: "language/module-code/early-dup-export-star-as-dflt.js" Expect Syntax Error: "language/module-code/early-export-global.js" Expect Syntax Error: "language/module-code/early-export-unresolvable.js" Expect Syntax Error: "language/module-code/early-new-target.js" -Expect Syntax Error: "language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-declaration-body.js" -Expect Syntax Error: "language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-declaration-params.js" -Expect Syntax Error: "language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-expr-body.js" -Expect Syntax Error: "language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-expr-params.js" Expect Syntax Error: "language/statements/async-function/array-destructuring-param-strict-body.js" Expect Syntax Error: "language/statements/async-function/dflt-params-duplicates.js" Expect Syntax Error: "language/statements/async-function/dflt-params-rest.js" @@ -19651,6 +19647,37 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" · ─ ╰──── + × `await` is only allowed within async functions and at the top levels of modules + ╭─[language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-declaration-body.js:37:1] + 37 │ + 38 │ function fn() { await 0; } + · ───── + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-declaration-params.js:37:1] + 37 │ + 38 │ function fn(x = await 1) { + · ───── + 39 │ return x; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-expr-body.js:28:1] + 28 │ 0, function () { + 29 │ await 1; + · ───── + 30 │ }; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[language/module-code/top-level-await/syntax/early-does-not-propagate-to-fn-expr-params.js:27:1] + 27 │ + 28 │ 0, function (x = await 1) { + · ───── + 29 │ return x; + ╰──── + × Keywords cannot contain escape characters ╭─[language/module-code/top-level-await/syntax/early-no-escaped-await.js:24:1] 24 │ diff --git a/tasks/coverage/typescript.snap b/tasks/coverage/typescript.snap index f1c2e00d4..2fccae8c1 100644 --- a/tasks/coverage/typescript.snap +++ b/tasks/coverage/typescript.snap @@ -1,7 +1,7 @@ TypeScript Summary: AST Parsed : 2305/2338 (98.59%) Positive Passed: 2305/2338 (98.59%) -Negative Passed: 644/2532 (25.43%) +Negative Passed: 645/2532 (25.47%) Expect Syntax Error: "Symbols/ES5SymbolProperty2.ts" Expect Syntax Error: "Symbols/ES5SymbolProperty6.ts" Expect Syntax Error: "additionalChecks/noPropertyAccessFromIndexSignature1.ts" @@ -300,7 +300,6 @@ Expect Syntax Error: "dynamicImport/importCallExpressionAsyncES3CJS.ts" Expect Syntax Error: "dynamicImport/importCallExpressionAsyncES3System.ts" Expect Syntax Error: "dynamicImport/importCallExpressionAsyncES3UMD.ts" Expect Syntax Error: "dynamicImport/importCallExpressionSpecifierNotStringTypeError.ts" -Expect Syntax Error: "enums/awaitAndYield.ts" Expect Syntax Error: "enums/enumConstantMemberWithString.ts" Expect Syntax Error: "enums/enumConstantMemberWithTemplateLiterals.ts" Expect Syntax Error: "enums/enumConstantMembers.ts" @@ -4406,6 +4405,14 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts" 10 │ ╰──── + × `await` is only allowed within async functions and at the top levels of modules + ╭─[enums/awaitAndYield.ts:4:1] + 4 │ enum E { + 5 │ foo = await x, + · ───── + 6 │ baz = yield 1, + ╰──── + × Expect token ╭─[enums/enumErrors.ts:47:1] 47 │