aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/test_db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/test_db.rs')
-rw-r--r--crates/ra_hir/src/test_db.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs
new file mode 100644
index 000000000..047a27aaf
--- /dev/null
+++ b/crates/ra_hir/src/test_db.rs
@@ -0,0 +1,131 @@
1//! FIXME: write short doc here
2
3use std::{panic, sync::Arc};
4
5use hir_def::{db::DefDatabase2, ModuleId};
6use hir_expand::diagnostics::DiagnosticSink;
7use parking_lot::Mutex;
8use ra_db::{
9 salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, SourceDatabase,
10 SourceRootId,
11};
12
13use crate::{db, debug::HirDebugHelper};
14
15#[salsa::database(
16 ra_db::SourceDatabaseExtStorage,
17 ra_db::SourceDatabaseStorage,
18 db::InternDatabaseStorage,
19 db::AstDatabaseStorage,
20 db::DefDatabaseStorage,
21 db::DefDatabase2Storage,
22 db::HirDatabaseStorage
23)]
24#[derive(Debug)]
25pub struct TestDB {
26 events: Mutex<Option<Vec<salsa::Event<TestDB>>>>,
27 runtime: salsa::Runtime<TestDB>,
28}
29
30impl panic::RefUnwindSafe for TestDB {}
31
32impl FileLoader for TestDB {
33 fn file_text(&self, file_id: FileId) -> Arc<String> {
34 FileLoaderDelegate(self).file_text(file_id)
35 }
36 fn resolve_relative_path(
37 &self,
38 anchor: FileId,
39 relative_path: &RelativePath,
40 ) -> Option<FileId> {
41 FileLoaderDelegate(self).resolve_relative_path(anchor, relative_path)
42 }
43 fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> {
44 FileLoaderDelegate(self).relevant_crates(file_id)
45 }
46}
47
48// FIXME: improve `WithFixture` to bring useful hir debugging back
49impl HirDebugHelper for TestDB {
50 fn crate_name(&self, _krate: CrateId) -> Option<String> {
51 None
52 }
53
54 fn file_path(&self, _file_id: FileId) -> Option<String> {
55 None
56 }
57}
58
59impl TestDB {
60 pub fn diagnostics(&self) -> String {
61 let mut buf = String::new();
62 let crate_graph = self.crate_graph();
63 for krate in crate_graph.iter().next() {
64 let crate_def_map = self.crate_def_map(krate);
65 for (module_id, _) in crate_def_map.modules.iter() {
66 let module_id = ModuleId { krate, module_id };
67 let module = crate::Module::from(module_id);
68 module.diagnostics(
69 self,
70 &mut DiagnosticSink::new(|d| {
71 buf += &format!("{:?}: {}\n", d.syntax_node(self).text(), d.message());
72 }),
73 )
74 }
75 }
76 buf
77 }
78}
79
80impl salsa::Database for TestDB {
81 fn salsa_runtime(&self) -> &salsa::Runtime<TestDB> {
82 &self.runtime
83 }
84
85 fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) {
86 let mut events = self.events.lock();
87 if let Some(events) = &mut *events {
88 events.push(event());
89 }
90 }
91}
92
93impl Default for TestDB {
94 fn default() -> TestDB {
95 let mut db = TestDB { events: Default::default(), runtime: salsa::Runtime::default() };
96 db.set_crate_graph(Default::default());
97 db
98 }
99}
100
101impl salsa::ParallelDatabase for TestDB {
102 fn snapshot(&self) -> salsa::Snapshot<TestDB> {
103 salsa::Snapshot::new(TestDB {
104 events: Default::default(),
105 runtime: self.runtime.snapshot(self),
106 })
107 }
108}
109
110impl TestDB {
111 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<TestDB>> {
112 *self.events.lock() = Some(Vec::new());
113 f();
114 self.events.lock().take().unwrap()
115 }
116
117 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
118 let events = self.log(f);
119 events
120 .into_iter()
121 .filter_map(|e| match e.kind {
122 // This pretty horrible, but `Debug` is the only way to inspect
123 // QueryDescriptor at the moment.
124 salsa::EventKind::WillExecute { database_key } => {
125 Some(format!("{:?}", database_key))
126 }
127 _ => None,
128 })
129 .collect()
130 }
131}