use std::sync::Arc;
use mir_analyzer::db::{MirDatabase, SourceFile};
use tower_lsp::lsp_types::Url;
use crate::db::index::IndexArc;
use crate::db::parse::ParsedArc;
use crate::db::symbol_map::SymbolMapArc;
use crate::db::workspace_index::{WorkspaceIndexArc, WorkspaceIndexData, build_maps};
use crate::document::ast::ParsedDoc;
use crate::index::file_index::FileIndex;
use crate::types::symbol_map::SymbolMap;
#[salsa::input]
pub struct LspWsFile {
pub source: SourceFile,
pub cached_index: Option<Arc<FileIndex>>,
}
#[salsa::input]
pub struct LspWorkspace {
pub files: Arc<[LspWsFile]>,
}
#[salsa::tracked(no_eq, lru = 2048)]
pub fn parsed_doc(db: &dyn MirDatabase, file: SourceFile) -> ParsedArc {
ParsedArc(Arc::new(ParsedDoc::parse(file.text(db).clone())))
}
#[salsa::tracked(no_eq, lru = 2048)]
pub fn symbol_map(db: &dyn MirDatabase, file: SourceFile) -> SymbolMapArc {
let doc = parsed_doc(db, file);
SymbolMapArc(Arc::new(SymbolMap::build(doc.get())))
}
#[salsa::tracked]
pub fn file_index(db: &dyn MirDatabase, wf: LspWsFile) -> IndexArc {
if let Some(cached) = wf.cached_index(db) {
return IndexArc(cached.clone());
}
let doc = parsed_doc(db, *wf.source(db));
IndexArc(Arc::new(FileIndex::extract(doc.get())))
}
#[salsa::tracked(no_eq)]
pub fn workspace_index(db: &dyn MirDatabase, ws: LspWorkspace) -> WorkspaceIndexArc {
let ws_files = ws.files(db);
let mut files: Vec<(Url, Arc<FileIndex>)> = Vec::with_capacity(ws_files.len());
for wf in ws_files.iter() {
let Ok(url) = Url::parse(wf.source(db).path(db)) else {
continue;
};
let idx = file_index(db, *wf).0.clone();
files.push((url, idx));
}
let (classes_by_name, subtypes_of, decls_by_name, classes_by_lowercase_name) =
build_maps(&files);
WorkspaceIndexArc(Arc::new(WorkspaceIndexData {
files,
classes_by_name,
subtypes_of,
decls_by_name,
classes_by_lowercase_name,
}))
}