aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/test_db.rs
diff options
context:
space:
mode:
authorZac Pullar-Strecker <[email protected]>2020-07-31 03:12:44 +0100
committerZac Pullar-Strecker <[email protected]>2020-07-31 03:12:44 +0100
commitf05d7b41a719d848844b054a16477b29d0f063c6 (patch)
tree0a8a0946e8aef2ce64d4c13d0035ba41cce2daf3 /crates/ra_hir_ty/src/test_db.rs
parent73ff610e41959e3e7c78a2b4b25b086883132956 (diff)
parent6b7cb8b5ab539fc4333ce34bc29bf77c976f232a (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.rs125
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
3use std::{ 3use std::{
4 panic, 4 fmt, panic,
5 sync::{Arc, Mutex}, 5 sync::{Arc, Mutex},
6}; 6};
7 7
8use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId}; 8use hir_def::{db::DefDatabase, ModuleId};
9use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink}; 9use hir_expand::db::AstDatabase;
10use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast}; 10use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast};
11use rustc_hash::FxHashSet; 11use ra_syntax::TextRange;
12use stdx::format_to; 12use rustc_hash::{FxHashMap, FxHashSet};
13 13use test_utils::extract_annotations;
14use 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)]
28pub struct TestDB { 24pub 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}
28impl 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
33impl Upcast<dyn AstDatabase> for TestDB { 34impl Upcast<dyn AstDatabase> for TestDB {
@@ -43,18 +44,10 @@ impl Upcast<dyn DefDatabase> for TestDB {
43} 44}
44 45
45impl salsa::Database for TestDB { 46impl 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 {
62impl salsa::ParallelDatabase for TestDB { 55impl 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
85impl TestDB { 78impl 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
172impl TestDB { 115impl 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 })