mun_language_server/
analysis.rs1use crate::{
2 cancelation::Canceled, change::AnalysisChange, completion, db::AnalysisDatabase, diagnostics,
3 diagnostics::Diagnostic, file_structure, FilePosition,
4};
5use mun_hir::{line_index::LineIndex, AstDatabase, SourceDatabase};
6use mun_syntax::SourceFile;
7use salsa::{ParallelDatabase, Snapshot};
8use std::sync::Arc;
9
10pub type Cancelable<T> = Result<T, Canceled>;
12
13#[derive(Default)]
16pub struct Analysis {
17 db: AnalysisDatabase,
18}
19
20impl Analysis {
21 pub fn apply_change(&mut self, change: AnalysisChange) {
24 self.db.apply_change(change)
25 }
26
27 pub fn snapshot(&self) -> AnalysisSnapshot {
30 AnalysisSnapshot {
31 db: self.db.snapshot(),
32 }
33 }
34
35 pub fn request_cancelation(&mut self) {
37 self.db.request_cancelation();
38 }
39}
40
41pub struct AnalysisSnapshot {
48 db: Snapshot<AnalysisDatabase>,
49}
50
51impl AnalysisSnapshot {
52 pub fn parse(&self, file_id: mun_hir::FileId) -> Cancelable<SourceFile> {
54 self.with_db(|db| db.parse(file_id).tree())
55 }
56
57 pub fn diagnostics(&self, file_id: mun_hir::FileId) -> Cancelable<Vec<Diagnostic>> {
59 self.with_db(|db| diagnostics::diagnostics(db, file_id))
60 }
61
62 pub fn package_source_files(
64 &self,
65 package_id: mun_hir::PackageId,
66 ) -> Cancelable<Vec<mun_hir::FileId>> {
67 self.with_db(|db| {
68 let packages = db.packages();
69 let source_root = db.source_root(packages[package_id].source_root);
70 source_root.files().collect()
71 })
72 }
73
74 pub fn file_line_index(&self, file_id: mun_hir::FileId) -> Cancelable<Arc<LineIndex>> {
76 self.with_db(|db| db.line_index(file_id))
77 }
78
79 pub fn file_structure(
81 &self,
82 file_id: mun_hir::FileId,
83 ) -> Cancelable<Vec<file_structure::StructureNode>> {
84 self.with_db(|db| file_structure::file_structure(&db.parse(file_id).tree()))
85 }
86
87 pub fn completions(
89 &self,
90 position: FilePosition,
91 ) -> Cancelable<Option<Vec<completion::CompletionItem>>> {
92 self.with_db(|db| completion::completions(db, position).map(Into::into))
93 }
94
95 fn with_db<F: FnOnce(&AnalysisDatabase) -> T + std::panic::UnwindSafe, T>(
97 &self,
98 f: F,
99 ) -> Cancelable<T> {
100 self.db.catch_canceled(f)
101 }
102}