diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index b6cf7818b092f..905cc1c1ee15e 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -307,16 +307,6 @@ impl<'a> Traverse<'a> for TransformerImpl<'a, '_> { self.x2_es2022.exit_static_block(block, ctx); } - fn enter_ts_module_declaration( - &mut self, - decl: &mut TSModuleDeclaration<'a>, - ctx: &mut TraverseCtx<'a>, - ) { - if let Some(typescript) = self.x0_typescript.as_mut() { - typescript.enter_ts_module_declaration(decl, ctx); - } - } - #[inline] fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { self.common.enter_expression(expr, ctx); diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index ef8313c4fd387..42242c9b9dc7b 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -1,5 +1,3 @@ -use rustc_hash::FxHashSet; - use oxc_allocator::{TakeIn, Vec as ArenaVec}; use oxc_ast::ast::*; use oxc_diagnostics::OxcDiagnostic; @@ -29,7 +27,6 @@ pub struct TypeScriptAnnotations<'a, 'ctx> { has_jsx_fragment: bool, jsx_element_import_name: String, jsx_fragment_import_name: String, - type_identifier_names: FxHashSet>, } impl<'a, 'ctx> TypeScriptAnnotations<'a, 'ctx> { @@ -55,7 +52,6 @@ impl<'a, 'ctx> TypeScriptAnnotations<'a, 'ctx> { has_jsx_fragment: false, jsx_element_import_name, jsx_fragment_import_name, - type_identifier_names: FxHashSet::default(), } } } @@ -79,7 +75,7 @@ impl<'a> Traverse<'a> for TypeScriptAnnotations<'a, '_> { true } else { decl.specifiers - .retain(|specifier| self.can_retain_export_specifier(specifier, ctx)); + .retain(|specifier| Self::can_retain_export_specifier(specifier, ctx)); // Keep the export declaration if there are still specifiers after removing type exports !decl.specifiers.is_empty() } @@ -456,8 +452,6 @@ impl<'a> Traverse<'a> for TypeScriptAnnotations<'a, '_> { // Remove TS specific statements stmts.retain(|stmt| match stmt { Statement::ExpressionStatement(s) => !s.expression.is_typescript_syntax(), - // Any namespaces left after namespace transform are type only, so remove them - Statement::TSModuleDeclaration(_) => false, match_declaration!(Statement) => !stmt.to_declaration().is_typescript_syntax(), // Ignore ModuleDeclaration as it's handled in the program _ => true, @@ -548,17 +542,6 @@ impl<'a> Traverse<'a> for TypeScriptAnnotations<'a, '_> { fn enter_jsx_fragment(&mut self, _elem: &mut JSXFragment<'a>, _ctx: &mut TraverseCtx<'a>) { self.has_jsx_fragment = true; } - - fn enter_ts_module_declaration( - &mut self, - decl: &mut TSModuleDeclaration<'a>, - _ctx: &mut TraverseCtx<'a>, - ) { - // NB: Namespace transform happens in `enter_program` visitor, and replaces retained - // namespaces with functions. This visitor is called after, by which time any remaining - // namespaces need to be deleted. - self.type_identifier_names.insert(decl.id.name()); - } } impl<'a> TypeScriptAnnotations<'a, '_> { @@ -615,14 +598,8 @@ impl<'a> TypeScriptAnnotations<'a, '_> { self.is_jsx_imports(&id.name) } - fn can_retain_export_specifier( - &self, - specifier: &ExportSpecifier<'a>, - ctx: &TraverseCtx<'a>, - ) -> bool { - if specifier.export_kind.is_type() - || self.type_identifier_names.contains(&specifier.exported.name()) - { + fn can_retain_export_specifier(specifier: &ExportSpecifier<'a>, ctx: &TraverseCtx<'a>) -> bool { + if specifier.export_kind.is_type() { return false; } !matches!(&specifier.local, ModuleExportName::IdentifierReference(ident) if Self::is_refers_to_type(ident, ctx)) diff --git a/crates/oxc_transformer/src/typescript/mod.rs b/crates/oxc_transformer/src/typescript/mod.rs index 385ffdd8d46b6..441d2bddb0656 100644 --- a/crates/oxc_transformer/src/typescript/mod.rs +++ b/crates/oxc_transformer/src/typescript/mod.rs @@ -118,14 +118,6 @@ impl<'a> Traverse<'a> for TypeScript<'a, '_> { self.annotations.enter_class_body(body, ctx); } - fn enter_ts_module_declaration( - &mut self, - decl: &mut TSModuleDeclaration<'a>, - ctx: &mut TraverseCtx<'a>, - ) { - self.annotations.enter_ts_module_declaration(decl, ctx); - } - fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { self.annotations.enter_expression(expr, ctx); } diff --git a/crates/oxc_transformer/src/typescript/namespace.rs b/crates/oxc_transformer/src/typescript/namespace.rs index bd83338126e05..98b9bf1515c77 100644 --- a/crates/oxc_transformer/src/typescript/namespace.rs +++ b/crates/oxc_transformer/src/typescript/namespace.rs @@ -1,7 +1,6 @@ use oxc_allocator::{Box as ArenaBox, TakeIn, Vec as ArenaVec}; use oxc_ast::{NONE, ast::*}; use oxc_ecmascript::BoundNames; -use oxc_semantic::Reference; use oxc_span::SPAN; use oxc_syntax::{ operator::{AssignmentOperator, LogicalOperator}, @@ -22,16 +21,11 @@ pub struct TypeScriptNamespace<'a, 'ctx> { // Options allow_namespaces: bool, - only_remove_type_imports: bool, } impl<'a, 'ctx> TypeScriptNamespace<'a, 'ctx> { pub fn new(options: &TypeScriptOptions, ctx: &'ctx TransformCtx<'a>) -> Self { - Self { - ctx, - allow_namespaces: options.allow_namespaces, - only_remove_type_imports: options.only_remove_type_imports, - } + Self { ctx, allow_namespaces: options.allow_namespaces } } } @@ -39,7 +33,6 @@ impl<'a> Traverse<'a> for TypeScriptNamespace<'a, '_> { // `namespace Foo { }` -> `let Foo; (function (_Foo) { })(Foo || (Foo = {}));` fn enter_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) { // namespace declaration is only allowed at the top level - if !has_namespace(program.body.as_slice()) { return; } @@ -59,14 +52,12 @@ impl<'a> Traverse<'a> for TypeScriptNamespace<'a, '_> { self.handle_nested(decl, /* is_export */ false, &mut new_stmts, None, ctx); continue; } - Statement::ExportNamedDeclaration(export_decl) => { - if export_decl.declaration.as_ref().is_none_or(|decl| { - decl.declare() || !matches!(decl, Declaration::TSModuleDeclaration(_)) - }) { - new_stmts.push(Statement::ExportNamedDeclaration(export_decl)); - continue; - } - + Statement::ExportNamedDeclaration(export_decl) + if export_decl.declaration.as_ref().is_some_and(|declaration| { + !declaration.declare() + && matches!(declaration, Declaration::TSModuleDeclaration(_)) + }) => + { let Some(Declaration::TSModuleDeclaration(decl)) = export_decl.unbox().declaration else { @@ -156,7 +147,6 @@ impl<'a> TypeScriptNamespace<'a, '_> { match stmt { Statement::TSModuleDeclaration(decl) => { self.handle_nested(decl, /* is_export */ false, &mut new_stmts, None, ctx); - continue; } Statement::ExportNamedDeclaration(export_decl) => { // NB: `ExportNamedDeclaration` with no declaration (e.g. `export {x}`) is not @@ -219,25 +209,9 @@ impl<'a> TypeScriptNamespace<'a, '_> { _ => {} } } - continue; - } - // Retain when `only_remove_type_imports` is true or there are value references - // The behavior is the same as `TypeScriptModule::transform_ts_import_equals` - Statement::TSImportEqualsDeclaration(decl) - if !self.only_remove_type_imports - && ctx - .scoping() - .get_resolved_references(decl.id.symbol_id()) - .all(Reference::is_type) => - { - continue; } - Statement::TSTypeAliasDeclaration(_) | Statement::TSInterfaceDeclaration(_) => { - continue; - } - _ => {} + _ => new_stmts.push(stmt), } - new_stmts.push(stmt); } if !Self::is_redeclaration_namespace(&ident, ctx) { diff --git a/tasks/coverage/snapshots/semantic_typescript.snap b/tasks/coverage/snapshots/semantic_typescript.snap index 59b559488cc62..74a456a3045fd 100644 --- a/tasks/coverage/snapshots/semantic_typescript.snap +++ b/tasks/coverage/snapshots/semantic_typescript.snap @@ -2095,9 +2095,6 @@ rebuilt : ScopeId(0): ["M2"] Scope children mismatch: after transform: ScopeId(0): [ScopeId(1), ScopeId(4)] rebuilt : ScopeId(0): [ScopeId(1)] -Bindings mismatch: -after transform: ScopeId(4): ["C", "T", "_M"] -rebuilt : ScopeId(1): ["C", "_M"] Scope flags mismatch: after transform: ScopeId(4): ScopeFlags(StrictMode | Function) rebuilt : ScopeId(1): ScopeFlags(Function) @@ -17964,9 +17961,6 @@ rebuilt : ScopeId(0): ["B"] Scope children mismatch: after transform: ScopeId(0): [ScopeId(1), ScopeId(3)] rebuilt : ScopeId(0): [ScopeId(1)] -Bindings mismatch: -after transform: ScopeId(3): ["A", "Y", "_B"] -rebuilt : ScopeId(1): ["A", "_B"] Scope flags mismatch: after transform: ScopeId(3): ScopeFlags(StrictMode | Function) rebuilt : ScopeId(1): ScopeFlags(Function) @@ -20060,9 +20054,6 @@ rebuilt : ScopeId(1): ScopeFlags(Function) Scope children mismatch: after transform: ScopeId(1): [ScopeId(2), ScopeId(3)] rebuilt : ScopeId(1): [ScopeId(2)] -Bindings mismatch: -after transform: ScopeId(4): ["Bug", "_editor", "i", "modes"] -rebuilt : ScopeId(3): ["Bug", "_editor", "i"] Scope flags mismatch: after transform: ScopeId(4): ScopeFlags(StrictMode | Function) rebuilt : ScopeId(3): ScopeFlags(Function) @@ -20078,9 +20069,6 @@ rebuilt : ScopeId(14): ScopeFlags(Function) Scope children mismatch: after transform: ScopeId(15): [ScopeId(16), ScopeId(17)] rebuilt : ScopeId(14): [ScopeId(15)] -Bindings mismatch: -after transform: ScopeId(18): ["A1Alias1", "_B", "c", "i"] -rebuilt : ScopeId(16): ["_B", "c", "i"] Scope flags mismatch: after transform: ScopeId(18): ScopeFlags(StrictMode | Function) rebuilt : ScopeId(16): ScopeFlags(Function) @@ -20926,9 +20914,6 @@ rebuilt : ScopeId(2): ScopeFlags(Function) Scope flags mismatch: after transform: ScopeId(4): ScopeFlags(StrictMode | Function) rebuilt : ScopeId(4): ScopeFlags(Function) -Bindings mismatch: -after transform: ScopeId(5): ["M", "_M2", "bar"] -rebuilt : ScopeId(5): ["_M2", "bar"] Scope flags mismatch: after transform: ScopeId(5): ScopeFlags(StrictMode | Function) rebuilt : ScopeId(5): ScopeFlags(Function) diff --git a/tasks/transform_conformance/snapshots/oxc.snap.md b/tasks/transform_conformance/snapshots/oxc.snap.md index 6dc8d32308c5f..5e72fa1ab6101 100644 --- a/tasks/transform_conformance/snapshots/oxc.snap.md +++ b/tasks/transform_conformance/snapshots/oxc.snap.md @@ -209,9 +209,6 @@ after transform: SymbolId(1): Span { start: 31, end: 33 } rebuilt : SymbolId(1): Span { start: 0, end: 0 } * namespace/import-=/input.ts -Bindings mismatch: -after transform: ScopeId(1): ["V", "X", "_N"] -rebuilt : ScopeId(1): ["V", "_N"] Scope flags mismatch: after transform: ScopeId(1): ScopeFlags(StrictMode | Function) rebuilt : ScopeId(1): ScopeFlags(Function)