use rustc_hash::FxHashMap; use oxc::syntax::module_record::{self, ModuleRecord}; use crate::types::{ EcmaScriptModule, ExportExportName, ExportExportNameKind, ExportImportName, ExportImportNameKind, ExportLocalName, ExportLocalNameKind, ImportName, ImportNameKind, Span, StaticExport, StaticExportEntry, StaticImport, StaticImportEntry, ValueSpan, }; impl From<&ModuleRecord<'_>> for EcmaScriptModule { fn from(record: &ModuleRecord<'_>) -> Self { let mut static_imports = record .requested_modules .iter() .flat_map(|(name, requested_modules)| { requested_modules.iter().filter(|m| m.is_import).map(|m| { let entries = record .import_entries .iter() .filter(|e| e.statement_span == m.statement_span) .map(StaticImportEntry::from) .collect::>(); { StaticImport { start: m.statement_span.start, end: m.statement_span.end, module_request: ValueSpan { value: name.to_string(), start: m.span.start, end: m.span.end, }, entries, } } }) }) .collect::>(); static_imports.sort_unstable_by_key(|e| e.start); let mut static_exports = record .local_export_entries .iter() .chain(record.indirect_export_entries.iter()) .chain(record.star_export_entries.iter()) .map(|e| (e.statement_span, StaticExportEntry::from(e))) .collect::>() .into_iter() .fold(FxHashMap::<_, Vec>::default(), |mut acc, (span, e)| { acc.entry(span).or_default().push(e); acc }) .into_iter() .map(|(span, entries)| StaticExport { start: span.start, end: span.end, entries }) .collect::>(); static_exports.sort_unstable_by_key(|e| e.start); let import_metas = record.import_metas.iter().map(Span::from).collect(); Self { has_module_syntax: record.has_module_syntax, static_imports, static_exports, import_metas, } } } impl From<&oxc::span::Span> for Span { fn from(span: &oxc::span::Span) -> Self { Self { start: span.start, end: span.end } } } impl From<&module_record::ExportEntry<'_>> for StaticExportEntry { fn from(e: &module_record::ExportEntry) -> Self { Self { start: e.span.start, end: e.span.end, module_request: e.module_request.as_ref().map(ValueSpan::from), import_name: ExportImportName::from(&e.import_name), export_name: ExportExportName::from(&e.export_name), local_name: ExportLocalName::from(&e.local_name), } } } impl From<&module_record::ImportEntry<'_>> for StaticImportEntry { fn from(e: &module_record::ImportEntry<'_>) -> Self { Self { import_name: ImportName::from(&e.import_name), local_name: ValueSpan::from(&e.local_name), is_type: e.is_type, } } } impl From<&module_record::ImportImportName<'_>> for ImportName { fn from(e: &module_record::ImportImportName<'_>) -> Self { let (kind, name, start, end) = match e { module_record::ImportImportName::Name(name_span) => ( ImportNameKind::Name, Some(name_span.name.to_string()), Some(name_span.span.start), Some(name_span.span.end), ), module_record::ImportImportName::NamespaceObject => { (ImportNameKind::NamespaceObject, None, None, None) } module_record::ImportImportName::Default(span) => { (ImportNameKind::Default, None, Some(span.start), Some(span.end)) } }; Self { kind, name, start, end } } } impl From<&module_record::NameSpan<'_>> for ValueSpan { fn from(name_span: &module_record::NameSpan) -> Self { Self { value: name_span.name.to_string(), start: name_span.span.start, end: name_span.span.end, } } } impl From<&module_record::ExportImportName<'_>> for ExportImportName { fn from(e: &module_record::ExportImportName<'_>) -> Self { let (kind, name, start, end) = match e { module_record::ExportImportName::Name(name_span) => ( ExportImportNameKind::Name, Some(name_span.name.to_string()), Some(name_span.span.start), Some(name_span.span.end), ), module_record::ExportImportName::All => (ExportImportNameKind::All, None, None, None), module_record::ExportImportName::AllButDefault => { (ExportImportNameKind::AllButDefault, None, None, None) } module_record::ExportImportName::Null => (ExportImportNameKind::None, None, None, None), }; Self { kind, name, start, end } } } impl From<&module_record::ExportExportName<'_>> for ExportExportName { fn from(e: &module_record::ExportExportName<'_>) -> Self { let (kind, name, start, end) = match e { module_record::ExportExportName::Name(name_span) => ( ExportExportNameKind::Name, Some(name_span.name.to_string()), Some(name_span.span.start), Some(name_span.span.end), ), module_record::ExportExportName::Default(span) => { (ExportExportNameKind::Default, None, Some(span.start), Some(span.end)) } module_record::ExportExportName::Null => (ExportExportNameKind::None, None, None, None), }; Self { kind, name, start, end } } } impl From<&module_record::ExportLocalName<'_>> for ExportLocalName { fn from(e: &module_record::ExportLocalName<'_>) -> Self { let (kind, name, start, end) = match e { module_record::ExportLocalName::Name(name_span) => ( ExportLocalNameKind::Name, Some(name_span.name.to_string()), Some(name_span.span.start), Some(name_span.span.end), ), module_record::ExportLocalName::Default(name_span) => ( ExportLocalNameKind::Default, Some(name_span.name.to_string()), Some(name_span.span.start), Some(name_span.span.end), ), module_record::ExportLocalName::Null => (ExportLocalNameKind::None, None, None, None), }; Self { kind, name, start, end } } }