From 22b412f1a9d245cc3d3774dab9408e3a39a52025 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Mon, 30 Dec 2019 14:25:19 +0100 Subject: find_path WIP --- crates/ra_hir_def/src/find_path.rs | 44 ++++++++++++++++++++++++++++++++++++++ crates/ra_hir_def/src/lib.rs | 1 + crates/ra_hir_def/src/test_db.rs | 13 +++++++++++ 3 files changed, 58 insertions(+) create mode 100644 crates/ra_hir_def/src/find_path.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/find_path.rs b/crates/ra_hir_def/src/find_path.rs new file mode 100644 index 000000000..1ddf5fca6 --- /dev/null +++ b/crates/ra_hir_def/src/find_path.rs @@ -0,0 +1,44 @@ +//! An algorithm to find a path to refer to a certain item. + +use crate::{ModuleDefId, path::ModPath, ModuleId}; + +pub fn find_path(item: ModuleDefId, from: ModuleId) -> ModPath { + todo!() +} + +#[cfg(test)] +mod tests { + use super::*; + use ra_db::{fixture::WithFixture, SourceDatabase}; + use crate::{db::DefDatabase, test_db::TestDB}; + use ra_syntax::ast::AstNode; + use hir_expand::hygiene::Hygiene; + + /// `code` needs to contain a cursor marker; checks that `find_path` for the + /// item the `path` refers to returns that same path when called from the + /// module the cursor is in. + fn check_found_path(code: &str, path: &str) { + let (db, pos) = TestDB::with_position(code); + let module = db.module_for_file(pos.file_id); + let parsed_path_file = ra_syntax::SourceFile::parse(&format!("use {};", path)); + let ast_path = parsed_path_file.syntax_node().descendants().find_map(ra_syntax::ast::Path::cast).unwrap(); + let mod_path = ModPath::from_src(ast_path, &Hygiene::new_unhygienic()).unwrap(); + + let crate_def_map = db.crate_def_map(module.krate); + let resolved = crate_def_map.resolve_path(&db, module.local_id, &mod_path, crate::item_scope::BuiltinShadowMode::Module).0.take_types().unwrap(); + + let found_path = find_path(resolved, module); + + assert_eq!(mod_path, found_path); + } + + #[test] + fn same_module() { + let code = r#" +//- /main.rs +struct S; +<|> +"#; + check_found_path(code, "S"); + } +} diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 61f044ecf..ebc12e891 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -37,6 +37,7 @@ pub mod src; pub mod child_by_source; pub mod visibility; +pub mod find_path; #[cfg(test)] mod test_db; diff --git a/crates/ra_hir_def/src/test_db.rs b/crates/ra_hir_def/src/test_db.rs index 54e3a84bd..a403f183f 100644 --- a/crates/ra_hir_def/src/test_db.rs +++ b/crates/ra_hir_def/src/test_db.rs @@ -6,6 +6,7 @@ use std::{ }; use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath}; +use crate::db::DefDatabase; #[salsa::database( ra_db::SourceDatabaseExtStorage, @@ -54,6 +55,18 @@ impl FileLoader for TestDB { } impl TestDB { + pub fn module_for_file(&self, file_id: FileId) -> crate::ModuleId { + for &krate in self.relevant_crates(file_id).iter() { + let crate_def_map = self.crate_def_map(krate); + for (local_id, data) in crate_def_map.modules.iter() { + if data.origin.file_id() == Some(file_id) { + return crate::ModuleId { krate, local_id }; + } + } + } + panic!("Can't find module for file") + } + pub fn log(&self, f: impl FnOnce()) -> Vec> { *self.events.lock().unwrap() = Some(Vec::new()); f(); -- cgit v1.2.3