diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index 323f42e078f37..08e8f352ce860 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -1144,6 +1144,16 @@ pub fn getter_parameters(span: Span) -> OxcDiagnostic { .with_help("Remove these parameters here") } +#[cold] +pub fn setter_with_optional_parameter(span: Span) -> OxcDiagnostic { + ts_error("1051", "A 'set' accessor cannot have an optional parameter.").with_label(span) +} + +#[cold] +pub fn accessor_cannot_have_this_parameter(span: Span) -> OxcDiagnostic { + ts_error("2784", "'get' and 'set' accessors cannot declare 'this' parameters.").with_label(span) +} + #[cold] pub fn variable_declarator_definite(span: Span) -> OxcDiagnostic { ts_error( diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index 8dbea2c9fe66e..5879d829392e2 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -1213,13 +1213,40 @@ impl<'a> ParserImpl<'a> { self.parse_formal_parameters(FunctionKind::Declaration, FormalParameterKind::Signature); let return_type = self.parse_ts_return_type_annotation(); self.parse_type_member_semicolon(); - if kind == TSMethodSignatureKind::Set - && let Some(return_type) = return_type.as_ref() - { - self.error(diagnostics::a_set_accessor_cannot_have_a_return_type_annotation( - return_type.span, - )); + + if let Some(this_param) = &this_param { + self.error(diagnostics::accessor_cannot_have_this_parameter(this_param.span)); + } + + match kind { + TSMethodSignatureKind::Get => { + if !params.items.is_empty() { + self.error(diagnostics::getter_parameters(params.span)); + } + } + TSMethodSignatureKind::Set => { + if let Some(return_type) = return_type.as_ref() { + self.error(diagnostics::a_set_accessor_cannot_have_a_return_type_annotation( + return_type.span, + )); + } + if let Some(rest) = ¶ms.rest { + self.error(diagnostics::setter_with_rest_parameter(rest.span)); + } + if params.items.len() != 1 { + self.error(diagnostics::setter_with_parameters( + params.span, + params.items.len(), + )); + } else if let Some(param) = params.items.first() + && param.optional + { + self.error(diagnostics::setter_with_optional_parameter(param.span)); + } + } + TSMethodSignatureKind::Method => {} } + self.ast.ts_signature_method_signature( self.end_span(span), key, diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index a56000c1eed28..9c4fc6ab7ceeb 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -3,7 +3,7 @@ commit: fc58af40 parser_babel Summary: AST Parsed : 2217/2223 (99.73%) Positive Passed: 2204/2223 (99.15%) -Negative Passed: 1649/1689 (97.63%) +Negative Passed: 1654/1689 (97.93%) 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 @@ -56,16 +56,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/import/equals-require-in-script/input.ts -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/input.ts - -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/input.ts - -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/input.ts - -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter-babel-7/input.ts - -Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts - Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/module-namespace/module-identifier-invalid/input.ts Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/regression/keyword-qualified-type-2/input.ts @@ -13323,6 +13313,66 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ─ ╰──── + × TS(1051): A 'set' accessor cannot have an optional parameter. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-optional-parameter/input.ts:2:11] + 1 │ interface Foo { + 2 │ set bar(foo?: string); + · ──────────── + 3 │ } + ╰──── + + × A 'get' accessor must not have any formal parameters. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/input.ts:2:10] + 1 │ interface Foo { + 2 │ get foo(param): string; + · ─────── + 3 │ set foo(); + ╰──── + help: Remove these parameters here + + × A 'set' accessor must have exactly one parameter. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-parameters/input.ts:3:10] + 2 │ get foo(param): string; + 3 │ set foo(); + · ── + 4 │ } + ╰──── + help: Add a parameter here + + × A 'set' accessor cannot have rest parameter. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/input.ts:2:11] + 1 │ interface Foo { + 2 │ set bar(...v); + · ──── + 3 │ } + ╰──── + + × A 'set' accessor must have exactly one parameter. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter/input.ts:2:10] + 1 │ interface Foo { + 2 │ set bar(...v); + · ────── + 3 │ } + ╰──── + help: Add a parameter here + + × A 'set' accessor cannot have rest parameter. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter-babel-7/input.ts:2:11] + 1 │ interface Foo { + 2 │ set bar(...v); + · ──── + 3 │ } + ╰──── + + × A 'set' accessor must have exactly one parameter. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-reset-parameter-babel-7/input.ts:2:10] + 1 │ interface Foo { + 2 │ set bar(...v); + · ────── + 3 │ } + ╰──── + help: Add a parameter here + × TS(1095): A 'set' accessor cannot have a return type annotation. ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-return-types/input.ts:2:17] 1 │ interface Foo { @@ -13331,6 +13381,31 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc 3 │ } ╰──── + × TS(2784): 'get' and 'set' accessors cannot declare 'this' parameters. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts:2:11] + 1 │ interface Foo { + 2 │ get bar(this: Foo); + · ───────── + 3 │ set bar(this: Foo); + ╰──── + + × TS(2784): 'get' and 'set' accessors cannot declare 'this' parameters. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts:3:11] + 2 │ get bar(this: Foo); + 3 │ set bar(this: Foo); + · ───────── + 4 │ } + ╰──── + + × A 'set' accessor must have exactly one parameter. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-invalid-this-parameters/input.ts:3:10] + 2 │ get bar(this: Foo); + 3 │ set bar(this: Foo); + · ─────────── + 4 │ } + ╰──── + help: Add a parameter here + × Expected `(` but found `<` ╭─[babel/packages/babel-parser/test/fixtures/typescript/interface/get-set-type-parameters/input.ts:2:10] 1 │ interface Foo {