aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/test_db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/test_db.rs')
-rw-r--r--crates/hir_def/src/test_db.rs101
1 files changed, 101 insertions, 0 deletions
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs
new file mode 100644
index 000000000..42a762936
--- /dev/null
+++ b/crates/hir_def/src/test_db.rs
@@ -0,0 +1,101 @@
1//! Database used for testing `hir_def`.
2
3use std::{
4 fmt, panic,
5 sync::{Arc, Mutex},
6};
7
8use base_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, Upcast};
9use hir_expand::db::AstDatabase;
10use rustc_hash::FxHashSet;
11
12use crate::db::DefDatabase;
13
14#[salsa::database(
15 base_db::SourceDatabaseExtStorage,
16 base_db::SourceDatabaseStorage,
17 hir_expand::db::AstDatabaseStorage,
18 crate::db::InternDatabaseStorage,
19 crate::db::DefDatabaseStorage
20)]
21#[derive(Default)]
22pub struct TestDB {
23 storage: salsa::Storage<TestDB>,
24 events: Mutex<Option<Vec<salsa::Event>>>,
25}
26
27impl Upcast<dyn AstDatabase> for TestDB {
28 fn upcast(&self) -> &(dyn AstDatabase + 'static) {
29 &*self
30 }
31}
32
33impl Upcast<dyn DefDatabase> for TestDB {
34 fn upcast(&self) -> &(dyn DefDatabase + 'static) {
35 &*self
36 }
37}
38
39impl salsa::Database for TestDB {
40 fn salsa_event(&self, event: salsa::Event) {
41 let mut events = self.events.lock().unwrap();
42 if let Some(events) = &mut *events {
43 events.push(event);
44 }
45 }
46}
47
48impl fmt::Debug for TestDB {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("TestDB").finish()
51 }
52}
53
54impl panic::RefUnwindSafe for TestDB {}
55
56impl FileLoader for TestDB {
57 fn file_text(&self, file_id: FileId) -> Arc<String> {
58 FileLoaderDelegate(self).file_text(file_id)
59 }
60 fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
61 FileLoaderDelegate(self).resolve_path(anchor, path)
62 }
63 fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
64 FileLoaderDelegate(self).relevant_crates(file_id)
65 }
66}
67
68impl TestDB {
69 pub fn module_for_file(&self, file_id: FileId) -> crate::ModuleId {
70 for &krate in self.relevant_crates(file_id).iter() {
71 let crate_def_map = self.crate_def_map(krate);
72 for (local_id, data) in crate_def_map.modules.iter() {
73 if data.origin.file_id() == Some(file_id) {
74 return crate::ModuleId { krate, local_id };
75 }
76 }
77 }
78 panic!("Can't find module for file")
79 }
80
81 pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> {
82 *self.events.lock().unwrap() = Some(Vec::new());
83 f();
84 self.events.lock().unwrap().take().unwrap()
85 }
86
87 pub fn log_executed(&self, f: impl FnOnce()) -> Vec<String> {
88 let events = self.log(f);
89 events
90 .into_iter()
91 .filter_map(|e| match e.kind {
92 // This pretty horrible, but `Debug` is the only way to inspect
93 // QueryDescriptor at the moment.
94 salsa::EventKind::WillExecute { database_key } => {
95 Some(format!("{:?}", database_key.debug(self)))
96 }
97 _ => None,
98 })
99 .collect()
100 }
101}