feat(linter): resolve ESM star exports (#2682)

This commit is contained in:
Boshen 2024-03-11 21:43:11 +08:00 committed by GitHub
parent 8a73d18fcf
commit 366a87975d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 54 additions and 9 deletions

View file

@ -289,17 +289,50 @@ impl Runtime {
.for_each_with(tx_error, |tx_error, (specifier, resolution)| {
let path = resolution.path();
self.process_path(path, tx_error);
if let Some(target_module_record_ref) = self.module_map.get(path) {
if let ModuleState::Resolved(target_module_record) =
target_module_record_ref.value()
{
module_record
.loaded_modules
.insert(specifier.clone(), Arc::clone(target_module_record));
}
}
let Some(target_module_record_ref) = self.module_map.get(path) else { return };
let ModuleState::Resolved(target_module_record) =
target_module_record_ref.value()
else {
return;
};
// Append target_module to loaded_modules
module_record
.loaded_modules
.insert(specifier.clone(), Arc::clone(target_module_record));
});
// The thread is blocked here until all dependent modules are resolved.
// Resolve and append `star_export_bindings`
for export_entry in &module_record.star_export_entries {
let Some(remote_module_record_ref) =
export_entry.module_request.as_ref().and_then(|module_request| {
module_record.loaded_modules.get(module_request.name())
})
else {
continue;
};
let remote_module_record = remote_module_record_ref.value();
// Append both remote `bindings` and `exported_bindings_from_star_export`
let remote_exported_bindings_from_star_export = remote_module_record
.exported_bindings_from_star_export
.iter()
.flat_map(|r| r.value().clone());
let remote_bindings = remote_module_record
.exported_bindings
.keys()
.cloned()
.chain(remote_exported_bindings_from_star_export)
.collect::<Vec<_>>();
module_record
.exported_bindings_from_star_export
.entry(remote_module_record.resolved_absolute_path.clone())
.or_default()
.value_mut()
.extend(remote_bindings);
}
// Stop if the current module is not marked for lint.
if !self.paths.contains(path) {
return vec![];

View file

@ -65,10 +65,21 @@ pub struct ModuleRecord {
/// not including export * as namespace declarations.
pub star_export_entries: Vec<ExportEntry>,
/// Local exported bindings
pub exported_bindings: FxHashMap<CompactStr, Span>,
/// Local duplicated exported bindings, for diagnostics
pub exported_bindings_duplicated: Vec<NameSpan>,
/// Reexported bindings from `export * from 'specifier'`
/// Keyed by resolved path
pub exported_bindings_from_star_export: DashMap<PathBuf, Vec<CompactStr>>,
/// `export default name`
/// ^^^^^^^ span
pub export_default: Option<Span>,
/// Duplicated span of `export default` for diagnostics
pub export_default_duplicated: Vec<Span>,
}
@ -99,6 +110,7 @@ impl fmt::Debug for ModuleRecord {
.field("star_export_entries", &self.star_export_entries)
.field("exported_bindings", &self.exported_bindings)
.field("exported_bindings_duplicated", &self.exported_bindings_duplicated)
.field("exported_bindings_from_star_export", &self.exported_bindings_from_star_export)
.field("export_default", &self.export_default)
.field("export_default_duplicated", &self.export_default_duplicated)
.finish()