diff --git a/crates/oxc_linter/src/rules/early_error/javascript.rs b/crates/oxc_linter/src/rules/early_error/javascript.rs index 158205523..e33ff7a00 100644 --- a/crates/oxc_linter/src/rules/early_error/javascript.rs +++ b/crates/oxc_linter/src/rules/early_error/javascript.rs @@ -70,15 +70,26 @@ impl Rule for EarlyErrorJavaScript { } } +#[derive(Debug, Error, Diagnostic)] +#[error("Cannot use await in class static initialization block")] +#[diagnostic()] +struct ClassStatickBlockAwait(#[label] Span); + #[derive(Debug, Error, Diagnostic)] #[error("The keyword '{0}' is reserved")] #[diagnostic()] struct ReservedKeyword(Atom, #[label] Span); fn check_identifier<'a>(name: &Atom, span: Span, node: &AstNode<'a>, ctx: &LintContext<'a>) { - // It is a Syntax Error if the goal symbol of the syntactic grammar is Module and the StringValue of IdentifierName is "await". - if *name == "await" && ctx.source_type().is_module() { - return ctx.diagnostic(ReservedKeyword(name.clone(), span)); + if *name == "await" { + // It is a Syntax Error if the goal symbol of the syntactic grammar is Module and the StringValue of IdentifierName is "await". + if ctx.source_type().is_module() { + return ctx.diagnostic(ReservedKeyword(name.clone(), span)); + } + // It is a Syntax Error if ClassStaticBlockStatementList Contains await is true. + if ctx.scope(node).flags.contains(ScopeFlags::ClassStaticBlock) { + return ctx.diagnostic(ClassStatickBlockAwait(span)); + } } // It is a Syntax Error if this phrase is contained in strict mode code and the StringValue of IdentifierName is: "implements", "interface", "let", "package", "private", "protected", "public", "static", or "yield". @@ -1032,6 +1043,11 @@ fn check_await_expression<'a>(expr: &AwaitExpression, node: &AstNode<'a>, ctx: & if is_in_formal_parameters(node, ctx) { ctx.diagnostic(AwaitOrYieldInParameter("await", expr.span)); } + // It is a Syntax Error if ClassStaticBlockStatementList Contains await is true. + if ctx.scope(node).flags.contains(ScopeFlags::ClassStaticBlock) { + let start = expr.span.start; + ctx.diagnostic(ClassStatickBlockAwait(Span::new(start, start + 5))); + } } fn check_yield_expression<'a>(expr: &YieldExpression, node: &AstNode<'a>, ctx: &LintContext<'a>) { diff --git a/tasks/coverage/test262.snap b/tasks/coverage/test262.snap index 040b38685..3a30a2c74 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: 3903/3917 (99.64%) +Negative Passed: 3905/3917 (99.69%) Expect Syntax Error: "language/global-code/export.js" Expect Syntax Error: "language/global-code/import.js" Expect Syntax Error: "language/import/dup-bound-names.js" @@ -14,8 +14,6 @@ Expect Syntax Error: "language/module-code/early-dup-export-id.js" 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/statements/class/static-init-invalid-await.js" -Expect Syntax Error: "language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-invalid.js" Expect to Parse: "language/block-scope/syntax/redeclaration-global/allowed-to-redeclare-function-declaration-with-var.js" × Identifier `f` has already been declared @@ -13491,6 +13489,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" 27 │ }; ╰──── + × Cannot use await in class static initialization block + ╭─[language/expressions/class/static-init-await-binding.js:20:1] + 20 │ static { + 21 │ (class await {}); + · ───── + 22 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[language/expressions/class/static-init-await-binding.js:20:1] 20 │ static { @@ -16209,6 +16215,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" 32 │ }); ╰──── + × Cannot use await in class static initialization block + ╭─[language/expressions/object/identifier-shorthand-static-init-await-invalid.js:22:1] + 22 │ static { + 23 │ ({ await }); + · ───── + 24 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[language/expressions/object/identifier-shorthand-static-init-await-invalid.js:22:1] 22 │ static { @@ -29413,6 +29427,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" 27 │ } ╰──── + × Cannot use await in class static initialization block + ╭─[language/statements/class/static-init-await-binding-invalid.js:23:1] + 23 │ static { + 24 │ class await {} + · ───── + 25 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[language/statements/class/static-init-await-binding-invalid.js:23:1] 23 │ static { @@ -29429,6 +29451,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" 22 │ } ╰──── + × Cannot use await in class static initialization block + ╭─[language/statements/class/static-init-invalid-await.js:29:1] + 29 │ static { + 30 │ await 0; + · ───── + 31 │ } + ╰──── + × Identifier `x` has already been declared ╭─[language/statements/class/static-init-invalid-label-dup.js:20:1] 20 │ static { @@ -29614,6 +29644,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" 15 │ ╰──── + × Cannot use await in class static initialization block + ╭─[language/statements/const/static-init-await-binding-invalid.js:23:1] + 23 │ static { + 24 │ const await = 0; + · ───── + 25 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[language/statements/const/static-init-await-binding-invalid.js:23:1] 23 │ static { @@ -34131,6 +34169,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" 15 │ ╰──── + × Cannot use await in class static initialization block + ╭─[language/statements/let/static-init-await-binding-invalid.js:23:1] + 23 │ static { + 24 │ let await; + · ───── + 25 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[language/statements/let/static-init-await-binding-invalid.js:23:1] 23 │ static { @@ -35506,6 +35552,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" · ───────── ╰──── + × Cannot use await in class static initialization block + ╭─[language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-invalid.js:23:1] + 23 │ static { + 24 │ var [await] = []; + · ───── + 25 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-invalid.js:23:1] 23 │ static { @@ -35565,6 +35619,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" 30 │ ╰──── + × Cannot use await in class static initialization block + ╭─[language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-invalid.js:23:1] + 23 │ static { + 24 │ var {await} = {}; + · ───── + 25 │ } + ╰──── + × Cannot assign to 'eval' in strict mode ╭─[language/statements/variable/eval-strict-list-final-init.js:14:1] 14 │ @@ -35649,6 +35711,14 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js" · ──── ╰──── + × Cannot use await in class static initialization block + ╭─[language/statements/variable/static-init-await-binding-invalid.js:23:1] + 23 │ static { + 24 │ var await; + · ───── + 25 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[language/statements/variable/static-init-await-binding-invalid.js:23:1] 23 │ static { diff --git a/tasks/coverage/typescript.snap b/tasks/coverage/typescript.snap index a980c92e1..1ab784ef0 100644 --- a/tasks/coverage/typescript.snap +++ b/tasks/coverage/typescript.snap @@ -2809,6 +2809,22 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts" 14 │ ╰──── + × Cannot use await in class static initialization block + ╭─[classes/classStaticBlock/classStaticBlock7.ts:2:1] + 2 │ static { + 3 │ await 1; + · ───── + 4 │ yield 1; + ╰──── + + × Cannot use await in class static initialization block + ╭─[classes/classStaticBlock/classStaticBlock7.ts:11:1] + 11 │ static { + 12 │ await 1; + · ───── + 13 │ + ╰──── + × A 'yield' expression is only allowed in a generator body. ╭─[classes/classStaticBlock/classStaticBlock7.ts:3:1] 3 │ await 1;