-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
07a688f
commit 1bcc8eb
Showing
4 changed files
with
345 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,4 +9,4 @@ pub mod strip; | |
mod strip_import; | ||
mod strip_type; | ||
mod transform; | ||
mod typescript; | ||
pub mod typescript; |
290 changes: 287 additions & 3 deletions
290
crates/swc_ecma_transforms_typescript/src/strip_type.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,291 @@ | ||
use swc_ecma_visit::VisitMut; | ||
use swc_common::{collections::AHashSet, util::take::Take}; | ||
use swc_ecma_ast::*; | ||
use swc_ecma_visit::{VisitMut, VisitMutWith}; | ||
|
||
/// This Module will strip all types/generics/interface/declares | ||
/// and type import/export | ||
pub(crate) struct StripType; | ||
#[derive(Default)] | ||
pub(crate) struct StripType { | ||
type_id: AHashSet<Id>, | ||
} | ||
|
||
impl VisitMut for StripType {} | ||
impl VisitMut for StripType { | ||
fn visit_mut_accessibility(&mut self, _: &mut Accessibility) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_true_plus_minus(&mut self, _: &mut TruePlusMinus) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_array_type(&mut self, _: &mut TsArrayType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_call_signature_decl(&mut self, _: &mut TsCallSignatureDecl) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_conditional_type(&mut self, _: &mut TsConditionalType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_construct_signature_decl(&mut self, _: &mut TsConstructSignatureDecl) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_constructor_type(&mut self, _: &mut TsConstructorType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_entity_name(&mut self, _: &mut TsEntityName) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_external_module_ref(&mut self, _: &mut TsExternalModuleRef) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_fn_or_constructor_type(&mut self, _: &mut TsFnOrConstructorType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_fn_param(&mut self, _: &mut TsFnParam) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_fn_type(&mut self, _: &mut TsFnType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_import_type(&mut self, _: &mut TsImportType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_index_signature(&mut self, _: &mut TsIndexSignature) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_indexed_access_type(&mut self, _: &mut TsIndexedAccessType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_infer_type(&mut self, _: &mut TsInferType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_interface_body(&mut self, _: &mut TsInterfaceBody) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_interface_decl(&mut self, _: &mut TsInterfaceDecl) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_intersection_type(&mut self, _: &mut TsIntersectionType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_keyword_type(&mut self, _: &mut TsKeywordType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_keyword_type_kind(&mut self, _: &mut TsKeywordTypeKind) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_mapped_type(&mut self, _: &mut TsMappedType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_method_signature(&mut self, _: &mut TsMethodSignature) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_module_ref(&mut self, _: &mut TsModuleRef) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_optional_type(&mut self, _: &mut TsOptionalType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_parenthesized_type(&mut self, _: &mut TsParenthesizedType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_property_signature(&mut self, _: &mut TsPropertySignature) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_qualified_name(&mut self, _: &mut TsQualifiedName) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_rest_type(&mut self, _: &mut TsRestType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_this_type(&mut self, _: &mut TsThisType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_this_type_or_ident(&mut self, _: &mut TsThisTypeOrIdent) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_tuple_type(&mut self, _: &mut TsTupleType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type(&mut self, _: &mut TsType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_alias_decl(&mut self, _: &mut TsTypeAliasDecl) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_ann(&mut self, _: &mut TsTypeAnn) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_element(&mut self, _: &mut TsTypeElement) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_lit(&mut self, _: &mut TsTypeLit) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_operator(&mut self, _: &mut TsTypeOperator) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_operator_op(&mut self, _: &mut TsTypeOperatorOp) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_param(&mut self, _: &mut TsTypeParam) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_param_decl(&mut self, _: &mut TsTypeParamDecl) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_param_instantiation(&mut self, _: &mut TsTypeParamInstantiation) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_predicate(&mut self, _: &mut TsTypePredicate) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_query(&mut self, _: &mut TsTypeQuery) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_query_expr(&mut self, _: &mut TsTypeQueryExpr) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_type_ref(&mut self, _: &mut TsTypeRef) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_union_or_intersection_type(&mut self, _: &mut TsUnionOrIntersectionType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_ts_union_type(&mut self, _: &mut TsUnionType) { | ||
unreachable!() | ||
} | ||
|
||
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) { | ||
n.retain(|module_item| match module_item { | ||
ModuleItem::ModuleDecl(ModuleDecl::Import(import_decl)) => !import_decl.type_only, | ||
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(export_decl)) => { | ||
match &export_decl.decl { | ||
Decl::Class(class) => !class.declare, | ||
Decl::Fn(r#fn) => !r#fn.declare, | ||
Decl::Var(var) => !var.declare, | ||
Decl::TsInterface(..) => false, | ||
Decl::TsTypeAlias(..) => false, | ||
Decl::TsEnum(ts_enum) => !ts_enum.declare, | ||
Decl::TsModule(ts_module) => !ts_module.declare, | ||
} | ||
} | ||
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(export_named)) => { | ||
!export_named.type_only | ||
} | ||
ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(export_default_decl)) => { | ||
!export_default_decl.decl.is_ts_interface_decl() | ||
} | ||
ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultExpr(..)) => true, | ||
ModuleItem::ModuleDecl(ModuleDecl::ExportAll(export_all)) => !export_all.type_only, | ||
ModuleItem::ModuleDecl(ModuleDecl::TsImportEquals(ts_import_equals)) => { | ||
!ts_import_equals.is_type_only | ||
} | ||
ModuleItem::ModuleDecl(ModuleDecl::TsExportAssignment(..)) => true, | ||
ModuleItem::ModuleDecl(ModuleDecl::TsNamespaceExport(..)) => { | ||
// https://www.typescriptlang.org/docs/handbook/modules.html#umd-modules | ||
// `TsNamespaceExport` is only used in UMD dts | ||
false | ||
} | ||
ModuleItem::Stmt(..) => true, | ||
}); | ||
|
||
n.visit_mut_children_with(self); | ||
|
||
n.retain(|module_item| !matches!(module_item, ModuleItem::Stmt(Stmt::Empty(empty)) if empty.span.is_dummy())) | ||
} | ||
|
||
fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) { | ||
n.visit_mut_children_with(self); | ||
|
||
n.retain(|stmt| !matches!(stmt, Stmt::Empty(empty) if empty.span.is_dummy())); | ||
} | ||
|
||
fn visit_mut_stmt(&mut self, n: &mut Stmt) { | ||
let retain = match n { | ||
Stmt::Block(..) | ||
| Stmt::Empty(..) | ||
| Stmt::Debugger(..) | ||
| Stmt::With(..) | ||
| Stmt::Return(..) | ||
| Stmt::Labeled(..) | ||
| Stmt::Break(..) | ||
| Stmt::Continue(..) | ||
| Stmt::If(..) | ||
| Stmt::Switch(..) | ||
| Stmt::Throw(..) | ||
| Stmt::Try(..) | ||
| Stmt::While(..) | ||
| Stmt::DoWhile(..) | ||
| Stmt::For(..) | ||
| Stmt::ForIn(..) | ||
| Stmt::ForOf(..) | ||
| Stmt::Expr(..) => true, | ||
Stmt::Decl(decl) => match decl { | ||
Decl::Class(class) => !class.declare, | ||
Decl::Fn(r#fn) => !r#fn.declare, | ||
Decl::Var(var) => !var.declare, | ||
Decl::TsInterface(ts_interface) => { | ||
self.type_id.insert(ts_interface.id.to_id()); | ||
false | ||
} | ||
Decl::TsTypeAlias(ts_type_alias) => { | ||
self.type_id.insert(ts_type_alias.id.to_id()); | ||
false | ||
} | ||
Decl::TsEnum(ts_enum) => !ts_enum.declare, | ||
Decl::TsModule(ts_module) => !ts_module.declare, | ||
}, | ||
}; | ||
|
||
if !retain { | ||
n.take(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use std::path::PathBuf; | ||
|
||
use swc_common::{chain, pass::Optional, Mark}; | ||
use swc_ecma_parser::{Syntax, TsConfig}; | ||
use swc_ecma_transforms_base::resolver; | ||
use swc_ecma_transforms_proposal::decorators; | ||
use swc_ecma_transforms_testing::test_fixture; | ||
use swc_ecma_transforms_typescript::typescript; | ||
use swc_ecma_visit::Fold; | ||
|
||
fn tr() -> impl Fold { | ||
tr_config(None, None) | ||
} | ||
|
||
fn tr_config( | ||
config: Option<typescript::Config>, | ||
decorators_config: Option<decorators::Config>, | ||
) -> impl Fold { | ||
let unresolved_mark = Mark::new(); | ||
let top_level_mark = Mark::new(); | ||
let has_decorators = decorators_config.is_some(); | ||
let config = config.unwrap_or_else(|| typescript::Config { | ||
no_empty_export: true, | ||
..Default::default() | ||
}); | ||
|
||
chain!( | ||
Optional::new( | ||
decorators(decorators_config.unwrap_or_default()), | ||
has_decorators, | ||
), | ||
resolver(unresolved_mark, top_level_mark, true), | ||
typescript::typescript(config), | ||
) | ||
} | ||
|
||
#[testing::fixture("tests/fixture/**/input.ts")] | ||
#[testing::fixture("tests/fixture/**/input.tsx")] | ||
fn typescript_fixture_new(input: PathBuf) { | ||
let output = input.with_file_name("output.js"); | ||
test_fixture( | ||
Syntax::Typescript(TsConfig { | ||
tsx: input.to_string_lossy().ends_with(".tsx"), | ||
..Default::default() | ||
}), | ||
&|_t| tr(), | ||
&input, | ||
&output, | ||
Default::default(), | ||
); | ||
} |