use std::sync::Arc;
use mir_analyzer::db::{MirDatabase, SourceFile};
use tower_lsp_server::ls_types::Uri;
use crate::db::index::IndexArc;
use crate::db::parse::ParsedArc;
use crate::db::symbol_map::SymbolMapArc;
use crate::db::workspace_index::{WorkspaceIndexArc, WorkspaceIndexData};
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<(Uri, Arc<FileIndex>)> = Vec::with_capacity(ws_files.len());
for wf in ws_files.iter() {
let Ok(url) = (wf.source(db).path(db)).parse::<Uri>() else {
continue;
};
let idx = file_index(db, *wf).0.clone();
files.push((url, idx));
}
WorkspaceIndexArc(Arc::new(WorkspaceIndexData::from_files(files)))
}