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