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