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
107
108
109
110
111
112
113
114
115
116
117
118
119
use swc_atoms::Atom;
use swc_ecma_ast::*;
use swc_ecma_utils::private_ident;
use crate::CompilerImpl;
impl<'a> CompilerImpl<'a> {
pub(crate) fn transform_export_namespace_from(&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_namespace()))
})
.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,
with,
})) if specifiers.iter().any(|s| s.is_namespace()) => {
let mut origin_specifiers = Vec::new();
let mut import_specifiers = Vec::new();
let mut export_specifiers = Vec::new();
for s in specifiers.into_iter() {
match s {
ExportSpecifier::Namespace(ExportNamespaceSpecifier { span, name }) => {
let local_bridge =
private_ident!(format!("_{}", normalize_name(&name)));
import_specifiers.push(ImportSpecifier::Namespace(
ImportStarAsSpecifier {
span,
local: local_bridge.clone(),
},
));
export_specifiers.push(ExportSpecifier::Named(
ExportNamedSpecifier {
span,
orig: local_bridge.into(),
exported: Some(name),
is_type_only: false,
},
))
}
ExportSpecifier::Default(..) | ExportSpecifier::Named(..) => {
origin_specifiers.push(s);
}
}
}
stmts.push(
ImportDecl {
span,
specifiers: import_specifiers,
src: src.clone(),
type_only: false,
with: with.clone(),
phase: Default::default(),
}
.into(),
);
stmts.push(
NamedExport {
span,
specifiers: export_specifiers,
src: None,
type_only: false,
with: None,
}
.into(),
);
if !origin_specifiers.is_empty() {
stmts.push(
NamedExport {
span,
specifiers: origin_specifiers,
src: Some(src),
type_only: false,
with,
}
.into(),
);
}
}
_ => {
stmts.push(item);
}
}
}
*items = stmts;
}
}
fn normalize_name(module_export_name: &ModuleExportName) -> &Atom {
match module_export_name {
ModuleExportName::Ident(Ident { sym: name, .. })
| ModuleExportName::Str(Str { value: name, .. }) => name,
}
}