php_lsp/db/
mir_queries.rs1use std::sync::Arc;
7
8use mir_analyzer::db::{MirDatabase, SourceFile};
9use tower_lsp::lsp_types::Url;
10
11use crate::db::index::IndexArc;
12use crate::db::parse::ParsedArc;
13use crate::db::symbol_map::SymbolMapArc;
14use crate::db::workspace_index::{WorkspaceIndexArc, WorkspaceIndexData, build_maps};
15use crate::document::ast::ParsedDoc;
16use crate::index::file_index::FileIndex;
17use crate::types::symbol_map::SymbolMap;
18
19#[salsa::input]
25pub struct LspWsFile {
26 pub source: SourceFile,
27 pub cached_index: Option<Arc<FileIndex>>,
28}
29
30#[salsa::input]
34pub struct LspWorkspace {
35 pub files: Arc<[LspWsFile]>,
36}
37
38#[salsa::tracked(no_eq, lru = 2048)]
42pub fn parsed_doc(db: &dyn MirDatabase, file: SourceFile) -> ParsedArc {
43 ParsedArc(Arc::new(ParsedDoc::parse(file.text(db).clone())))
44}
45
46#[salsa::tracked(no_eq, lru = 2048)]
49pub fn symbol_map(db: &dyn MirDatabase, file: SourceFile) -> SymbolMapArc {
50 let doc = parsed_doc(db, file);
51 SymbolMapArc(Arc::new(SymbolMap::build(doc.get())))
52}
53
54#[salsa::tracked]
58pub fn file_index(db: &dyn MirDatabase, wf: LspWsFile) -> IndexArc {
59 if let Some(cached) = wf.cached_index(db) {
60 return IndexArc(cached.clone());
61 }
62 let doc = parsed_doc(db, *wf.source(db));
63 IndexArc(Arc::new(FileIndex::extract(doc.get())))
64}
65
66#[salsa::tracked(no_eq)]
70pub fn workspace_index(db: &dyn MirDatabase, ws: LspWorkspace) -> WorkspaceIndexArc {
71 let ws_files = ws.files(db);
72 let mut files: Vec<(Url, Arc<FileIndex>)> = Vec::with_capacity(ws_files.len());
73 for wf in ws_files.iter() {
74 let Ok(url) = Url::parse(wf.source(db).path(db)) else {
75 continue;
76 };
77 let idx = file_index(db, *wf).0.clone();
78 files.push((url, idx));
79 }
80 let (classes_by_name, subtypes_of, decls_by_name, classes_by_lowercase_name) =
81 build_maps(&files);
82 WorkspaceIndexArc(Arc::new(WorkspaceIndexData {
83 files,
84 classes_by_name,
85 subtypes_of,
86 decls_by_name,
87 classes_by_lowercase_name,
88 }))
89}