use std::collections::HashMap;
use cairo_lang_defs::db::DefsGroup;
use cairo_lang_filesystem::db::FilesGroup;
use cairo_lang_filesystem::ids::FileId;
use cairo_lang_filesystem::span::TextSpan;
use cairo_language_common::CommonGroup;
use crate::lang::db::AnalysisDatabase;
#[derive(Clone, Default)]
pub struct SearchScope<'db> {
entries: HashMap<FileId<'db>, Option<TextSpan>>,
}
impl<'db> SearchScope<'db> {
pub fn empty() -> Self {
Self::default()
}
#[tracing::instrument(skip_all)]
pub fn everything(db: &'db AnalysisDatabase) -> Self {
let mut this = Self::empty();
for crate_id in db.crates() {
for &module_id in db.crate_modules(*crate_id).iter() {
if let Ok(file_id) = db.module_main_file(module_id)
&& let Some((files, _)) =
db.file_and_subfiles_with_corresponding_modules(file_id)
{
this.entries.extend(files.iter().copied().map(|f| (f, None)));
}
}
}
this
}
pub fn file(file: FileId<'db>) -> Self {
Self { entries: [(file, None)].into() }
}
pub fn file_span(file: FileId<'db>, span: TextSpan) -> Self {
Self { entries: [(file, Some(span))].into() }
}
pub fn file_with_subfiles(db: &'db AnalysisDatabase, file: FileId<'db>) -> Self {
let mut this = Self { entries: [(file, None)].into() };
if let Some((files, _)) = db.file_and_subfiles_with_corresponding_modules(file) {
this.entries.extend(files.iter().copied().map(|f| (f, None)));
}
this
}
pub fn files_spans(files: HashMap<FileId<'db>, Option<TextSpan>>) -> Self {
Self { entries: files }
}
pub fn files_contents_and_spans<'a>(
&'a self,
db: &'db AnalysisDatabase,
) -> impl Iterator<Item = (FileId<'db>, &'db str, Option<TextSpan>)> + use<'a, 'db> {
self.entries.iter().map(|(&file, &span)| (file, span)).filter_map(move |(file, span)| {
let text = db.file_content(file)?;
Some((file, text, span))
})
}
}