diff options
author | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
---|---|---|
committer | Zac Pullar-Strecker <[email protected]> | 2020-07-31 03:12:44 +0100 |
commit | f05d7b41a719d848844b054a16477b29d0f063c6 (patch) | |
tree | 0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/ra_hir_ty/src/test_db.rs | |
parent | 73ff610e41959e3e7c78a2b4b25b086883132956 (diff) | |
parent | 6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (diff) |
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
Hasn't fixed tests yet.
Diffstat (limited to 'crates/ra_hir_ty/src/test_db.rs')
-rw-r--r-- | crates/ra_hir_ty/src/test_db.rs | 125 |
1 files changed, 34 insertions, 91 deletions
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index 0481a7b12..a1714ff0f 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs | |||
@@ -1,20 +1,16 @@ | |||
1 | //! Database used for testing `hir`. | 1 | //! Database used for testing `hir`. |
2 | 2 | ||
3 | use std::{ | 3 | use std::{ |
4 | panic, | 4 | fmt, panic, |
5 | sync::{Arc, Mutex}, | 5 | sync::{Arc, Mutex}, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; | 8 | use hir_def::{db::DefDatabase, ModuleId}; |
9 | use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink}; | 9 | use hir_expand::db::AstDatabase; |
10 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast}; | 10 | use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast}; |
11 | use rustc_hash::FxHashSet; | 11 | use ra_syntax::TextRange; |
12 | use stdx::format_to; | 12 | use rustc_hash::{FxHashMap, FxHashSet}; |
13 | 13 | use test_utils::extract_annotations; | |
14 | use crate::{ | ||
15 | db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator, | ||
16 | unsafe_validation::UnsafeValidator, | ||
17 | }; | ||
18 | 14 | ||
19 | #[salsa::database( | 15 | #[salsa::database( |
20 | ra_db::SourceDatabaseExtStorage, | 16 | ra_db::SourceDatabaseExtStorage, |
@@ -24,10 +20,15 @@ use crate::{ | |||
24 | hir_def::db::DefDatabaseStorage, | 20 | hir_def::db::DefDatabaseStorage, |
25 | crate::db::HirDatabaseStorage | 21 | crate::db::HirDatabaseStorage |
26 | )] | 22 | )] |
27 | #[derive(Debug, Default)] | 23 | #[derive(Default)] |
28 | pub struct TestDB { | 24 | pub struct TestDB { |
29 | events: Mutex<Option<Vec<salsa::Event<TestDB>>>>, | 25 | storage: salsa::Storage<TestDB>, |
30 | runtime: salsa::Runtime<TestDB>, | 26 | events: Mutex<Option<Vec<salsa::Event>>>, |
27 | } | ||
28 | impl fmt::Debug for TestDB { | ||
29 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
30 | f.debug_struct("TestDB").finish() | ||
31 | } | ||
31 | } | 32 | } |
32 | 33 | ||
33 | impl Upcast<dyn AstDatabase> for TestDB { | 34 | impl Upcast<dyn AstDatabase> for TestDB { |
@@ -43,18 +44,10 @@ impl Upcast<dyn DefDatabase> for TestDB { | |||
43 | } | 44 | } |
44 | 45 | ||
45 | impl salsa::Database for TestDB { | 46 | impl salsa::Database for TestDB { |
46 | fn salsa_runtime(&self) -> &salsa::Runtime<TestDB> { | 47 | fn salsa_event(&self, event: salsa::Event) { |
47 | &self.runtime | ||
48 | } | ||
49 | |||
50 | fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> { | ||
51 | &mut self.runtime | ||
52 | } | ||
53 | |||
54 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<TestDB>) { | ||
55 | let mut events = self.events.lock().unwrap(); | 48 | let mut events = self.events.lock().unwrap(); |
56 | if let Some(events) = &mut *events { | 49 | if let Some(events) = &mut *events { |
57 | events.push(event()); | 50 | events.push(event); |
58 | } | 51 | } |
59 | } | 52 | } |
60 | } | 53 | } |
@@ -62,8 +55,8 @@ impl salsa::Database for TestDB { | |||
62 | impl salsa::ParallelDatabase for TestDB { | 55 | impl salsa::ParallelDatabase for TestDB { |
63 | fn snapshot(&self) -> salsa::Snapshot<TestDB> { | 56 | fn snapshot(&self) -> salsa::Snapshot<TestDB> { |
64 | salsa::Snapshot::new(TestDB { | 57 | salsa::Snapshot::new(TestDB { |
58 | storage: self.storage.snapshot(), | ||
65 | events: Default::default(), | 59 | events: Default::default(), |
66 | runtime: self.runtime.snapshot(self), | ||
67 | }) | 60 | }) |
68 | } | 61 | } |
69 | } | 62 | } |
@@ -83,7 +76,7 @@ impl FileLoader for TestDB { | |||
83 | } | 76 | } |
84 | 77 | ||
85 | impl TestDB { | 78 | impl TestDB { |
86 | pub fn module_for_file(&self, file_id: FileId) -> ModuleId { | 79 | pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { |
87 | for &krate in self.relevant_crates(file_id).iter() { | 80 | for &krate in self.relevant_crates(file_id).iter() { |
88 | let crate_def_map = self.crate_def_map(krate); | 81 | let crate_def_map = self.crate_def_map(krate); |
89 | for (local_id, data) in crate_def_map.modules.iter() { | 82 | for (local_id, data) in crate_def_map.modules.iter() { |
@@ -95,82 +88,32 @@ impl TestDB { | |||
95 | panic!("Can't find module for file") | 88 | panic!("Can't find module for file") |
96 | } | 89 | } |
97 | 90 | ||
98 | fn diag<F: FnMut(&dyn Diagnostic)>(&self, mut cb: F) { | 91 | pub(crate) fn extract_annotations(&self) -> FxHashMap<FileId, Vec<(TextRange, String)>> { |
99 | let crate_graph = self.crate_graph(); | 92 | let mut files = Vec::new(); |
100 | for krate in crate_graph.iter() { | ||
101 | let crate_def_map = self.crate_def_map(krate); | ||
102 | |||
103 | let mut fns = Vec::new(); | ||
104 | for (module_id, _) in crate_def_map.modules.iter() { | ||
105 | for decl in crate_def_map[module_id].scope.declarations() { | ||
106 | if let ModuleDefId::FunctionId(f) = decl { | ||
107 | fns.push(f) | ||
108 | } | ||
109 | } | ||
110 | |||
111 | for impl_id in crate_def_map[module_id].scope.impls() { | ||
112 | let impl_data = self.impl_data(impl_id); | ||
113 | for item in impl_data.items.iter() { | ||
114 | if let AssocItemId::FunctionId(f) = item { | ||
115 | fns.push(*f) | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | for f in fns { | ||
122 | let infer = self.infer(f.into()); | ||
123 | let mut sink = DiagnosticSink::new(&mut cb); | ||
124 | infer.add_diagnostics(self, f, &mut sink); | ||
125 | let mut validator = ExprValidator::new(f, infer.clone(), &mut sink); | ||
126 | validator.validate_body(self); | ||
127 | let mut validator = UnsafeValidator::new(f, infer, &mut sink); | ||
128 | validator.validate_body(self); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | pub fn diagnostics(&self) -> (String, u32) { | ||
134 | let mut buf = String::new(); | ||
135 | let mut count = 0; | ||
136 | self.diag(|d| { | ||
137 | format_to!(buf, "{:?}: {}\n", d.syntax_node(self).text(), d.message()); | ||
138 | count += 1; | ||
139 | }); | ||
140 | (buf, count) | ||
141 | } | ||
142 | |||
143 | /// Like `diagnostics`, but filtered for a single diagnostic. | ||
144 | pub fn diagnostic<D: Diagnostic>(&self) -> (String, u32) { | ||
145 | let mut buf = String::new(); | ||
146 | let mut count = 0; | ||
147 | self.diag(|d| { | ||
148 | // We want to filter diagnostics by the particular one we are testing for, to | ||
149 | // avoid surprising results in tests. | ||
150 | if d.downcast_ref::<D>().is_some() { | ||
151 | format_to!(buf, "{:?}: {}\n", d.syntax_node(self).text(), d.message()); | ||
152 | count += 1; | ||
153 | }; | ||
154 | }); | ||
155 | (buf, count) | ||
156 | } | ||
157 | |||
158 | pub fn all_files(&self) -> Vec<FileId> { | ||
159 | let mut res = Vec::new(); | ||
160 | let crate_graph = self.crate_graph(); | 93 | let crate_graph = self.crate_graph(); |
161 | for krate in crate_graph.iter() { | 94 | for krate in crate_graph.iter() { |
162 | let crate_def_map = self.crate_def_map(krate); | 95 | let crate_def_map = self.crate_def_map(krate); |
163 | for (module_id, _) in crate_def_map.modules.iter() { | 96 | for (module_id, _) in crate_def_map.modules.iter() { |
164 | let file_id = crate_def_map[module_id].origin.file_id(); | 97 | let file_id = crate_def_map[module_id].origin.file_id(); |
165 | res.extend(file_id) | 98 | files.extend(file_id) |
166 | } | 99 | } |
167 | } | 100 | } |
168 | res | 101 | files |
102 | .into_iter() | ||
103 | .filter_map(|file_id| { | ||
104 | let text = self.file_text(file_id); | ||
105 | let annotations = extract_annotations(&text); | ||
106 | if annotations.is_empty() { | ||
107 | return None; | ||
108 | } | ||
109 | Some((file_id, annotations)) | ||
110 | }) | ||
111 | .collect() | ||
169 | } | 112 | } |
170 | } | 113 | } |
171 | 114 | ||
172 | impl TestDB { | 115 | impl TestDB { |
173 | pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<TestDB>> { | 116 | pub fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> { |
174 | *self.events.lock().unwrap() = Some(Vec::new()); | 117 | *self.events.lock().unwrap() = Some(Vec::new()); |
175 | f(); | 118 | f(); |
176 | self.events.lock().unwrap().take().unwrap() | 119 | self.events.lock().unwrap().take().unwrap() |
@@ -184,7 +127,7 @@ impl TestDB { | |||
184 | // This pretty horrible, but `Debug` is the only way to inspect | 127 | // This pretty horrible, but `Debug` is the only way to inspect |
185 | // QueryDescriptor at the moment. | 128 | // QueryDescriptor at the moment. |
186 | salsa::EventKind::WillExecute { database_key } => { | 129 | salsa::EventKind::WillExecute { database_key } => { |
187 | Some(format!("{:?}", database_key)) | 130 | Some(format!("{:?}", database_key.debug(self))) |
188 | } | 131 | } |
189 | _ => None, | 132 | _ => None, |
190 | }) | 133 | }) |