mod propagate;
#[cfg(test)]
mod tests;
use rustc_hash::FxHashSet;
use fallow_types::discover::FileId;
use super::ModuleGraph;
use propagate::{propagate_named_re_export, propagate_star_re_export};
impl ModuleGraph {
pub(super) fn resolve_re_export_chains(&mut self) {
let re_export_info: Vec<(FileId, FileId, String, String)> = self
.modules
.iter()
.flat_map(|m| {
m.re_exports.iter().map(move |re| {
(
m.file_id,
re.source_file,
re.imported_name.clone(),
re.exported_name.clone(),
)
})
})
.collect();
if re_export_info.is_empty() {
return;
}
let mut changed = true;
let max_iterations = 20; let mut iteration = 0;
let mut existing_refs: FxHashSet<FileId> = FxHashSet::default();
while changed && iteration < max_iterations {
changed = false;
iteration += 1;
for &(barrel_id, source_id, ref imported_name, ref exported_name) in &re_export_info {
let barrel_idx = barrel_id.0 as usize;
let source_idx = source_id.0 as usize;
if barrel_idx >= self.modules.len() || source_idx >= self.modules.len() {
continue;
}
if exported_name == "*" {
changed |= propagate_star_re_export(
&mut self.modules,
&self.edges,
barrel_id,
barrel_idx,
source_idx,
);
} else {
changed |= propagate_named_re_export(
&mut self.modules,
barrel_id,
barrel_idx,
source_idx,
imported_name,
exported_name,
&mut existing_refs,
);
}
}
}
if iteration >= max_iterations {
tracing::warn!(
iterations = max_iterations,
"Re-export chain resolution hit iteration limit, some chains may be incomplete"
);
}
}
}