]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide_db/src/lib.rs
Cleanup
[rust.git] / crates / ra_ide_db / src / lib.rs
1 //! This crate defines the core datastructure representing IDE state -- `RootDatabase`.
2 //!
3 //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.
4
5 pub mod line_index;
6 pub mod line_index_utils;
7 pub mod feature_flags;
8 pub mod symbol_index;
9 pub mod change;
10 mod wasm_shims;
11
12 use std::sync::Arc;
13
14 use ra_db::{
15     salsa::{self, Database, Durability},
16     Canceled, CheckCanceled, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath,
17     SourceDatabase, SourceRootId,
18 };
19 use rustc_hash::FxHashMap;
20
21 use crate::{feature_flags::FeatureFlags, line_index::LineIndex, symbol_index::SymbolsDatabase};
22
23 #[salsa::database(
24     ra_db::SourceDatabaseStorage,
25     ra_db::SourceDatabaseExtStorage,
26     LineIndexDatabaseStorage,
27     symbol_index::SymbolsDatabaseStorage,
28     hir::db::InternDatabaseStorage,
29     hir::db::AstDatabaseStorage,
30     hir::db::DefDatabaseStorage,
31     hir::db::HirDatabaseStorage
32 )]
33 #[derive(Debug)]
34 pub struct RootDatabase {
35     runtime: salsa::Runtime<RootDatabase>,
36     pub feature_flags: Arc<FeatureFlags>,
37     pub(crate) debug_data: Arc<DebugData>,
38     pub last_gc: crate::wasm_shims::Instant,
39     pub last_gc_check: crate::wasm_shims::Instant,
40 }
41
42 impl FileLoader for RootDatabase {
43     fn file_text(&self, file_id: FileId) -> Arc<String> {
44         FileLoaderDelegate(self).file_text(file_id)
45     }
46     fn resolve_relative_path(
47         &self,
48         anchor: FileId,
49         relative_path: &RelativePath,
50     ) -> Option<FileId> {
51         FileLoaderDelegate(self).resolve_relative_path(anchor, relative_path)
52     }
53     fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> {
54         FileLoaderDelegate(self).relevant_crates(file_id)
55     }
56 }
57
58 impl salsa::Database for RootDatabase {
59     fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
60         &self.runtime
61     }
62     fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> {
63         &mut self.runtime
64     }
65     fn on_propagated_panic(&self) -> ! {
66         Canceled::throw()
67     }
68     fn salsa_event(&self, event: impl Fn() -> salsa::Event<RootDatabase>) {
69         match event().kind {
70             salsa::EventKind::DidValidateMemoizedValue { .. }
71             | salsa::EventKind::WillExecute { .. } => {
72                 self.check_canceled();
73             }
74             _ => (),
75         }
76     }
77 }
78
79 impl Default for RootDatabase {
80     fn default() -> RootDatabase {
81         RootDatabase::new(None, FeatureFlags::default())
82     }
83 }
84
85 impl RootDatabase {
86     pub fn new(lru_capacity: Option<usize>, feature_flags: FeatureFlags) -> RootDatabase {
87         let mut db = RootDatabase {
88             runtime: salsa::Runtime::default(),
89             last_gc: crate::wasm_shims::Instant::now(),
90             last_gc_check: crate::wasm_shims::Instant::now(),
91             feature_flags: Arc::new(feature_flags),
92             debug_data: Default::default(),
93         };
94         db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
95         db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
96         db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
97         let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP);
98         db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);
99         db.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity);
100         db.query_mut(hir::db::MacroExpandQuery).set_lru_capacity(lru_capacity);
101         db
102     }
103 }
104
105 impl salsa::ParallelDatabase for RootDatabase {
106     fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
107         salsa::Snapshot::new(RootDatabase {
108             runtime: self.runtime.snapshot(self),
109             last_gc: self.last_gc,
110             last_gc_check: self.last_gc_check,
111             feature_flags: Arc::clone(&self.feature_flags),
112             debug_data: Arc::clone(&self.debug_data),
113         })
114     }
115 }
116
117 #[salsa::query_group(LineIndexDatabaseStorage)]
118 pub trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
119     fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
120 }
121
122 fn line_index(db: &impl LineIndexDatabase, file_id: FileId) -> Arc<LineIndex> {
123     let text = db.file_text(file_id);
124     Arc::new(LineIndex::new(&*text))
125 }
126
127 #[derive(Debug, Default, Clone)]
128 pub(crate) struct DebugData {
129     pub(crate) root_paths: FxHashMap<SourceRootId, String>,
130     pub(crate) crate_names: FxHashMap<CrateId, String>,
131 }
132
133 impl DebugData {
134     pub(crate) fn merge(&mut self, other: DebugData) {
135         self.root_paths.extend(other.root_paths.into_iter());
136         self.crate_names.extend(other.crate_names.into_iter());
137     }
138 }