diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 03fe48524..10aa58bf1 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -1580,8 +1580,8 @@ pub struct Class<'a> { pub type_parameters: Option>>, pub super_type_parameters: Option>>, pub implements: Option>>, - /// Valid Modifiers: `export`, `abstract` - pub modifiers: Modifiers<'a>, + pub r#abstract: bool, + pub declare: bool, pub scope_id: Cell>, } diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index 33751363b..31fe3d2e8 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -1022,7 +1022,8 @@ impl<'a> AstBuilder<'a> { super_type_parameters: Option>>, implements: Option>>, decorators: Vec<'a, Decorator<'a>>, - modifiers: Modifiers<'a>, + r#abstract: bool, + declare: bool, ) -> Box<'a, Class<'a>> { self.alloc(Class::new( r#type, @@ -1034,7 +1035,8 @@ impl<'a> AstBuilder<'a> { type_parameters, super_type_parameters, implements, - modifiers, + r#abstract, + declare, )) } diff --git a/crates/oxc_ast/src/ast_impl/js.rs b/crates/oxc_ast/src/ast_impl/js.rs index d08d47e99..4f741414b 100644 --- a/crates/oxc_ast/src/ast_impl/js.rs +++ b/crates/oxc_ast/src/ast_impl/js.rs @@ -709,7 +709,7 @@ impl<'a> Declaration<'a> { match self { Declaration::VariableDeclaration(decl) => decl.declare, Declaration::FunctionDeclaration(decl) => decl.modifiers.is_contains_declare(), - Declaration::ClassDeclaration(decl) => decl.modifiers.is_contains_declare(), + Declaration::ClassDeclaration(decl) => decl.declare, Declaration::TSEnumDeclaration(decl) => decl.modifiers.is_contains_declare(), Declaration::TSTypeAliasDeclaration(decl) => decl.modifiers.is_contains_declare(), Declaration::TSModuleDeclaration(decl) => decl.modifiers.is_contains_declare(), @@ -1110,7 +1110,8 @@ impl<'a> Class<'a> { type_parameters: Option>>, super_type_parameters: Option>>, implements: Option>>, - modifiers: Modifiers<'a>, + r#abstract: bool, + declare: bool, ) -> Self { Self { r#type, @@ -1122,7 +1123,8 @@ impl<'a> Class<'a> { type_parameters, super_type_parameters, implements, - modifiers, + r#abstract, + declare, scope_id: Cell::default(), } } @@ -1145,30 +1147,12 @@ impl<'a> Class<'a> { /// // ... /// } /// ``` - /// - /// Not to be confused with [`Class::is_declare`]. pub fn is_declaration(&self) -> bool { self.r#type == ClassType::ClassDeclaration } - /// `true` if this [`Class`] is being within a typescript declaration file - /// or `declare` statement. - /// - /// For example, - /// ```ts - /// declare global { - /// declare class Foo { - /// // ... - /// } - /// } - /// - /// Not to be confused with [`Class::is_declaration`]. - pub fn is_declare(&self) -> bool { - self.modifiers.contains(ModifierKind::Declare) - } - pub fn is_typescript_syntax(&self) -> bool { - self.is_declare() + self.declare || self.r#abstract } } @@ -1182,7 +1166,8 @@ impl<'a> Hash for Class<'a> { self.type_parameters.hash(state); self.super_type_parameters.hash(state); self.implements.hash(state); - self.modifiers.hash(state); + self.r#abstract.hash(state); + self.declare.hash(state); } } diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 992e4f29f..016b02fa5 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -2081,10 +2081,10 @@ impl<'a, const MINIFY: bool> Gen for MetaProperty<'a> { impl<'a, const MINIFY: bool> Gen for Class<'a> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { p.add_source_mapping(self.span.start); - if self.modifiers.is_contains_declare() { + if self.declare { p.print_str(b"declare "); } - if self.modifiers.is_contains_abstract() { + if self.r#abstract { p.print_str(b"abstract "); } let n = p.code_len(); diff --git a/crates/oxc_isolated_declarations/src/class.rs b/crates/oxc_isolated_declarations/src/class.rs index 1064cdb10..3f6a43561 100644 --- a/crates/oxc_isolated_declarations/src/class.rs +++ b/crates/oxc_isolated_declarations/src/class.rs @@ -308,7 +308,7 @@ impl<'a> IsolatedDeclarations<'a> { decl: &Class<'a>, modifiers: Option>, ) -> Option>> { - if decl.is_declare() { + if decl.declare { return None; } @@ -463,7 +463,7 @@ impl<'a> IsolatedDeclarations<'a> { let body = self.ast.class_body(decl.body.span, elements); let mut modifiers = modifiers.unwrap_or_else(|| self.modifiers_declare()); - if decl.modifiers.is_contains_abstract() { + if decl.r#abstract { modifiers.add_modifier(Modifier { span: SPAN, kind: ModifierKind::Abstract }); }; @@ -477,7 +477,8 @@ impl<'a> IsolatedDeclarations<'a> { self.ast.copy(&decl.super_type_parameters), self.ast.copy(&decl.implements), self.ast.new_vec(), - modifiers, + modifiers.is_contains_abstract(), + modifiers.is_contains_declare(), )) } diff --git a/crates/oxc_linter/src/rules/eslint/no_useless_constructor.rs b/crates/oxc_linter/src/rules/eslint/no_useless_constructor.rs index a6a26803f..1c91b3e2b 100644 --- a/crates/oxc_linter/src/rules/eslint/no_useless_constructor.rs +++ b/crates/oxc_linter/src/rules/eslint/no_useless_constructor.rs @@ -103,7 +103,7 @@ impl Rule for NoUselessConstructor { return; }; let AstKind::Class(class) = class_node.kind() else { unreachable!() }; - if class.is_declare() { + if class.declare { return; } diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index b83638d15..fbb534fa3 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -19,7 +19,7 @@ impl<'a> ParserImpl<'a> { stmt_ctx: StatementContext, start_span: Span, ) -> Result> { - let decl = self.parse_class_declaration(start_span, Modifiers::empty())?; + let decl = self.parse_class_declaration(start_span, &Modifiers::empty())?; if stmt_ctx.is_single_statement() { self.error(diagnostics::class_declaration(Span::new( @@ -35,7 +35,7 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_class_declaration( &mut self, start_span: Span, - modifiers: Modifiers<'a>, + modifiers: &Modifiers<'a>, ) -> Result>> { self.parse_class(start_span, ClassType::ClassDeclaration, modifiers) } @@ -45,7 +45,7 @@ impl<'a> ParserImpl<'a> { /// class `BindingIdentifier`[?Yield, ?Await]opt `ClassTail`[?Yield, ?Await] pub(crate) fn parse_class_expression(&mut self) -> Result> { let class = - self.parse_class(self.start_span(), ClassType::ClassExpression, Modifiers::empty())?; + self.parse_class(self.start_span(), ClassType::ClassExpression, &Modifiers::empty())?; Ok(self.ast.class_expression(class)) } @@ -53,7 +53,7 @@ impl<'a> ParserImpl<'a> { &mut self, start_span: Span, r#type: ClassType, - modifiers: Modifiers<'a>, + modifiers: &Modifiers<'a>, ) -> Result>> { self.bump_any(); // advance `class` @@ -80,6 +80,15 @@ impl<'a> ParserImpl<'a> { } let body = self.parse_class_body()?; + for modifier in modifiers.iter() { + if !matches!(modifier.kind, ModifierKind::Declare | ModifierKind::Abstract) { + self.error(diagnostics::modifiers_cannot_appear( + modifier.span, + modifier.kind.as_str(), + )); + } + } + Ok(self.ast.class( r#type, self.end_span(start_span), @@ -90,7 +99,8 @@ impl<'a> ParserImpl<'a> { super_type_parameters, implements, decorators, - modifiers, + modifiers.is_contains_abstract(), + modifiers.is_contains_declare(), )) } diff --git a/crates/oxc_parser/src/js/module.rs b/crates/oxc_parser/src/js/module.rs index d2d614e00..879d0019d 100644 --- a/crates/oxc_parser/src/js/module.rs +++ b/crates/oxc_parser/src/js/module.rs @@ -318,12 +318,12 @@ impl<'a> ParserImpl<'a> { self.eat_decorators()?; let declaration = match self.cur_kind() { Kind::Class => self - .parse_class_declaration(decl_span, /* modifiers */ Modifiers::empty()) + .parse_class_declaration(decl_span, /* modifiers */ &Modifiers::empty()) .map(ExportDefaultDeclarationKind::ClassDeclaration)?, _ if self.at(Kind::Abstract) && self.peek_at(Kind::Class) && self.ts_enabled() => { // eat the abstract modifier let (_, modifiers) = self.eat_modifiers_before_declaration(); - self.parse_class_declaration(decl_span, modifiers) + self.parse_class_declaration(decl_span, &modifiers) .map(ExportDefaultDeclarationKind::ClassDeclaration)? } _ if self.at(Kind::Interface) diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index 6aaffd660..7ef044322 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -294,7 +294,7 @@ impl<'a> ParserImpl<'a> { self.parse_ts_interface_declaration(start_span, modifiers) } Kind::Class => self - .parse_class_declaration(start_span, modifiers) + .parse_class_declaration(start_span, &modifiers) .map(Declaration::ClassDeclaration), Kind::Import => { self.bump_any(); diff --git a/crates/oxc_prettier/src/format/class.rs b/crates/oxc_prettier/src/format/class.rs index b97a52b55..0ad921e5a 100644 --- a/crates/oxc_prettier/src/format/class.rs +++ b/crates/oxc_prettier/src/format/class.rs @@ -11,7 +11,7 @@ use crate::{ pub(super) fn print_class<'a>(p: &mut Prettier<'a>, class: &Class<'a>) -> Doc<'a> { let mut parts = p.vec(); - if class.modifiers.contains(ModifierKind::Abstract) { + if class.r#abstract { parts.push(ss!("abstract ")); } parts.push(ss!("class ")); diff --git a/crates/oxc_semantic/src/binder.rs b/crates/oxc_semantic/src/binder.rs index aa9406df9..d3fbc67f9 100644 --- a/crates/oxc_semantic/src/binder.rs +++ b/crates/oxc_semantic/src/binder.rs @@ -79,7 +79,7 @@ impl<'a> Binder for VariableDeclarator<'a> { impl<'a> Binder for Class<'a> { fn bind(&self, builder: &mut SemanticBuilder) { let Some(ident) = &self.id else { return }; - if !self.modifiers.contains(ModifierKind::Declare) { + if !self.declare { let symbol_id = builder.declare_symbol( ident.span, &ident.name, diff --git a/crates/oxc_semantic/src/checker/mod.rs b/crates/oxc_semantic/src/checker/mod.rs index 3e6e4e3dd..236cba6df 100644 --- a/crates/oxc_semantic/src/checker/mod.rs +++ b/crates/oxc_semantic/src/checker/mod.rs @@ -71,7 +71,6 @@ pub fn check<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { } AstKind::Class(class) => { js::check_class(class, node, ctx); - ts::check_class(class, node, ctx); } AstKind::MethodDefinition(method) => js::check_method_definition(method, ctx), AstKind::ObjectProperty(prop) => js::check_object_property(prop, ctx), diff --git a/crates/oxc_semantic/src/checker/typescript.rs b/crates/oxc_semantic/src/checker/typescript.rs index d4b6c9387..b6423831e 100644 --- a/crates/oxc_semantic/src/checker/typescript.rs +++ b/crates/oxc_semantic/src/checker/typescript.rs @@ -176,9 +176,6 @@ fn check_declaration_modifiers<'a>( pub fn check_function<'a>(function: &Function<'a>, node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { check_declaration_modifiers(&function.modifiers, node, ctx); } -pub fn check_class<'a>(class: &Class<'a>, node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) { - check_declaration_modifiers(&class.modifiers, node, ctx); -} pub fn check_ts_type_alias_declaration<'a>( decl: &TSTypeAliasDeclaration<'a>, diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index a01243efc..4cd14a1b4 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -165,7 +165,8 @@ impl<'a> TypeScriptAnnotations<'a> { class.type_parameters = None; class.super_type_parameters = None; class.implements = None; - class.modifiers = Modifiers::empty(); + class.r#abstract = false; + class.declare = false; } pub fn transform_class_body(&mut self, body: &mut ClassBody<'a>) { diff --git a/crates/oxc_traverse/src/ancestor.rs b/crates/oxc_traverse/src/ancestor.rs index 6b1677ce8..d1308878f 100644 --- a/crates/oxc_traverse/src/ancestor.rs +++ b/crates/oxc_traverse/src/ancestor.rs @@ -6124,7 +6124,8 @@ pub(crate) const OFFSET_CLASS_TYPE_PARAMETERS: usize = offset_of!(Class, type_pa pub(crate) const OFFSET_CLASS_SUPER_TYPE_PARAMETERS: usize = offset_of!(Class, super_type_parameters); pub(crate) const OFFSET_CLASS_IMPLEMENTS: usize = offset_of!(Class, implements); -pub(crate) const OFFSET_CLASS_MODIFIERS: usize = offset_of!(Class, modifiers); +pub(crate) const OFFSET_CLASS_ABSTRACT: usize = offset_of!(Class, r#abstract); +pub(crate) const OFFSET_CLASS_DECLARE: usize = offset_of!(Class, declare); pub(crate) const OFFSET_CLASS_SCOPE_ID: usize = offset_of!(Class, scope_id); #[repr(transparent)] @@ -6186,8 +6187,13 @@ impl<'a> ClassWithoutDecorators<'a> { } #[inline] - pub fn modifiers(&self) -> &Modifiers<'a> { - unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_MODIFIERS) as *const Modifiers<'a>) } + pub fn r#abstract(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) } + } + + #[inline] + pub fn declare(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) } } #[inline] @@ -6257,8 +6263,13 @@ impl<'a> ClassWithoutId<'a> { } #[inline] - pub fn modifiers(&self) -> &Modifiers<'a> { - unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_MODIFIERS) as *const Modifiers<'a>) } + pub fn r#abstract(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) } + } + + #[inline] + pub fn declare(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) } } #[inline] @@ -6328,8 +6339,13 @@ impl<'a> ClassWithoutSuperClass<'a> { } #[inline] - pub fn modifiers(&self) -> &Modifiers<'a> { - unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_MODIFIERS) as *const Modifiers<'a>) } + pub fn r#abstract(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) } + } + + #[inline] + pub fn declare(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) } } #[inline] @@ -6401,8 +6417,13 @@ impl<'a> ClassWithoutBody<'a> { } #[inline] - pub fn modifiers(&self) -> &Modifiers<'a> { - unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_MODIFIERS) as *const Modifiers<'a>) } + pub fn r#abstract(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) } + } + + #[inline] + pub fn declare(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) } } #[inline] @@ -6471,8 +6492,13 @@ impl<'a> ClassWithoutTypeParameters<'a> { } #[inline] - pub fn modifiers(&self) -> &Modifiers<'a> { - unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_MODIFIERS) as *const Modifiers<'a>) } + pub fn r#abstract(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) } + } + + #[inline] + pub fn declare(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) } } #[inline] @@ -6541,8 +6567,13 @@ impl<'a> ClassWithoutSuperTypeParameters<'a> { } #[inline] - pub fn modifiers(&self) -> &Modifiers<'a> { - unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_MODIFIERS) as *const Modifiers<'a>) } + pub fn r#abstract(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) } + } + + #[inline] + pub fn declare(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) } } #[inline] @@ -6611,8 +6642,13 @@ impl<'a> ClassWithoutImplements<'a> { } #[inline] - pub fn modifiers(&self) -> &Modifiers<'a> { - unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_MODIFIERS) as *const Modifiers<'a>) } + pub fn r#abstract(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_ABSTRACT) as *const bool) } + } + + #[inline] + pub fn declare(&self) -> &bool { + unsafe { &*((self.0 as *const u8).add(OFFSET_CLASS_DECLARE) as *const bool) } } #[inline] diff --git a/tasks/coverage/parser_typescript.snap b/tasks/coverage/parser_typescript.snap index c8355a4ea..29bf31296 100644 --- a/tasks/coverage/parser_typescript.snap +++ b/tasks/coverage/parser_typescript.snap @@ -6422,6 +6422,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ export export function f() { } ╰──── + × TS1044: 'export' modifier cannot appear on a module or namespace element. + ╭─[compiler/exportAlreadySeen.ts:6:16] + 5 │ export export module N { + 6 │ export export class C { } + · ────── + 7 │ export export interface I { } + ╰──── + × TS1044: 'export' modifier cannot appear on a module or namespace element. ╭─[compiler/exportAlreadySeen.ts:12:12] 11 │ declare module A { @@ -6430,6 +6438,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 13 │ export export function f() ╰──── + × TS1044: 'export' modifier cannot appear on a module or namespace element. + ╭─[compiler/exportAlreadySeen.ts:16:16] + 15 │ export export module N { + 16 │ export export class C { } + · ────── + 17 │ export export interface I { } + ╰──── + × Modifiers cannot be used here. ╭─[compiler/exportAlreadySeen.ts:3:12] 2 │ export export var x = 1; @@ -6438,14 +6454,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 4 │ ╰──── - × Modifiers cannot be used here. - ╭─[compiler/exportAlreadySeen.ts:6:16] - 5 │ export export module N { - 6 │ export export class C { } - · ────── - 7 │ export export interface I { } - ╰──── - × Modifiers cannot be used here. ╭─[compiler/exportAlreadySeen.ts:7:16] 6 │ export export class C { } @@ -6470,14 +6478,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 14 │ ╰──── - × Modifiers cannot be used here. - ╭─[compiler/exportAlreadySeen.ts:16:16] - 15 │ export export module N { - 16 │ export export class C { } - · ────── - 17 │ export export interface I { } - ╰──── - × Modifiers cannot be used here. ╭─[compiler/exportAlreadySeen.ts:17:16] 16 │ export export class C { } @@ -10668,7 +10668,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 2 │ } ╰──── - × 'async' modifier cannot be used here. + × TS1044: 'async' modifier cannot appear on a module or namespace element. ╭─[conformance/async/es5/asyncClass_es5.ts:1:1] 1 │ async class C { · ───── @@ -10803,7 +10803,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 2 │ } ╰──── - × 'async' modifier cannot be used here. + × TS1044: 'async' modifier cannot appear on a module or namespace element. ╭─[conformance/async/es6/asyncClass_es6.ts:1:1] 1 │ async class C { · ───── @@ -16205,7 +16205,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ let; ╰──── - × Modifiers cannot be used here. + × TS1044: 'public' modifier cannot appear on a module or namespace element. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:4:5] 3 │ module Y { 4 │ public class A { s: string } @@ -16213,7 +16213,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 5 │ ╰──── - × Modifiers cannot be used here. + × TS1044: 'public' modifier cannot appear on a module or namespace element. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:6:5] 5 │ 6 │ public class BB extends A { @@ -16221,7 +16221,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 7 │ id: number; ╰──── - × Modifiers cannot be used here. + × TS1044: 'public' modifier cannot appear on a module or namespace element. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:12:5] 11 │ module Y2 { 12 │ public class AA { s: T } @@ -16229,6 +16229,78 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 13 │ public interface I { id: number } ╰──── + × TS1044: 'public' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:15:5] + 14 │ + 15 │ public class B extends AA implements I { id: number } + · ────── + 16 │ } + ╰──── + + × TS1044: 'private' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:29:5] + 28 │ module YY { + 29 │ private class A { s: string } + · ─────── + 30 │ + ╰──── + + × TS1044: 'private' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:31:5] + 30 │ + 31 │ private class BB extends A { + · ─────── + 32 │ id: number; + ╰──── + + × TS1044: 'private' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:37:5] + 36 │ module YY2 { + 37 │ private class AA { s: T } + · ─────── + 38 │ private interface I { id: number } + ╰──── + + × TS1044: 'private' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:40:5] + 39 │ + 40 │ private class B extends AA implements I { id: number } + · ─────── + 41 │ } + ╰──── + + × TS1044: 'static' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:55:5] + 54 │ module YYY { + 55 │ static class A { s: string } + · ────── + 56 │ + ╰──── + + × TS1044: 'static' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:57:5] + 56 │ + 57 │ static class BB extends A { + · ────── + 58 │ id: number; + ╰──── + + × TS1044: 'static' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:63:5] + 62 │ module YYY2 { + 63 │ static class AA { s: T } + · ────── + 64 │ static interface I { id: number } + ╰──── + + × TS1044: 'static' modifier cannot appear on a module or namespace element. + ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:66:5] + 65 │ + 66 │ static class B extends AA implements I { id: number } + · ────── + 67 │ } + ╰──── + × Modifiers cannot be used here. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:13:5] 12 │ public class AA { s: T } @@ -16237,14 +16309,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 14 │ ╰──── - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:15:5] - 14 │ - 15 │ public class B extends AA implements I { id: number } - · ────── - 16 │ } - ╰──── - × Modifiers cannot be used here. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:19:5] 18 │ module Y3 { @@ -16261,30 +16325,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 26 │ } ╰──── - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:29:5] - 28 │ module YY { - 29 │ private class A { s: string } - · ─────── - 30 │ - ╰──── - - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:31:5] - 30 │ - 31 │ private class BB extends A { - · ─────── - 32 │ id: number; - ╰──── - - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:37:5] - 36 │ module YY2 { - 37 │ private class AA { s: T } - · ─────── - 38 │ private interface I { id: number } - ╰──── - × Modifiers cannot be used here. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:38:5] 37 │ private class AA { s: T } @@ -16293,14 +16333,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 39 │ ╰──── - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:40:5] - 39 │ - 40 │ private class B extends AA implements I { id: number } - · ─────── - 41 │ } - ╰──── - × Modifiers cannot be used here. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:44:5] 43 │ module YY3 { @@ -16317,30 +16349,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 51 │ } ╰──── - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:55:5] - 54 │ module YYY { - 55 │ static class A { s: string } - · ────── - 56 │ - ╰──── - - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:57:5] - 56 │ - 57 │ static class BB extends A { - · ────── - 58 │ id: number; - ╰──── - - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:63:5] - 62 │ module YYY2 { - 63 │ static class AA { s: T } - · ────── - 64 │ static interface I { id: number } - ╰──── - × Modifiers cannot be used here. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:64:5] 63 │ static class AA { s: T } @@ -16349,14 +16357,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 65 │ ╰──── - × Modifiers cannot be used here. - ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:66:5] - 65 │ - 66 │ static class B extends AA implements I { id: number } - · ────── - 67 │ } - ╰──── - × Modifiers cannot be used here. ╭─[conformance/internalModules/moduleBody/invalidModuleWithStatementsOfEveryKind.ts:70:5] 69 │ module YYY3 { @@ -17751,7 +17751,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" 3 │ } ╰──── - × Modifiers cannot be used here. + × TS1044: 'protected' modifier cannot appear on a module or namespace element. ╭─[conformance/parser/ecmascript5/Protected/Protected1.ts:1:1] 1 │ protected class C { · ───────── @@ -17855,7 +17855,7 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts" ╰──── help: Try insert a semicolon here - × Modifiers cannot be used here. + × TS1044: 'export' modifier cannot appear on a module or namespace element. ╭─[conformance/parser/ecmascript5/RegressionTests/parser618973.ts:1:8] 1 │ export export class Foo { · ──────