diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index fb507095e0a1c..a4a1f76f37db1 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -646,6 +646,14 @@ pub fn ts_empty_type_argument_list(span: Span) -> OxcDiagnostic { ts_error("1099", "Type argument list cannot be empty.").with_label(span) } +#[cold] +pub fn ts_instantiation_expression_cannot_be_followed_by_property_access( + span: Span, +) -> OxcDiagnostic { + ts_error("1477", "An instantiation expression cannot be followed by a property access.") + .with_label(span) +} + #[cold] pub fn ts_string_literal_expected(span: Span) -> OxcDiagnostic { ts_error("1141", "String literal expected.").with_label(span) diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 545f930880b15..fc6696ee20f97 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -830,11 +830,25 @@ impl<'a> ParserImpl<'a> { }; if is_property_access { + if matches!(lhs, Expression::TSInstantiationExpression(_)) { + self.error( + diagnostics::ts_instantiation_expression_cannot_be_followed_by_property_access( + self.end_span(lhs_span), + ), + ); + } lhs = self.parse_static_member_expression(lhs_span, lhs, question_dot); continue; } if (question_dot || !self.ctx.has_decorator()) && self.at(Kind::LBrack) { + if matches!(lhs, Expression::TSInstantiationExpression(_)) { + self.error( + diagnostics::ts_instantiation_expression_cannot_be_followed_by_property_access( + self.end_span(lhs_span), + ), + ); + } lhs = self.parse_computed_member_expression(lhs_span, lhs, question_dot); continue; } diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index fac663457044d..733d014c3cff8 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -3,7 +3,7 @@ commit: 92c052dc parser_babel Summary: AST Parsed : 2223/2224 (99.96%) Positive Passed: 2210/2224 (99.37%) -Negative Passed: 1655/1689 (97.99%) +Negative Passed: 1656/1689 (98.05%) Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/explicit-resource-management/invalid-for-using-of-no-initializer/input.js Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/cast/unparenthesized-assert-and-assign/input.ts @@ -60,8 +60,6 @@ Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/ty Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/regression/keyword-qualified-type-2/input.ts -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/type-arguments/instantiation-expression-property-access/input.ts - Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/types/const-type-parameters-invalid/input.ts Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/types/invalid-import-type-options-escaped-with/input.ts @@ -14072,6 +14070,37 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ── ╰──── + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/type-arguments/instantiation-expression-property-access/input.ts:2:1] + 1 │ // invalid + 2 │ a.c; + · ───── + 3 │ a?.c; + ╰──── + + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/type-arguments/instantiation-expression-property-access/input.ts:3:1] + 2 │ a.c; + 3 │ a?.c; + · ────── + 4 │ a?.[c]; + ╰──── + + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/type-arguments/instantiation-expression-property-access/input.ts:4:1] + 3 │ a?.c; + 4 │ a?.[c]; + · ────── + 5 │ + ╰──── + + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/type-arguments/instantiation-expression-property-access/input.ts:13:1] + 12 │ // longer, invalid + 13 │ a?.b.d + · ──────── + ╰──── + × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[babel/packages/babel-parser/test/fixtures/typescript/type-arguments/new-without-arguments-missing-semicolon/input.ts:1:9] 1 │ new A if (0); diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index a994927ffcc65..7203d7d8ac15b 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -3,7 +3,7 @@ commit: 95e3aaa9 parser_typescript Summary: AST Parsed : 9842/9843 (99.99%) Positive Passed: 9838/9843 (99.95%) -Negative Passed: 1511/2557 (59.09%) +Negative Passed: 1514/2557 (59.21%) Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration3.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/FunctionDeclaration4.ts @@ -716,8 +716,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/omittedExpre Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/operationsAvailableOnPromisedType.ts -Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/optionalChainWithInstantiationExpression1.ts - Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/optionalParamReferencingOtherParams2.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/optionalParamReferencingOtherParams3.ts @@ -1774,10 +1772,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/parser/ec Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/FunctionDeclarations/parserFunctionDeclaration7.ts -Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts - -Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts - Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration5.ts Expect Syntax Error: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessor1.ts @@ -6510,6 +6504,13 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va ╰──── help: Allowed modifiers are: declare, async + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[typescript/tests/cases/compiler/genericCallWithoutArgs.ts:4:1] + 3 │ + 4 │ f. + · ───────────────── + ╰──── + × Unexpected token ╭─[typescript/tests/cases/compiler/genericCallWithoutArgs.ts:4:18] 3 │ @@ -8990,6 +8991,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va · ─ ╰──── + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[typescript/tests/cases/compiler/optionalChainWithInstantiationExpression1.ts:12:1] + 11 │ + 12 │ a?.b.d; + · ──────── + 13 │ + ╰──── + × Identifier `C1M5` has already been declared ╭─[typescript/tests/cases/compiler/optionalParamArgsTest.ts:31:12] 30 │ @@ -22430,6 +22439,27 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va · ─ ╰──── + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[typescript/tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts:3:1] + 2 │ Foo.Bar(); + 3 │ Foo.Bar(); + · ─────── + 4 │ Foo.Bar(); + ╰──── + + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[typescript/tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts:4:1] + 3 │ Foo.Bar(); + 4 │ Foo.Bar(); + · ─────── + ╰──── + + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[typescript/tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts:1:9] + 1 │ var v = List.makeChild(); + · ───────────── + ╰──── + × Expected `;` but found `[` ╭─[typescript/tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration10.ts:2:18] 1 │ class C { @@ -26747,6 +26777,22 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va 12 │ ╰──── + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[typescript/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts:7:12] + 6 │ const a2 = f.g; // () => number + 7 │ const a3 = f.g; // () => U + · ────────── + 8 │ const a4 = f.g; // () => number + ╰──── + + × TS(1477): An instantiation expression cannot be followed by a property access. + ╭─[typescript/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts:8:12] + 7 │ const a3 = f.g; // () => U + 8 │ const a4 = f.g; // () => number + · ────────── + 9 │ const a5 = f['g']; // () => number + ╰──── + × Unexpected token ╭─[typescript/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts:18:29] 17 │