1use oxc_span::Span;
11
12use crate::ExportName;
13use fallow_types::extract::VisibilityTag;
14
15use super::types::{
16 CachedDynamicImport, CachedDynamicImportPattern, CachedExport, CachedImport, CachedMember,
17 CachedModule, CachedReExport, CachedRequireCall, CachedSuppression, IMPORT_KIND_DEFAULT,
18 IMPORT_KIND_NAMED, IMPORT_KIND_NAMESPACE, IMPORT_KIND_SIDE_EFFECT,
19};
20
21#[must_use]
23pub fn cached_to_module(
24 cached: &CachedModule,
25 file_id: fallow_types::discover::FileId,
26) -> crate::ModuleInfo {
27 use crate::{
28 DynamicImportInfo, ExportInfo, ImportInfo, ImportedName, MemberInfo, ModuleInfo,
29 ReExportInfo, RequireCallInfo,
30 };
31
32 let exports = cached
33 .exports
34 .iter()
35 .map(|e| ExportInfo {
36 name: if e.is_default {
37 ExportName::Default
38 } else {
39 ExportName::Named(e.name.clone())
40 },
41 local_name: e.local_name.clone(),
42 is_type_only: e.is_type_only,
43 visibility: match e.visibility {
44 1 => VisibilityTag::Public,
45 2 => VisibilityTag::Internal,
46 3 => VisibilityTag::Beta,
47 4 => VisibilityTag::Alpha,
48 5 => VisibilityTag::ExpectedUnused,
49 _ => VisibilityTag::None,
50 },
51 span: Span::new(e.span_start, e.span_end),
52 members: e
53 .members
54 .iter()
55 .map(|m| MemberInfo {
56 name: m.name.clone(),
57 kind: m.kind,
58 span: Span::new(m.span_start, m.span_end),
59 has_decorator: m.has_decorator,
60 })
61 .collect(),
62 super_class: e.super_class.clone(),
63 })
64 .collect();
65
66 let imports = cached
67 .imports
68 .iter()
69 .map(|i| ImportInfo {
70 source: i.source.clone(),
71 imported_name: match i.kind {
72 IMPORT_KIND_DEFAULT => ImportedName::Default,
73 IMPORT_KIND_NAMESPACE => ImportedName::Namespace,
74 IMPORT_KIND_SIDE_EFFECT => ImportedName::SideEffect,
75 _ => ImportedName::Named(i.imported_name.clone()),
77 },
78 local_name: i.local_name.clone(),
79 is_type_only: i.is_type_only,
80 span: Span::new(i.span_start, i.span_end),
81 source_span: Span::new(i.source_span_start, i.source_span_end),
82 })
83 .collect();
84
85 let re_exports = cached
86 .re_exports
87 .iter()
88 .map(|r| ReExportInfo {
89 source: r.source.clone(),
90 imported_name: r.imported_name.clone(),
91 exported_name: r.exported_name.clone(),
92 is_type_only: r.is_type_only,
93 span: Span::new(r.span_start, r.span_end),
94 })
95 .collect();
96
97 let dynamic_imports = cached
98 .dynamic_imports
99 .iter()
100 .map(|d| DynamicImportInfo {
101 source: d.source.clone(),
102 span: Span::new(d.span_start, d.span_end),
103 destructured_names: d.destructured_names.clone(),
104 local_name: d.local_name.clone(),
105 })
106 .collect();
107
108 let require_calls = cached
109 .require_calls
110 .iter()
111 .map(|r| RequireCallInfo {
112 source: r.source.clone(),
113 span: Span::new(r.span_start, r.span_end),
114 destructured_names: r.destructured_names.clone(),
115 local_name: r.local_name.clone(),
116 })
117 .collect();
118
119 let dynamic_import_patterns = cached
120 .dynamic_import_patterns
121 .iter()
122 .map(|p| crate::DynamicImportPattern {
123 prefix: p.prefix.clone(),
124 suffix: p.suffix.clone(),
125 span: Span::new(p.span_start, p.span_end),
126 })
127 .collect();
128
129 let suppressions = cached
130 .suppressions
131 .iter()
132 .map(|s| crate::suppress::Suppression {
133 line: s.line,
134 comment_line: s.comment_line,
135 kind: if s.kind == 0 {
136 None
137 } else {
138 crate::suppress::IssueKind::from_discriminant(s.kind)
139 },
140 })
141 .collect();
142
143 ModuleInfo {
144 file_id,
145 exports,
146 imports,
147 re_exports,
148 dynamic_imports,
149 dynamic_import_patterns,
150 require_calls,
151 member_accesses: cached.member_accesses.clone(),
152 whole_object_uses: cached.whole_object_uses.clone(),
153 has_cjs_exports: cached.has_cjs_exports,
154 content_hash: cached.content_hash,
155 suppressions,
156 unused_import_bindings: cached.unused_import_bindings.clone(),
157 line_offsets: cached.line_offsets.clone(),
158 complexity: cached.complexity.clone(),
159 flag_uses: cached.flag_uses.clone(),
160 }
161}
162
163#[must_use]
169pub fn module_to_cached(
170 module: &crate::ModuleInfo,
171 mtime_secs: u64,
172 file_size: u64,
173) -> CachedModule {
174 CachedModule {
175 content_hash: module.content_hash,
176 mtime_secs,
177 file_size,
178 exports: module
179 .exports
180 .iter()
181 .map(|e| CachedExport {
182 name: match &e.name {
183 ExportName::Named(n) => n.clone(),
184 ExportName::Default => String::new(),
185 },
186 is_default: matches!(e.name, ExportName::Default),
187 is_type_only: e.is_type_only,
188 visibility: e.visibility as u8,
189 local_name: e.local_name.clone(),
190 span_start: e.span.start,
191 span_end: e.span.end,
192 members: e
193 .members
194 .iter()
195 .map(|m| CachedMember {
196 name: m.name.clone(),
197 kind: m.kind,
198 span_start: m.span.start,
199 span_end: m.span.end,
200 has_decorator: m.has_decorator,
201 })
202 .collect(),
203 super_class: e.super_class.clone(),
204 })
205 .collect(),
206 imports: module
207 .imports
208 .iter()
209 .map(|i| {
210 let (kind, imported_name) = match &i.imported_name {
211 crate::ImportedName::Named(n) => (IMPORT_KIND_NAMED, n.clone()),
212 crate::ImportedName::Default => (IMPORT_KIND_DEFAULT, String::new()),
213 crate::ImportedName::Namespace => (IMPORT_KIND_NAMESPACE, String::new()),
214 crate::ImportedName::SideEffect => (IMPORT_KIND_SIDE_EFFECT, String::new()),
215 };
216 CachedImport {
217 source: i.source.clone(),
218 imported_name,
219 local_name: i.local_name.clone(),
220 is_type_only: i.is_type_only,
221 kind,
222 span_start: i.span.start,
223 span_end: i.span.end,
224 source_span_start: i.source_span.start,
225 source_span_end: i.source_span.end,
226 }
227 })
228 .collect(),
229 re_exports: module
230 .re_exports
231 .iter()
232 .map(|r| CachedReExport {
233 source: r.source.clone(),
234 imported_name: r.imported_name.clone(),
235 exported_name: r.exported_name.clone(),
236 is_type_only: r.is_type_only,
237 span_start: r.span.start,
238 span_end: r.span.end,
239 })
240 .collect(),
241 dynamic_imports: module
242 .dynamic_imports
243 .iter()
244 .map(|d| CachedDynamicImport {
245 source: d.source.clone(),
246 span_start: d.span.start,
247 span_end: d.span.end,
248 destructured_names: d.destructured_names.clone(),
249 local_name: d.local_name.clone(),
250 })
251 .collect(),
252 require_calls: module
253 .require_calls
254 .iter()
255 .map(|r| CachedRequireCall {
256 source: r.source.clone(),
257 span_start: r.span.start,
258 span_end: r.span.end,
259 destructured_names: r.destructured_names.clone(),
260 local_name: r.local_name.clone(),
261 })
262 .collect(),
263 member_accesses: module.member_accesses.clone(),
264 whole_object_uses: module.whole_object_uses.clone(),
265 dynamic_import_patterns: module
266 .dynamic_import_patterns
267 .iter()
268 .map(|p| CachedDynamicImportPattern {
269 prefix: p.prefix.clone(),
270 suffix: p.suffix.clone(),
271 span_start: p.span.start,
272 span_end: p.span.end,
273 })
274 .collect(),
275 has_cjs_exports: module.has_cjs_exports,
276 unused_import_bindings: module.unused_import_bindings.clone(),
277 suppressions: module
278 .suppressions
279 .iter()
280 .map(|s| CachedSuppression {
281 line: s.line,
282 comment_line: s.comment_line,
283 kind: s
284 .kind
285 .map_or(0, crate::suppress::IssueKind::to_discriminant),
286 })
287 .collect(),
288 line_offsets: module.line_offsets.clone(),
289 complexity: module.complexity.clone(),
290 flag_uses: module.flag_uses.clone(),
291 }
292}