diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index 9d0c336b552eb..0abe69472d6d3 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -570,6 +570,15 @@ pub fn cannot_appear_on_an_index_signature(modifier: &Modifier) -> OxcDiagnostic .with_label(modifier.span) } +/// TS(1243) +pub fn accessor_modifier(modifier: &Modifier) -> OxcDiagnostic { + ts_error( + "1243", + format!("'accessor' modifier cannot be used with '{}' modifier.", modifier.kind), + ) + .with_label(modifier.span) +} + /// TS(1354) #[cold] pub fn readonly_in_array_or_tuple_type(span: Span) -> OxcDiagnostic { diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index 412d5a3848a55..e1840bd5c1124 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -304,16 +304,11 @@ impl<'a> ParserImpl<'a> { if optional { self.error(diagnostics::optional_accessor_property(optional_span)); } - Some(self.parse_class_accessor_property( - span, - key, - computed, - r#static, - r#abstract, - r#override, - definite, - accessibility, - )) + Some( + self.parse_class_accessor_property( + span, key, computed, r#static, definite, &modifiers, + ), + ) } else if self.at(Kind::LParen) || self.at(Kind::LAngle) || r#async || generator { if !computed { if let Some((name, span)) = key.prop_name() { @@ -515,32 +510,38 @@ impl<'a> ParserImpl<'a> { key: PropertyKey<'a>, computed: bool, r#static: bool, - r#abstract: bool, - r#override: bool, definite: bool, - accessibility: Option, + modifiers: &Modifiers<'a>, ) -> ClassElement<'a> { let type_annotation = if self.is_ts { self.parse_ts_type_annotation() } else { None }; let value = self.eat(Kind::Eq).then(|| self.parse_assignment_expression_or_higher()); self.asi(); - let r#type = if r#abstract { + let r#type = if modifiers.contains(ModifierKind::Abstract) { AccessorPropertyType::TSAbstractAccessorProperty } else { AccessorPropertyType::AccessorProperty }; - let decorators = self.consume_decorators(); + self.verify_modifiers( + modifiers, + ModifierFlags::ACCESSIBILITY + | ModifierFlags::ACCESSOR + | ModifierFlags::STATIC + | ModifierFlags::ABSTRACT + | ModifierFlags::OVERRIDE, + diagnostics::accessor_modifier, + ); self.ast.class_element_accessor_property( self.end_span(span), r#type, - decorators, + self.consume_decorators(), key, type_annotation, value, computed, r#static, - r#override, + modifiers.contains(ModifierKind::Override), definite, - accessibility, + modifiers.accessibility(), ) } } diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 7cf023352dab7..cefbbce2fc167 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -11886,6 +11886,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc 7 │ } ╰──── + × TS(1243): 'accessor' modifier cannot be used with 'declare' modifier. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/class/accessor-invalid/input.ts:2:3] + 1 │ abstract class Foo { + 2 │ declare accessor prop7: number; + · ─────── + 3 │ private accessor #p: any; + ╰──── + × TS(18010): An accessibility modifier cannot be used with a private identifier. ╭─[babel/packages/babel-parser/test/fixtures/typescript/class/accessor-invalid/input.ts:3:3] 2 │ declare accessor prop7: number; @@ -11902,6 +11910,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc 8 │ abstract accessor f = 1; ╰──── + × TS(1243): 'accessor' modifier cannot be used with 'readonly' modifier. + ╭─[babel/packages/babel-parser/test/fixtures/typescript/class/accessor-invalid/input.ts:9:3] + 8 │ abstract accessor f = 1; + 9 │ readonly accessor g; + · ──────── + 10 │ } + ╰──── + × TS(1092): Type parameters cannot appear on a constructor declaration ╭─[babel/packages/babel-parser/test/fixtures/typescript/class/constructor-with-type-parameters/input.ts:2:14] 1 │ class C { diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index 46bdf1d654ecc..f93492027c1c9 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -20327,6 +20327,22 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private ╰──── help: Remove the duplicate modifier. + × TS(1243): 'accessor' modifier cannot be used with 'readonly' modifier. + ╭─[typescript/tests/cases/conformance/classes/propertyMemberDeclarations/autoAccessorDisallowedModifiers.ts:3:5] + 2 │ accessor accessor a: any; + 3 │ readonly accessor b: any; + · ──────── + 4 │ declare accessor c: any; + ╰──── + + × TS(1243): 'accessor' modifier cannot be used with 'declare' modifier. + ╭─[typescript/tests/cases/conformance/classes/propertyMemberDeclarations/autoAccessorDisallowedModifiers.ts:4:5] + 3 │ readonly accessor b: any; + 4 │ declare accessor c: any; + · ─────── + 5 │ accessor public d: any; + ╰──── + × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[typescript/tests/cases/conformance/classes/propertyMemberDeclarations/autoAccessorDisallowedModifiers.ts:10:15] 9 │ accessor static h: any; diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index 3495d3b3583da..f6867052176c1 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -1377,6 +1377,15 @@ rebuilt : ["x"] `---- + x TS(1243): 'accessor' modifier cannot be used with 'readonly' modifier. + ,-[tasks/coverage/babel/packages/babel-plugin-transform-typescript/test/fixtures/class/accessor-allowDeclareFields-false/input.ts:14:3] + 13 | abstract accessor f = 1; + 14 | readonly accessor g; + : ^^^^^^^^ + 15 | } + `---- + + * class/accessor-allowDeclareFields-true/input.ts x TS(18010): An accessibility modifier cannot be used with a private @@ -1389,6 +1398,15 @@ rebuilt : ["x"] `---- + x TS(1243): 'accessor' modifier cannot be used with 'readonly' modifier. + ,-[tasks/coverage/babel/packages/babel-plugin-transform-typescript/test/fixtures/class/accessor-allowDeclareFields-true/input.ts:14:3] + 13 | abstract accessor f = 1; + 14 | readonly accessor g; + : ^^^^^^^^ + 15 | } + `---- + + * class/head/input.ts Unresolved references mismatch: after transform: ["D", "I"]