Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/test_db.rs')
| -rw-r--r-- | crates/hir-def/src/test_db.rs | 134 |
1 files changed, 102 insertions, 32 deletions
diff --git a/crates/hir-def/src/test_db.rs b/crates/hir-def/src/test_db.rs index 54e6c1fd20..b6f08c0caf 100644 --- a/crates/hir-def/src/test_db.rs +++ b/crates/hir-def/src/test_db.rs @@ -3,10 +3,11 @@ use std::{fmt, panic, sync::Mutex}; use base_db::{ - ra_salsa::{self, Durability}, - AnchoredPath, CrateId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, + CrateId, FileSourceRootInput, FileText, RootQueryDb, SourceDatabase, SourceRoot, SourceRootId, + SourceRootInput, Upcast, }; use hir_expand::{db::ExpandDatabase, files::FilePosition, InFile}; +use salsa::{AsDynDatabase, Durability}; use span::{EditionedFileId, FileId}; use syntax::{algo, ast, AstNode}; use triomphe::Arc; @@ -18,43 +19,58 @@ use crate::{ LocalModuleId, Lookup, ModuleDefId, ModuleId, }; -#[ra_salsa::database( - base_db::SourceRootDatabaseStorage, - base_db::SourceDatabaseStorage, - hir_expand::db::ExpandDatabaseStorage, - crate::db::InternDatabaseStorage, - crate::db::DefDatabaseStorage -)] +#[salsa::db] +#[derive(Clone)] pub(crate) struct TestDB { - storage: ra_salsa::Storage<TestDB>, - events: Mutex<Option<Vec<ra_salsa::Event>>>, + storage: salsa::Storage<Self>, + files: Arc<base_db::Files>, + events: Arc<Mutex<Option<Vec<salsa::Event>>>>, } impl Default for TestDB { fn default() -> Self { - let mut this = Self { storage: Default::default(), events: Default::default() }; - this.setup_syntax_context_root(); + let mut this = Self { + storage: Default::default(), + events: Default::default(), + files: Default::default(), + }; this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); this } } impl Upcast<dyn ExpandDatabase> for TestDB { + #[inline] fn upcast(&self) -> &(dyn ExpandDatabase + 'static) { self } } impl Upcast<dyn DefDatabase> for TestDB { + #[inline] fn upcast(&self) -> &(dyn DefDatabase + 'static) { self } } -impl ra_salsa::Database for TestDB { - fn salsa_event(&self, event: ra_salsa::Event) { +impl Upcast<dyn RootQueryDb> for TestDB { + fn upcast(&self) -> &(dyn RootQueryDb + 'static) { + self + } +} + +impl Upcast<dyn SourceDatabase> for TestDB { + fn upcast(&self) -> &(dyn SourceDatabase + 'static) { + self + } +} + +#[salsa::db] +impl salsa::Database for TestDB { + fn salsa_event(&self, event: &dyn std::ops::Fn() -> salsa::Event) { let mut events = self.events.lock().unwrap(); if let Some(events) = &mut *events { + let event = event(); events.push(event); } } @@ -68,12 +84,54 @@ impl fmt::Debug for TestDB { impl panic::RefUnwindSafe for TestDB {} -impl FileLoader for TestDB { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option<FileId> { - FileLoaderDelegate(self).resolve_path(path) +#[salsa::db] +impl SourceDatabase for TestDB { + fn file_text(&self, file_id: base_db::FileId) -> FileText { + self.files.file_text(file_id) } - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { - FileLoaderDelegate(self).relevant_crates(file_id) + + fn set_file_text(&mut self, file_id: base_db::FileId, text: &str) { + let files = Arc::clone(&self.files); + files.set_file_text(self, file_id, text); + } + + fn set_file_text_with_durability( + &mut self, + file_id: base_db::FileId, + text: &str, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_text_with_durability(self, file_id, text, durability); + } + + /// Source root of the file. + fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput { + self.files.source_root(source_root_id) + } + + fn set_source_root_with_durability( + &mut self, + source_root_id: SourceRootId, + source_root: Arc<SourceRoot>, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_source_root_with_durability(self, source_root_id, source_root, durability); + } + + fn file_source_root(&self, id: base_db::FileId) -> FileSourceRootInput { + self.files.file_source_root(id) + } + + fn set_file_source_root_with_durability( + &mut self, + id: base_db::FileId, + source_root_id: SourceRootId, + durability: Durability, + ) { + let files = Arc::clone(&self.files); + files.set_file_source_root_with_durability(self, id, source_root_id, durability); } } @@ -92,8 +150,10 @@ impl TestDB { } pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId { + let db = <TestDB as Upcast<dyn DefDatabase>>::upcast(self); + for &krate in self.relevant_crates(file_id).iter() { - let crate_def_map = self.crate_def_map(krate); + let crate_def_map = db.crate_def_map(krate); for (local_id, data) in crate_def_map.modules() { if data.origin.file_id().map(EditionedFileId::file_id) == Some(file_id) { return crate_def_map.module_id(local_id); @@ -104,8 +164,10 @@ impl TestDB { } pub(crate) fn module_at_position(&self, position: FilePosition) -> ModuleId { + let db = <TestDB as Upcast<dyn DefDatabase>>::upcast(self); + let file_module = self.module_for_file(position.file_id.file_id()); - let mut def_map = file_module.def_map(self); + let mut def_map = file_module.def_map(db); let module = self.mod_at_position(&def_map, position); def_map = match self.block_at_position(&def_map, position) { @@ -128,10 +190,11 @@ impl TestDB { /// Finds the smallest/innermost module in `def_map` containing `position`. fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId { + let db = <TestDB as Upcast<dyn DefDatabase>>::upcast(self); let mut size = None; let mut res = DefMap::ROOT; for (module, data) in def_map.modules() { - let src = data.definition_source(self); + let src = data.definition_source(db); if src.file_id != position.file_id { continue; } @@ -167,17 +230,18 @@ impl TestDB { } fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option<Arc<DefMap>> { + let db = <TestDB as Upcast<dyn DefDatabase>>::upcast(self); // Find the smallest (innermost) function in `def_map` containing the cursor. let mut size = None; let mut fn_def = None; for (_, module) in def_map.modules() { - let file_id = module.definition_source(self).file_id; + let file_id = module.definition_source(db).file_id; if file_id != position.file_id { continue; } for decl in module.scope.declarations() { if let ModuleDefId::FunctionId(it) = decl { - let range = it.lookup(self).source(self).value.syntax().text_range(); + let range = it.lookup(db).source(db).value.syntax().text_range(); if !range.contains(position.offset) { continue; @@ -203,10 +267,13 @@ impl TestDB { // Find the innermost block expression that has a `DefMap`. let def_with_body = fn_def?.into(); - let (_, source_map) = self.body_with_source_map(def_with_body); - let scopes = self.expr_scopes(def_with_body); - let root = self.parse(position.file_id); + let source_map = db.body_with_source_map(def_with_body).1; + let scopes = db.expr_scopes(def_with_body); + + let editioned_file_id_wrapper = + base_db::EditionedFileId::new(db.as_dyn_database(), position.file_id); + let root = db.parse(editioned_file_id_wrapper); let scope_iter = algo::ancestors_at_offset(&root.syntax_node(), position.offset) .filter_map(|node| { let block = ast::BlockExpr::cast(node)?; @@ -223,7 +290,7 @@ impl TestDB { let mut containing_blocks = scopes.scope_chain(Some(scope)).filter_map(|scope| scopes.block(scope)); - if let Some(block) = containing_blocks.next().map(|block| self.block_def_map(block)) { + if let Some(block) = containing_blocks.next().map(|block| db.block_def_map(block)) { return Some(block); } } @@ -231,7 +298,7 @@ impl TestDB { None } - pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<ra_salsa::Event> { + pub(crate) fn log(&self, f: impl FnOnce()) -> Vec<salsa::Event> { *self.events.lock().unwrap() = Some(Vec::new()); f(); self.events.lock().unwrap().take().unwrap() @@ -244,8 +311,11 @@ impl TestDB { .filter_map(|e| match e.kind { // This is pretty horrible, but `Debug` is the only way to inspect // QueryDescriptor at the moment. - ra_salsa::EventKind::WillExecute { database_key } => { - Some(format!("{:?}", database_key.debug(self))) + salsa::EventKind::WillExecute { database_key } => { + let ingredient = self + .as_dyn_database() + .ingredient_debug_name(database_key.ingredient_index()); + Some(ingredient.to_string()) } _ => None, }) |