diff options
-rw-r--r-- | crates/ra_analysis/src/db.rs | 41 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/nameres.rs | 64 |
2 files changed, 104 insertions, 1 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 887d687ea..7c28c9a2b 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use parking_lot::Mutex; | ||
3 | use ra_editor::LineIndex; | 4 | use ra_editor::LineIndex; |
4 | use ra_syntax::{SourceFileNode, SyntaxNode}; | 5 | use ra_syntax::{SourceFileNode, SyntaxNode}; |
5 | use salsa::{self, Database}; | 6 | use salsa::{self, Database}; |
@@ -18,6 +19,11 @@ use crate::{ | |||
18 | 19 | ||
19 | #[derive(Debug)] | 20 | #[derive(Debug)] |
20 | pub(crate) struct RootDatabase { | 21 | pub(crate) struct RootDatabase { |
22 | #[cfg(test)] | ||
23 | events: Mutex<Option<Vec<salsa::Event<RootDatabase>>>>, | ||
24 | #[cfg(not(test))] | ||
25 | events: (), | ||
26 | |||
21 | runtime: salsa::Runtime<RootDatabase>, | 27 | runtime: salsa::Runtime<RootDatabase>, |
22 | id_maps: IdMaps, | 28 | id_maps: IdMaps, |
23 | } | 29 | } |
@@ -26,11 +32,22 @@ impl salsa::Database for RootDatabase { | |||
26 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { | 32 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { |
27 | &self.runtime | 33 | &self.runtime |
28 | } | 34 | } |
35 | |||
36 | fn salsa_event(&self, event: impl Fn() -> salsa::Event<RootDatabase>) { | ||
37 | #[cfg(test)] | ||
38 | { | ||
39 | let mut events = self.events.lock(); | ||
40 | if let Some(events) = &mut *events { | ||
41 | events.push(event()); | ||
42 | } | ||
43 | } | ||
44 | } | ||
29 | } | 45 | } |
30 | 46 | ||
31 | impl Default for RootDatabase { | 47 | impl Default for RootDatabase { |
32 | fn default() -> RootDatabase { | 48 | fn default() -> RootDatabase { |
33 | let mut db = RootDatabase { | 49 | let mut db = RootDatabase { |
50 | events: Default::default(), | ||
34 | runtime: salsa::Runtime::default(), | 51 | runtime: salsa::Runtime::default(), |
35 | id_maps: IdMaps::default(), | 52 | id_maps: IdMaps::default(), |
36 | }; | 53 | }; |
@@ -55,6 +72,7 @@ pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { | |||
55 | impl salsa::ParallelDatabase for RootDatabase { | 72 | impl salsa::ParallelDatabase for RootDatabase { |
56 | fn snapshot(&self) -> salsa::Snapshot<RootDatabase> { | 73 | fn snapshot(&self) -> salsa::Snapshot<RootDatabase> { |
57 | salsa::Snapshot::new(RootDatabase { | 74 | salsa::Snapshot::new(RootDatabase { |
75 | events: Default::default(), | ||
58 | runtime: self.runtime.snapshot(self), | 76 | runtime: self.runtime.snapshot(self), |
59 | id_maps: self.id_maps.clone(), | 77 | id_maps: self.id_maps.clone(), |
60 | }) | 78 | }) |
@@ -67,6 +85,29 @@ impl IdDatabase for RootDatabase { | |||
67 | } | 85 | } |
68 | } | 86 | } |
69 | 87 | ||
88 | #[cfg(test)] | ||
89 | impl RootDatabase { | ||
90 | pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event<RootDatabase>> { | ||
91 | *self.events.lock() = Some(Vec::new()); | ||
92 | f(); | ||
93 | let events = self.events.lock().take().unwrap(); | ||
94 | events | ||
95 | } | ||
96 | |||
97 | pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec<String> { | ||
98 | let events = self.log(f); | ||
99 | events | ||
100 | .into_iter() | ||
101 | .filter_map(|e| match e.kind { | ||
102 | // This pretty horrible, but `Debug` is the only way to inspect | ||
103 | // QueryDescriptor at the moment. | ||
104 | salsa::EventKind::WillExecute { descriptor } => Some(format!("{:?}", descriptor)), | ||
105 | _ => None, | ||
106 | }) | ||
107 | .collect() | ||
108 | } | ||
109 | } | ||
110 | |||
70 | salsa::database_storage! { | 111 | salsa::database_storage! { |
71 | pub(crate) struct RootDatabaseStorage for RootDatabase { | 112 | pub(crate) struct RootDatabaseStorage for RootDatabase { |
72 | impl crate::input::FilesDatabase { | 113 | impl crate::input::FilesDatabase { |
diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs index 4c555421d..648ec5e43 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs | |||
@@ -358,7 +358,8 @@ where | |||
358 | #[cfg(test)] | 358 | #[cfg(test)] |
359 | mod tests { | 359 | mod tests { |
360 | use crate::{ | 360 | use crate::{ |
361 | mock_analysis::analysis_and_position, | 361 | AnalysisChange, |
362 | mock_analysis::{MockAnalysis, analysis_and_position}, | ||
362 | descriptors::{DescriptorDatabase, module::ModuleDescriptor}, | 363 | descriptors::{DescriptorDatabase, module::ModuleDescriptor}, |
363 | input::FilesDatabase, | 364 | input::FilesDatabase, |
364 | }; | 365 | }; |
@@ -396,4 +397,65 @@ mod tests { | |||
396 | let resolution = &item_map.per_module[&module_id].items[&name]; | 397 | let resolution = &item_map.per_module[&module_id].items[&name]; |
397 | assert!(resolution.def_id.is_some()); | 398 | assert!(resolution.def_id.is_some()); |
398 | } | 399 | } |
400 | |||
401 | #[test] | ||
402 | fn typing_inside_a_function_should_not_invalidate_item_map() { | ||
403 | let mock_analysis = MockAnalysis::with_files( | ||
404 | " | ||
405 | //- /lib.rs | ||
406 | mod foo; | ||
407 | |||
408 | use crate::foo::bar::Baz; | ||
409 | |||
410 | fn foo() -> i32 { | ||
411 | 1 + 1 | ||
412 | } | ||
413 | //- /foo/mod.rs | ||
414 | pub mod bar; | ||
415 | |||
416 | //- /foo/bar.rs | ||
417 | pub struct Baz; | ||
418 | ", | ||
419 | ); | ||
420 | |||
421 | let file_id = mock_analysis.id_of("/lib.rs"); | ||
422 | let mut host = mock_analysis.analysis_host(); | ||
423 | |||
424 | let source_root = host.analysis().imp.db.file_source_root(file_id); | ||
425 | |||
426 | { | ||
427 | let db = host.analysis().imp.db; | ||
428 | let events = db.log_executed(|| { | ||
429 | db._item_map(source_root).unwrap(); | ||
430 | }); | ||
431 | assert!(format!("{:?}", events).contains("_item_map")) | ||
432 | } | ||
433 | |||
434 | let mut change = AnalysisChange::new(); | ||
435 | |||
436 | change.change_file( | ||
437 | file_id, | ||
438 | " | ||
439 | mod foo; | ||
440 | |||
441 | use crate::foo::bar::Baz; | ||
442 | |||
443 | fn foo() -> i32 { 92 } | ||
444 | " | ||
445 | .to_string(), | ||
446 | ); | ||
447 | |||
448 | host.apply_change(change); | ||
449 | |||
450 | { | ||
451 | let db = host.analysis().imp.db; | ||
452 | let events = db.log_executed(|| { | ||
453 | db._item_map(source_root).unwrap(); | ||
454 | }); | ||
455 | // assert!( | ||
456 | // !format!("{:?}", events).contains("_item_map"), | ||
457 | // "{:#?}", events | ||
458 | // ) | ||
459 | } | ||
460 | } | ||
399 | } | 461 | } |