From 955d2eea452b82f7286de902424d2cf5d4b78401 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 21 Nov 2018 20:44:05 +0300 Subject: add test loggin API to db --- crates/ra_analysis/src/db.rs | 41 ++++++++++++++ .../ra_analysis/src/descriptors/module/nameres.rs | 64 +++++++++++++++++++++- 2 files changed, 104 insertions(+), 1 deletion(-) (limited to 'crates') 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 @@ use std::sync::Arc; +use parking_lot::Mutex; use ra_editor::LineIndex; use ra_syntax::{SourceFileNode, SyntaxNode}; use salsa::{self, Database}; @@ -18,6 +19,11 @@ use crate::{ #[derive(Debug)] pub(crate) struct RootDatabase { + #[cfg(test)] + events: Mutex>>>, + #[cfg(not(test))] + events: (), + runtime: salsa::Runtime, id_maps: IdMaps, } @@ -26,11 +32,22 @@ impl salsa::Database for RootDatabase { fn salsa_runtime(&self) -> &salsa::Runtime { &self.runtime } + + fn salsa_event(&self, event: impl Fn() -> salsa::Event) { + #[cfg(test)] + { + let mut events = self.events.lock(); + if let Some(events) = &mut *events { + events.push(event()); + } + } + } } impl Default for RootDatabase { fn default() -> RootDatabase { let mut db = RootDatabase { + events: Default::default(), runtime: salsa::Runtime::default(), id_maps: IdMaps::default(), }; @@ -55,6 +72,7 @@ pub(crate) fn check_canceled(db: &impl salsa::Database) -> Cancelable<()> { impl salsa::ParallelDatabase for RootDatabase { fn snapshot(&self) -> salsa::Snapshot { salsa::Snapshot::new(RootDatabase { + events: Default::default(), runtime: self.runtime.snapshot(self), id_maps: self.id_maps.clone(), }) @@ -67,6 +85,29 @@ impl IdDatabase for RootDatabase { } } +#[cfg(test)] +impl RootDatabase { + pub(crate) fn log(&self, f: impl FnOnce()) -> Vec> { + *self.events.lock() = Some(Vec::new()); + f(); + let events = self.events.lock().take().unwrap(); + events + } + + pub(crate) fn log_executed(&self, f: impl FnOnce()) -> Vec { + let events = self.log(f); + events + .into_iter() + .filter_map(|e| match e.kind { + // This pretty horrible, but `Debug` is the only way to inspect + // QueryDescriptor at the moment. + salsa::EventKind::WillExecute { descriptor } => Some(format!("{:?}", descriptor)), + _ => None, + }) + .collect() + } +} + salsa::database_storage! { pub(crate) struct RootDatabaseStorage for RootDatabase { 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 #[cfg(test)] mod tests { use crate::{ - mock_analysis::analysis_and_position, + AnalysisChange, + mock_analysis::{MockAnalysis, analysis_and_position}, descriptors::{DescriptorDatabase, module::ModuleDescriptor}, input::FilesDatabase, }; @@ -396,4 +397,65 @@ mod tests { let resolution = &item_map.per_module[&module_id].items[&name]; assert!(resolution.def_id.is_some()); } + + #[test] + fn typing_inside_a_function_should_not_invalidate_item_map() { + let mock_analysis = MockAnalysis::with_files( + " + //- /lib.rs + mod foo; + + use crate::foo::bar::Baz; + + fn foo() -> i32 { + 1 + 1 + } + //- /foo/mod.rs + pub mod bar; + + //- /foo/bar.rs + pub struct Baz; + ", + ); + + let file_id = mock_analysis.id_of("/lib.rs"); + let mut host = mock_analysis.analysis_host(); + + let source_root = host.analysis().imp.db.file_source_root(file_id); + + { + let db = host.analysis().imp.db; + let events = db.log_executed(|| { + db._item_map(source_root).unwrap(); + }); + assert!(format!("{:?}", events).contains("_item_map")) + } + + let mut change = AnalysisChange::new(); + + change.change_file( + file_id, + " + mod foo; + + use crate::foo::bar::Baz; + + fn foo() -> i32 { 92 } + " + .to_string(), + ); + + host.apply_change(change); + + { + let db = host.analysis().imp.db; + let events = db.log_executed(|| { + db._item_map(source_root).unwrap(); + }); + // assert!( + // !format!("{:?}", events).contains("_item_map"), + // "{:#?}", events + // ) + } + } } -- cgit v1.2.3