use std::{collections::BTreeSet, path::PathBuf};
use gimli::Reader as _;
use crate::{
die::{
cu::is_rust_cu, file_entry_to_path, navigation::get_roots, utils::pretty_print_die_entry,
},
DebugFile, DwarfDb, SourceFile,
};
#[salsa::tracked(returns(ref))]
pub fn index_debug_file_sources<'db>(
db: &'db dyn DwarfDb,
debug_file: DebugFile,
) -> (BTreeSet<PathBuf>, BTreeSet<SourceFile<'db>>) {
let mut compile_dirs = BTreeSet::new();
let mut sources = BTreeSet::new();
let roots = get_roots(db, debug_file);
for (_unit_offset, unit_ref) in &roots {
let mut entries = unit_ref.entries();
let Some((_, root)) = entries.next_dfs().ok().flatten() else {
continue;
};
if is_rust_cu(root, unit_ref) {
if let Some(compile_dir) = &unit_ref.comp_dir {
match compile_dir.to_string() {
Ok(compile_dir) => {
if compile_dir.is_empty() {
tracing::debug!(
"Skipping empty compile directory for unit: {}",
pretty_print_die_entry(root, unit_ref)
);
} else {
compile_dirs.insert(PathBuf::from(compile_dir.to_string()));
}
}
Err(e) => {
tracing::error!("Failed to convert compile directory to string: {e}");
}
}
}
let files = unit_ref
.line_program
.as_ref()
.map(|lp| {
lp.header()
.file_names()
.iter()
.flat_map(|f| {
file_entry_to_path(db, f, unit_ref)
.map(|path| SourceFile::new(db, path))
})
.collect::<BTreeSet<_>>()
})
.unwrap_or_default();
sources.extend(files);
}
}
(compile_dirs, sources)
}