diff --git a/crates/oxc_codegen/tests/integration/ts.rs b/crates/oxc_codegen/tests/integration/ts.rs index ce3bb3e60b11c..dd1cc69b62391 100644 --- a/crates/oxc_codegen/tests/integration/ts.rs +++ b/crates/oxc_codegen/tests/integration/ts.rs @@ -10,6 +10,7 @@ fn cases() { test_same("({ foo(): string {} });\n"); test_same("interface I {}\n"); test_same("function F() {}\n"); + test_same("class C {\n\tp = await(0);\n}\n"); } #[test] diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index 07f5ef6041105..a49d284e58d09 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -471,7 +471,10 @@ impl<'a> ParserImpl<'a> { ) -> ClassElement<'a> { let type_annotation = if self.is_ts { self.parse_ts_type_annotation() } else { None }; let decorators = self.consume_decorators(); - let value = if self.eat(Kind::Eq) { Some(self.parse_expr()) } else { None }; + // Initializer[+In, ?Yield, ?Await]opt + let value = self + .eat(Kind::Eq) + .then(|| self.context(Context::In, Context::Yield | Context::Await, Self::parse_expr)); self.asi(); let r#type = if r#abstract { diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 69f3525419033..c289f81bfd592 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -1,9 +1,9 @@ commit: 578ac4df parser_babel Summary: -AST Parsed : 2306/2322 (99.31%) -Positive Passed: 2285/2322 (98.41%) -Negative Passed: 1557/1673 (93.07%) +AST Parsed : 2309/2322 (99.44%) +Positive Passed: 2288/2322 (98.54%) +Negative Passed: 1559/1673 (93.19%) Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/categorized/invalid-startindex-and-startline-specified-without-startcolumn/input.js Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/categorized/startline-and-startcolumn-specified/input.js @@ -34,14 +34,10 @@ Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/no-pattern-in-rest-with-ts/input.js -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/yield-in-class-property-in-generator/input.js - Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-static-block/invalid-decorators/input.js Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/private-in/invalid-private-followed-by-in-2/input.js -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/top-level-await-module/inside-class-property/input.js - Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/esprima/es2015-generator/generator-parameter-binding-property-reserved/input.js Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0276/input.js @@ -254,15 +250,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/o ╰──── help: new.target is only allowed in constructors and functions invoked using thew `new` operator -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-in-private-property-in-params-of-async-arrow/input.js - - × Expected a semicolon or an implicit semicolon after a statement, but found none - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-in-private-property-in-params-of-async-arrow/input.js:1:33] - 1 │ async( x = class { #x = await }) => {} - · ▲ - ╰──── - help: Try insert a semicolon here - Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/arguments-in-key/input.js × 'arguments' is not allowed in class field initializer @@ -273,15 +260,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022 4 │ } ╰──── -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-property-in-params-of-async-arrow/input.js - - × Expected a semicolon or an implicit semicolon after a statement, but found none - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-property-in-params-of-async-arrow/input.js:1:32] - 1 │ async( x = class { x = await }) => {} - · ▲ - ╰──── - help: Try insert a semicolon here - Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/new-target/input.js × Unexpected new.target expression @@ -356,15 +334,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022 ╰──── help: new.target is only allowed in constructors and functions invoked using thew `new` operator -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-static-block/await-binding-in-initializer-in-static-block/input.js - - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-static-block/await-binding-in-initializer-in-static-block/input.js:3:42] - 2 │ - 3 │ C = class { static { class D { x = await } } }; - · ─ - ╰──── - Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-static-block/duplicate-function-var-name/input.js × Identifier `x` has already been declared @@ -8523,6 +8492,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc 4 │ } ╰──── + × The keyword 'yield' is reserved + ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/yield-in-class-property-in-generator/input.js:4:9] + 3 │ // here yield is an identifier reference + 4 │ p = yield + 42; + · ───── + 5 │ } + ╰──── + × Cannot use `await` as an identifier in an async context ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-static-block/await-binding-in-async-arrow-function-in-static-block/input.js:3:29] 2 │ // await is not allowed in async arrow @@ -8725,6 +8702,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ───── ╰──── + × `await` is only allowed within async functions and at the top levels of modules + ╭─[babel/packages/babel-parser/test/fixtures/es2022/top-level-await-module/inside-class-property/input.js:2:7] + 1 │ export class C { + 2 │ p = await 0; + · ───── + 3 │ } + ╰──── + × `await` is only allowed within async functions and at the top levels of modules ╭─[babel/packages/babel-parser/test/fixtures/es2022/top-level-await-module/inside-function/input.js:2:3] 1 │ function fn() { diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index e5e6a6e15ea38..0343db03648ff 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -3,7 +3,7 @@ commit: 15392346 parser_typescript Summary: AST Parsed : 6523/6531 (99.88%) Positive Passed: 6511/6531 (99.69%) -Negative Passed: 1309/5754 (22.75%) +Negative Passed: 1314/5754 (22.84%) Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration24.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ExportAssignment7.ts @@ -326,8 +326,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/avoidListing Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/awaitCallExpressionInSyncFunction.ts -Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/awaitInClassInAsyncFunction.ts - Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/awaitedType.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/awaitedTypeNoLib.ts @@ -4612,8 +4610,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/async/es6 Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/asyncGenerators/asyncGeneratorParameterEvaluation.ts -Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts - Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAssignabilityConstructorFunction.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractClinterfaceAssignability.ts @@ -5836,16 +5832,10 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yield Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck31.ts -Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts - Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck48.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck50.ts -Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck57.ts - -Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck58.ts - Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck6.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck62.ts @@ -10059,6 +10049,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private ╰──── help: Try insert a semicolon here + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/compiler/awaitInClassInAsyncFunction.ts:9:15] + 8 │ return new class { + 9 │ baz = await bar(); + · ───── + 10 │ }; + ╰──── + × `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) { @@ -18654,6 +18652,70 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 47 │ } ╰──── + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:3:21] + 2 │ class C { + 3 │ [await x] = await x; + · ───── + 4 │ static [await x] = await x; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:4:28] + 3 │ [await x] = await x; + 4 │ static [await x] = await x; + · ───── + 5 │ + ╰──── + + × A 'yield' expression is only allowed in a generator body. + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:6:21] + 5 │ + 6 │ [yield 1] = yield 2; + · ───── + 7 │ static [yield 3] = yield 4; + ╰──── + + × A 'yield' expression is only allowed in a generator body. + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:7:28] + 6 │ [yield 1] = yield 2; + 7 │ static [yield 3] = yield 4; + · ───── + 8 │ } + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:11:21] + 10 │ return class { + 11 │ [await x] = await x; + · ───── + 12 │ static [await x] = await x; + ╰──── + + × `await` is only allowed within async functions and at the top levels of modules + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:12:28] + 11 │ [await x] = await x; + 12 │ static [await x] = await x; + · ───── + 13 │ + ╰──── + + × A 'yield' expression is only allowed in a generator body. + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:14:21] + 13 │ + 14 │ [yield 1] = yield 2; + · ───── + 15 │ static [yield 3] = yield 4; + ╰──── + + × A 'yield' expression is only allowed in a generator body. + ╭─[typescript/tests/cases/conformance/classes/awaitAndYieldInProperty.ts:15:28] + 14 │ [yield 1] = yield 2; + 15 │ static [yield 3] = yield 4; + · ───── + 16 │ } + ╰──── + × TS(1318): Accessor 'aa' cannot have an implementation because it is marked abstract. ╭─[typescript/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractAccessor.ts:3:17] 2 │ abstract get a(); @@ -19002,12 +19064,36 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 20 │ } ╰──── - × Unexpected token - ╭─[typescript/tests/cases/conformance/classes/classStaticBlock/classStaticBlock22.ts:25:16] - 24 │ await = 1; // legal - 25 │ x = await; // legal (initializers have an implicit function boundary) - · ─ - 26 │ }; + × Cannot use `await` as an identifier in an async context + ╭─[typescript/tests/cases/conformance/classes/classStaticBlock/classStaticBlock22.ts:32:12] + 31 │ static { + 32 │ (class await { }); // legal, 'await' in class expression name not bound inside of static block + · ───── + 33 │ } + ╰──── + + × Cannot use await in class static initialization block + ╭─[typescript/tests/cases/conformance/classes/classStaticBlock/classStaticBlock22.ts:4:9] + 3 │ static { + 4 │ let await: any; // illegal, cannot declare a new binding for await + · ────────── + 5 │ } + ╰──── + + × Cannot use await in class static initialization block + ╭─[typescript/tests/cases/conformance/classes/classStaticBlock/classStaticBlock22.ts:7:11] + 6 │ static { + 7 │ let { await } = {} as any; // illegal, cannot declare a new binding for await + · ───── + 8 │ } + ╰──── + + × Cannot use await in class static initialization block + ╭─[typescript/tests/cases/conformance/classes/classStaticBlock/classStaticBlock22.ts:13:9] + 12 │ static { + 13 │ let await; // illegal, cannot declare a new binding for await + · ───── + 14 │ } ╰──── × Unexpected token @@ -22036,6 +22122,30 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private · ───── ╰──── + × A 'yield' expression is only allowed in a generator body. + ╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck39.ts:7:13] + 6 │ class C { + 7 │ x = yield 0; + · ───── + 8 │ } + ╰──── + + × A 'yield' expression is only allowed in a generator body. + ╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck57.ts:3:13] + 2 │ class C { + 3 │ x = yield 0; + · ───── + 4 │ }; + ╰──── + + × A 'yield' expression is only allowed in a generator body. + ╭─[typescript/tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck58.ts:3:20] + 2 │ class C { + 3 │ static x = yield 0; + · ───── + 4 │ }; + ╰──── + × Cannot assign to this expression ╭─[typescript/tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts:7:9] 6 │ constructor() { diff --git a/tasks/coverage/snapshots/semantic_babel.snap b/tasks/coverage/snapshots/semantic_babel.snap index 76526ec8f8016..834597c4dfa3d 100644 --- a/tasks/coverage/snapshots/semantic_babel.snap +++ b/tasks/coverage/snapshots/semantic_babel.snap @@ -2,7 +2,7 @@ commit: 578ac4df semantic_babel Summary: AST Parsed : 2322/2322 (100.00%) -Positive Passed: 1903/2322 (81.96%) +Positive Passed: 1905/2322 (82.04%) semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/annex-b/enabled/3.3-function-in-if-body/input.js Symbol scope ID mismatch for "f": after transform: SymbolId(0): ScopeId(4294967294) @@ -78,7 +78,15 @@ after transform: ScopeId(5): ScopeFlags(StrictMode) rebuilt : ScopeId(7): ScopeFlags(0x0) semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-in-private-property-in-params-of-async-arrow/input.js -Expected a semicolon or an implicit semicolon after a statement, but found none +Bindings mismatch: +after transform: ScopeId(0): ["_asyncToGenerator", "_classPrivateFieldInitSpec"] +rebuilt : ScopeId(0): ["_asyncToGenerator", "_classPrivateFieldInitSpec", "_x"] +Bindings mismatch: +after transform: ScopeId(1): ["_x", "x"] +rebuilt : ScopeId(1): ["x"] +Symbol scope ID mismatch for "_x": +after transform: SymbolId(1): ScopeId(1) +rebuilt : SymbolId(2): ScopeId(0) semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/arguments-in-key/input.js 'arguments' is not allowed in class field initializer @@ -94,9 +102,6 @@ Symbol scope ID mismatch for "_await": after transform: SymbolId(3): ScopeId(2) rebuilt : SymbolId(2): ScopeId(0) -semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-property-in-params-of-async-arrow/input.js -Expected a semicolon or an implicit semicolon after a statement, but found none - semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/new-target/input.js Unexpected new.target expression Unexpected new.target expression @@ -107,9 +112,6 @@ Unexpected new.target expression Unexpected new.target expression Unexpected new.target expression -semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-static-block/await-binding-in-initializer-in-static-block/input.js -Unexpected token - semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-static-block/duplicate-function-var-name/input.js Identifier `x` has already been declared diff --git a/tasks/coverage/snapshots/transformer_babel.snap b/tasks/coverage/snapshots/transformer_babel.snap index eda40960a5527..4f3728db3b3a1 100644 --- a/tasks/coverage/snapshots/transformer_babel.snap +++ b/tasks/coverage/snapshots/transformer_babel.snap @@ -2,8 +2,4 @@ commit: 578ac4df transformer_babel Summary: AST Parsed : 2322/2322 (100.00%) -Positive Passed: 2320/2322 (99.91%) -Mismatch: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-in-private-property-in-async/input.js - -Mismatch: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-class-property-in-async/input.js - +Positive Passed: 2322/2322 (100.00%)