From ce48982c6f6a0f6657008be1ebc1eacc5bda146e Mon Sep 17 00:00:00 2001 From: Dunqing Date: Sat, 13 Jan 2024 19:03:50 +0800 Subject: [PATCH] feat(transformer/typescript): remove export specifier that import_kind is type --- crates/oxc_transformer/src/typescript/mod.rs | 19 +++++++++++++++---- tasks/transform_conformance/babel.snap.md | 6 ++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/crates/oxc_transformer/src/typescript/mod.rs b/crates/oxc_transformer/src/typescript/mod.rs index bf23388a64afc..bb7f210428764 100644 --- a/crates/oxc_transformer/src/typescript/mod.rs +++ b/crates/oxc_transformer/src/typescript/mod.rs @@ -20,7 +20,8 @@ pub struct TypeScript<'a> { ast: Rc>, ctx: TransformerCtx<'a>, verbatim_module_syntax: bool, - + /// type imports names + import_type_name_set: FxHashSet, export_name_set: FxHashSet, } @@ -30,7 +31,13 @@ impl<'a> TypeScript<'a> { ctx: TransformerCtx<'a>, verbatim_module_syntax: bool, ) -> Self { - Self { ast, ctx, verbatim_module_syntax, export_name_set: FxHashSet::default() } + Self { + ast, + ctx, + verbatim_module_syntax, + import_type_name_set: FxHashSet::default(), + export_name_set: FxHashSet::default(), + } } pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) { @@ -101,7 +108,7 @@ impl<'a> TypeScript<'a> { /// * Remove the top level import / export statements that are types /// * Adds `export {}` if all import / export statements are removed, this is used to tell /// downstream tools that this file is in ESM. - pub fn transform_program(&self, program: &mut Program<'a>) { + pub fn transform_program(&mut self, program: &mut Program<'a>) { let mut needs_explicit_esm = false; for stmt in program.body.iter_mut() { @@ -109,13 +116,17 @@ impl<'a> TypeScript<'a> { needs_explicit_esm = true; match &mut **module_decl { ModuleDeclaration::ExportNamedDeclaration(decl) => { - decl.specifiers.retain(|specifier| specifier.export_kind.is_value()); + decl.specifiers.retain(|specifier| { + !(specifier.export_kind.is_type() + || self.import_type_name_set.contains(specifier.exported.name())) + }); } ModuleDeclaration::ImportDeclaration(decl) if decl.import_kind.is_value() => { if let Some(specifiers) = &mut decl.specifiers { specifiers.retain(|specifier| match specifier { ImportDeclarationSpecifier::ImportSpecifier(s) => { if s.import_kind.is_type() { + self.import_type_name_set.insert(s.local.name.clone()); return false; } diff --git a/tasks/transform_conformance/babel.snap.md b/tasks/transform_conformance/babel.snap.md index c7f281a97c0dd..66f8f908d12b1 100644 --- a/tasks/transform_conformance/babel.snap.md +++ b/tasks/transform_conformance/babel.snap.md @@ -1,4 +1,4 @@ -Passed: 304/1179 +Passed: 306/1179 # All Passed: * babel-plugin-transform-numeric-separator @@ -832,7 +832,7 @@ Passed: 304/1179 * general/function-duplicate-name/input.js * general/object/input.js -# babel-plugin-transform-typescript (73/158) +# babel-plugin-transform-typescript (75/158) * class/abstract-class-decorated/input.ts * class/abstract-class-decorated-method/input.ts * class/abstract-class-decorated-parameter/input.ts @@ -872,9 +872,7 @@ Passed: 304/1179 * imports/import=-module-to-cjs/input.ts * imports/only-remove-type-imports/input.ts * imports/parameter-decorators/input.ts -* imports/type-only-export-specifier-1/input.ts * imports/type-only-export-specifier-2/input.ts -* imports/type-only-import-specifier-3/input.ts * imports/type-only-import-specifier-4/input.ts * namespace/ambient-module-nested/input.ts * namespace/ambient-module-nested-exported/input.ts