1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use swc_common::DUMMY_SP;
use swc_ecma_ast::*;
use swc_ecma_utils::quote_ident;
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut};
pub fn export_default_from() -> impl Fold + VisitMut {
as_folder(ExportDefaultFrom)
}
struct ExportDefaultFrom;
impl VisitMut for ExportDefaultFrom {
noop_visit_mut_type!();
fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
let count = items
.iter()
.filter(|m| {
matches!(m, ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
specifiers,
src: Some(..),
type_only: false,
..
})) if specifiers.iter().any(|s| s.is_default()))
})
.count();
if count == 0 {
return;
}
let mut stmts = Vec::<ModuleItem>::with_capacity(items.len() + count);
for item in items.drain(..) {
match item {
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
span,
specifiers,
src: Some(src),
type_only: false,
asserts,
})) if specifiers.iter().any(|s| s.is_default()) => {
let mut origin_specifiers = vec![];
let mut export_specifiers = vec![];
let mut has_namespace = false;
for s in specifiers.into_iter() {
match s {
ExportSpecifier::Default(ExportDefaultSpecifier { exported }) => {
export_specifiers.push(ExportSpecifier::Named(
ExportNamedSpecifier {
span: DUMMY_SP,
orig: quote_ident!(exported.span, "default").into(),
exported: Some(exported.into()),
is_type_only: false,
},
));
}
ExportSpecifier::Namespace(..) => {
has_namespace = true;
origin_specifiers.push(s);
}
ExportSpecifier::Named(..) => {
if has_namespace {
origin_specifiers.push(s);
} else {
export_specifiers.push(s);
}
}
}
}
stmts.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport {
span,
specifiers: export_specifiers,
src: Some(src.clone()),
type_only: false,
asserts: None,
},
)));
if !origin_specifiers.is_empty() {
stmts.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport {
span,
specifiers: origin_specifiers,
src: Some(src),
type_only: false,
asserts,
},
)));
}
}
_ => {
stmts.push(item);
}
}
}
*items = stmts;
}
}