1use rustc_hash::FxHashMap;
2
3use oxc::syntax::module_record::{self, ModuleRecord};
4
5use crate::types::{
6 DynamicImport, EcmaScriptModule, ExportExportName, ExportExportNameKind, ExportImportName,
7 ExportImportNameKind, ExportLocalName, ExportLocalNameKind, ImportName, ImportNameKind, Span,
8 StaticExport, StaticExportEntry, StaticImport, StaticImportEntry, ValueSpan,
9};
10
11impl From<&ModuleRecord<'_>> for EcmaScriptModule {
12 fn from(record: &ModuleRecord<'_>) -> Self {
13 let mut static_imports = record
14 .requested_modules
15 .iter()
16 .flat_map(|(name, requested_modules)| {
17 requested_modules.iter().filter(|m| m.is_import).map(|m| {
18 let entries = record
19 .import_entries
20 .iter()
21 .filter(|e| e.statement_span == m.statement_span)
22 .map(StaticImportEntry::from)
23 .collect::<Vec<_>>();
24 {
25 StaticImport {
26 start: m.statement_span.start,
27 end: m.statement_span.end,
28 module_request: ValueSpan {
29 value: name.to_string(),
30 start: m.span.start,
31 end: m.span.end,
32 },
33 entries,
34 }
35 }
36 })
37 })
38 .collect::<Vec<_>>();
39 static_imports.sort_unstable_by_key(|e| e.start);
40
41 let mut static_exports = record
42 .local_export_entries
43 .iter()
44 .chain(record.indirect_export_entries.iter())
45 .chain(record.star_export_entries.iter())
46 .map(|e| (e.statement_span, StaticExportEntry::from(e)))
47 .collect::<Vec<_>>()
48 .into_iter()
49 .fold(FxHashMap::<_, Vec<StaticExportEntry>>::default(), |mut acc, (span, e)| {
50 acc.entry(span).or_default().push(e);
51 acc
52 })
53 .into_iter()
54 .map(|(span, entries)| StaticExport { start: span.start, end: span.end, entries })
55 .collect::<Vec<_>>();
56 static_exports.sort_unstable_by_key(|e| e.start);
57
58 let dynamic_imports = record
59 .dynamic_imports
60 .iter()
61 .map(|i| DynamicImport {
62 start: i.span.start,
63 end: i.span.end,
64 module_request: Span::from(&i.module_request),
65 })
66 .collect::<Vec<_>>();
67
68 let import_metas = record.import_metas.iter().map(Span::from).collect();
69
70 Self {
71 has_module_syntax: record.has_module_syntax,
72 static_imports,
73 static_exports,
74 dynamic_imports,
75 import_metas,
76 }
77 }
78}
79
80impl From<&oxc::span::Span> for Span {
81 fn from(span: &oxc::span::Span) -> Self {
82 Self { start: span.start, end: span.end }
83 }
84}
85
86impl From<&module_record::ExportEntry<'_>> for StaticExportEntry {
87 fn from(e: &module_record::ExportEntry) -> Self {
88 Self {
89 start: e.span.start,
90 end: e.span.end,
91 module_request: e.module_request.as_ref().map(ValueSpan::from),
92 import_name: ExportImportName::from(&e.import_name),
93 export_name: ExportExportName::from(&e.export_name),
94 local_name: ExportLocalName::from(&e.local_name),
95 is_type: e.is_type,
96 }
97 }
98}
99
100impl From<&module_record::ImportEntry<'_>> for StaticImportEntry {
101 fn from(e: &module_record::ImportEntry<'_>) -> Self {
102 Self {
103 import_name: ImportName::from(&e.import_name),
104 local_name: ValueSpan::from(&e.local_name),
105 is_type: e.is_type,
106 }
107 }
108}
109
110impl From<&module_record::ImportImportName<'_>> for ImportName {
111 fn from(e: &module_record::ImportImportName<'_>) -> Self {
112 let (kind, name, start, end) = match e {
113 module_record::ImportImportName::Name(name_span) => (
114 ImportNameKind::Name,
115 Some(name_span.name.to_string()),
116 Some(name_span.span.start),
117 Some(name_span.span.end),
118 ),
119 module_record::ImportImportName::NamespaceObject => {
120 (ImportNameKind::NamespaceObject, None, None, None)
121 }
122 module_record::ImportImportName::Default(span) => {
123 (ImportNameKind::Default, None, Some(span.start), Some(span.end))
124 }
125 };
126 Self { kind, name, start, end }
127 }
128}
129
130impl From<&module_record::NameSpan<'_>> for ValueSpan {
131 fn from(name_span: &module_record::NameSpan) -> Self {
132 Self {
133 value: name_span.name.to_string(),
134 start: name_span.span.start,
135 end: name_span.span.end,
136 }
137 }
138}
139
140impl From<&module_record::ExportImportName<'_>> for ExportImportName {
141 fn from(e: &module_record::ExportImportName<'_>) -> Self {
142 let (kind, name, start, end) = match e {
143 module_record::ExportImportName::Name(name_span) => (
144 ExportImportNameKind::Name,
145 Some(name_span.name.to_string()),
146 Some(name_span.span.start),
147 Some(name_span.span.end),
148 ),
149 module_record::ExportImportName::All => (ExportImportNameKind::All, None, None, None),
150 module_record::ExportImportName::AllButDefault => {
151 (ExportImportNameKind::AllButDefault, None, None, None)
152 }
153 module_record::ExportImportName::Null => (ExportImportNameKind::None, None, None, None),
154 };
155 Self { kind, name, start, end }
156 }
157}
158
159impl From<&module_record::ExportExportName<'_>> for ExportExportName {
160 fn from(e: &module_record::ExportExportName<'_>) -> Self {
161 let (kind, name, start, end) = match e {
162 module_record::ExportExportName::Name(name_span) => (
163 ExportExportNameKind::Name,
164 Some(name_span.name.to_string()),
165 Some(name_span.span.start),
166 Some(name_span.span.end),
167 ),
168 module_record::ExportExportName::Default(span) => {
169 (ExportExportNameKind::Default, None, Some(span.start), Some(span.end))
170 }
171 module_record::ExportExportName::Null => (ExportExportNameKind::None, None, None, None),
172 };
173 Self { kind, name, start, end }
174 }
175}
176
177impl From<&module_record::ExportLocalName<'_>> for ExportLocalName {
178 fn from(e: &module_record::ExportLocalName<'_>) -> Self {
179 let (kind, name, start, end) = match e {
180 module_record::ExportLocalName::Name(name_span) => (
181 ExportLocalNameKind::Name,
182 Some(name_span.name.to_string()),
183 Some(name_span.span.start),
184 Some(name_span.span.end),
185 ),
186 module_record::ExportLocalName::Default(name_span) => (
187 ExportLocalNameKind::Default,
188 Some(name_span.name.to_string()),
189 Some(name_span.span.start),
190 Some(name_span.span.end),
191 ),
192 module_record::ExportLocalName::Null => (ExportLocalNameKind::None, None, None, None),
193 };
194 Self { kind, name, start, end }
195 }
196}