From cb6205c09da9fd6fc0bd9f88106f5e9bd3f471aa Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 17:22:48 +0300 Subject: use relpaths for module resolve --- crates/ra_hir/src/module/imp.rs | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index 4a19842c4..d04d24a61 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs @@ -4,9 +4,9 @@ use ra_syntax::{ ast::{self, NameOwner}, SmolStr, }; -use relative_path::RelativePathBuf; use rustc_hash::{FxHashMap, FxHashSet}; -use ra_db::{SourceRoot, SourceRootId, FileResolverImp, Cancelable, FileId,}; +use arrayvec::ArrayVec; +use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; use crate::{ HirDatabase, @@ -110,8 +110,7 @@ fn build_subtree( let (points_to, problem) = match sub { Submodule::Declaration(name) => { - let (points_to, problem) = - resolve_submodule(source, &name, &source_root.file_resolver); + let (points_to, problem) = resolve_submodule(db, source, &name); let points_to = points_to .into_iter() .map(|file_id| match roots.remove(&file_id) { @@ -153,30 +152,32 @@ fn build_subtree( } fn resolve_submodule( + db: &impl HirDatabase, source: ModuleSource, name: &SmolStr, - file_resolver: &FileResolverImp, ) -> (Vec, Option) { - // TODO: handle submodules of inline modules properly + // FIXME: handle submodules of inline modules properly let file_id = source.file_id(); - let mod_name = file_resolver.file_stem(file_id); + let source_root_id = db.file_source_root(file_id); + let path = db.file_relative_path(file_id); + let dir_path = path.parent().unwrap(); + let mod_name = path.file_stem().unwrap_or("unknown"); let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; - let file_mod = RelativePathBuf::from(format!("../{}.rs", name)); - let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name)); - let file_dir_mod = RelativePathBuf::from(format!("../{}/{}.rs", mod_name, name)); - let tmp1; - let tmp2; - let candidates = if is_dir_owner { - tmp1 = [&file_mod, &dir_mod]; - tmp1.iter() + let file_mod = dir_path.join(format!("{}.rs", name)); + let dir_mod = dir_path.join(format!("{}/mod.rs", name)); + let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name)); + let mut candidates = ArrayVec::<[_; 2]>::new(); + if is_dir_owner { + candidates.push(file_mod.clone()); + candidates.push(dir_mod); } else { - tmp2 = [&file_dir_mod]; - tmp2.iter() + candidates.push(file_dir_mod.clone()); }; let points_to = candidates - .filter_map(|path| file_resolver.resolve(file_id, path)) + .into_iter() + .filter_map(|path| db.source_root_file_by_path(source_root_id, path)) .collect::>(); let problem = if points_to.is_empty() { Some(Problem::UnresolvedModule { -- cgit v1.2.3 From 85290bc1342560d5560f0b2151cff1c0c6dac155 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 12:20:54 +0300 Subject: switch analysis to vfs --- crates/ra_hir/src/module/imp.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index d04d24a61..f3a346152 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs @@ -4,6 +4,7 @@ use ra_syntax::{ ast::{self, NameOwner}, SmolStr, }; +use relative_path::{RelativePathBuf, RelativePath}; use rustc_hash::{FxHashMap, FxHashSet}; use arrayvec::ArrayVec; use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; @@ -65,7 +66,7 @@ fn create_module_tree<'a>( let mut visited = FxHashSet::default(); let source_root = db.source_root(source_root); - for &file_id in source_root.files.iter() { + for &file_id in source_root.files.values() { let source = ModuleSource::new_file(file_id); if visited.contains(&source) { continue; // TODO: use explicit crate_roots here @@ -160,7 +161,8 @@ fn resolve_submodule( let file_id = source.file_id(); let source_root_id = db.file_source_root(file_id); let path = db.file_relative_path(file_id); - let dir_path = path.parent().unwrap(); + let root = RelativePathBuf::default(); + let dir_path = path.parent().unwrap_or(&root); let mod_name = path.file_stem().unwrap_or("unknown"); let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; @@ -174,14 +176,19 @@ fn resolve_submodule( } else { candidates.push(file_dir_mod.clone()); }; - + let sr = db.source_root(source_root_id); let points_to = candidates .into_iter() - .filter_map(|path| db.source_root_file_by_path(source_root_id, path)) + .filter_map(|path| sr.files.get(&path)) + .map(|&it| it) .collect::>(); let problem = if points_to.is_empty() { Some(Problem::UnresolvedModule { - candidate: if is_dir_owner { file_mod } else { file_dir_mod }, + candidate: RelativePath::new("../").join(&if is_dir_owner { + file_mod + } else { + file_dir_mod + }), }) } else { None -- cgit v1.2.3 From 26dcc70129399cadfd985f86bbad8d5127f8a3a0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 12:40:41 +0300 Subject: fix hir mock --- crates/ra_hir/src/mock.rs | 35 +++++++++++++++++-------------- crates/ra_hir/src/module/nameres/tests.rs | 7 ++++--- 2 files changed, 23 insertions(+), 19 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index b7193c4f3..54260101c 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use parking_lot::Mutex; use salsa::{self, Database}; -use ra_db::{LocationIntener, BaseDatabase, FilePosition, mock::FileMap, FileId, WORKSPACE, CrateGraph}; +use ra_db::{LocationIntener, BaseDatabase, FilePosition, FileId, WORKSPACE, CrateGraph, SourceRoot}; use relative_path::RelativePathBuf; use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; @@ -16,10 +16,10 @@ pub(crate) struct MockDatabase { } impl MockDatabase { - pub(crate) fn with_files(fixture: &str) -> (MockDatabase, FileMap) { - let (db, file_map, position) = MockDatabase::from_fixture(fixture); + pub(crate) fn with_files(fixture: &str) -> (MockDatabase, SourceRoot) { + let (db, source_root, position) = MockDatabase::from_fixture(fixture); assert!(position.is_none()); - (db, file_map) + (db, source_root) } pub(crate) fn with_position(fixture: &str) -> (MockDatabase, FilePosition) { @@ -33,48 +33,50 @@ impl MockDatabase { .set((), Arc::new(crate_graph)); } - fn from_fixture(fixture: &str) -> (MockDatabase, FileMap, Option) { + fn from_fixture(fixture: &str) -> (MockDatabase, SourceRoot, Option) { let mut db = MockDatabase::default(); let mut position = None; - let mut file_map = FileMap::default(); + let mut source_root = SourceRoot::default(); for entry in parse_fixture(fixture) { if entry.text.contains(CURSOR_MARKER) { assert!( position.is_none(), "only one marker (<|>) per fixture is allowed" ); - position = Some(db.add_file_with_position(&mut file_map, &entry.meta, &entry.text)); + position = + Some(db.add_file_with_position(&mut source_root, &entry.meta, &entry.text)); } else { - db.add_file(&mut file_map, &entry.meta, &entry.text); + db.add_file(&mut source_root, &entry.meta, &entry.text); } } - let source_root = file_map.clone().into_source_root(); db.query_mut(ra_db::SourceRootQuery) - .set(WORKSPACE, Arc::new(source_root)); - (db, file_map, position) + .set(WORKSPACE, Arc::new(source_root.clone())); + (db, source_root, position) } - fn add_file(&mut self, file_map: &mut FileMap, path: &str, text: &str) -> FileId { + fn add_file(&mut self, source_root: &mut SourceRoot, path: &str, text: &str) -> FileId { assert!(path.starts_with('/')); let path = RelativePathBuf::from_path(&path[1..]).unwrap(); - - let file_id = file_map.add(path); + let file_id = FileId(source_root.files.len() as u32); let text = Arc::new(text.to_string()); self.query_mut(ra_db::FileTextQuery).set(file_id, text); + self.query_mut(ra_db::FileRelativePathQuery) + .set(file_id, path.clone()); self.query_mut(ra_db::FileSourceRootQuery) .set(file_id, WORKSPACE); + source_root.files.insert(path, file_id); file_id } fn add_file_with_position( &mut self, - file_map: &mut FileMap, + source_root: &mut SourceRoot, path: &str, text: &str, ) -> FilePosition { let (offset, text) = extract_offset(text); - let file_id = self.add_file(file_map, path, &text); + let file_id = self.add_file(source_root, path, &text); FilePosition { file_id, offset } } } @@ -158,6 +160,7 @@ salsa::database_storage! { pub(crate) struct MockDatabaseStorage for MockDatabase { impl ra_db::FilesDatabase { fn file_text() for ra_db::FileTextQuery; + fn file_relative_path() for ra_db::FileRelativePathQuery; fn file_source_root() for ra_db::FileSourceRootQuery; fn source_root() for ra_db::SourceRootQuery; fn libraries() for ra_db::LibrariesQuery; diff --git a/crates/ra_hir/src/module/nameres/tests.rs b/crates/ra_hir/src/module/nameres/tests.rs index 9ddc32dcd..9fa9146e3 100644 --- a/crates/ra_hir/src/module/nameres/tests.rs +++ b/crates/ra_hir/src/module/nameres/tests.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use salsa::Database; use ra_db::{FilesDatabase, CrateGraph}; use ra_syntax::SmolStr; +use relative_path::RelativePath; use crate::{ self as hir, @@ -44,7 +45,7 @@ fn item_map_smoke_test() { #[test] fn item_map_across_crates() { - let (mut db, files) = MockDatabase::with_files( + let (mut db, sr) = MockDatabase::with_files( " //- /main.rs use test_crate::Baz; @@ -53,8 +54,8 @@ fn item_map_across_crates() { pub struct Baz; ", ); - let main_id = files.file_id("/main.rs"); - let lib_id = files.file_id("/lib.rs"); + let main_id = sr.files[RelativePath::new("/main.rs")]; + let lib_id = sr.files[RelativePath::new("/lib.rs")]; let mut crate_graph = CrateGraph::default(); let main_crate = crate_graph.add_crate_root(main_id); -- cgit v1.2.3 From 2fe41574a1695a6608d738f40ec51bc61fc7604a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 16:19:53 +0300 Subject: fix tests --- crates/ra_hir/src/mock.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 54260101c..9423e6571 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs @@ -2,12 +2,14 @@ use std::sync::Arc; use parking_lot::Mutex; use salsa::{self, Database}; -use ra_db::{LocationIntener, BaseDatabase, FilePosition, FileId, WORKSPACE, CrateGraph, SourceRoot}; +use ra_db::{LocationIntener, BaseDatabase, FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId}; use relative_path::RelativePathBuf; use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; use crate::{db, DefId, DefLoc}; +const WORKSPACE: SourceRootId = SourceRootId(0); + #[derive(Debug)] pub(crate) struct MockDatabase { events: Mutex>>>, @@ -106,11 +108,11 @@ impl Default for MockDatabase { runtime: salsa::Runtime::default(), id_maps: Default::default(), }; - db.query_mut(ra_db::SourceRootQuery) - .set(ra_db::WORKSPACE, Default::default()); db.query_mut(ra_db::CrateGraphQuery) .set((), Default::default()); - db.query_mut(ra_db::LibrariesQuery) + db.query_mut(ra_db::LocalRootsQuery) + .set((), Default::default()); + db.query_mut(ra_db::LibraryRootsQuery) .set((), Default::default()); db } @@ -163,7 +165,8 @@ salsa::database_storage! { fn file_relative_path() for ra_db::FileRelativePathQuery; fn file_source_root() for ra_db::FileSourceRootQuery; fn source_root() for ra_db::SourceRootQuery; - fn libraries() for ra_db::LibrariesQuery; + fn local_roots() for ra_db::LocalRootsQuery; + fn library_roots() for ra_db::LibraryRootsQuery; fn crate_graph() for ra_db::CrateGraphQuery; } impl ra_db::SyntaxDatabase { -- cgit v1.2.3 From 590bd5f849cf257f499f6c7aa8da3dc4ffc7578f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 18:04:17 +0300 Subject: workaround across-crate resolve bugs --- crates/ra_hir/src/module/nameres.rs | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 5540b827f..dc05c7112 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs @@ -252,7 +252,8 @@ where let krate = Crate::new(crate_id); for dep in krate.dependencies(self.db) { if let Some(module) = dep.krate.root_module(self.db)? { - self.add_module_item(&mut module_items, dep.name, module.module_id); + let def_id = module.def_id(self.db); + self.add_module_item(&mut module_items, dep.name, def_id); } } }; @@ -294,21 +295,21 @@ where // Populate modules for (name, module_id) in module_id.children(&self.module_tree) { - self.add_module_item(&mut module_items, name, module_id); + let def_loc = DefLoc { + kind: DefKind::Module, + source_root_id: self.source_root, + module_id, + source_item_id: module_id.source(&self.module_tree).0, + }; + let def_id = def_loc.id(self.db); + self.add_module_item(&mut module_items, name, def_id); } self.result.per_module.insert(module_id, module_items); Ok(()) } - fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, module_id: ModuleId) { - let def_loc = DefLoc { - kind: DefKind::Module, - source_root_id: self.source_root, - module_id, - source_item_id: module_id.source(&self.module_tree).0, - }; - let def_id = def_loc.id(self.db); + fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, def_id: DefId) { let resolution = Resolution { def_id: Some(def_id), import: None, @@ -329,7 +330,7 @@ where ImportKind::Named(ptr) => ptr, }; - let mut curr = match import.path.kind { + let mut curr: ModuleId = match import.path.kind { PathKind::Plain | PathKind::Self_ => module_id, PathKind::Super => { match module_id.parent(&self.module_tree) { @@ -357,8 +358,16 @@ where DefLoc { kind: DefKind::Module, module_id, + source_root_id, .. - } => module_id, + } => { + if source_root_id == self.source_root { + module_id + } else { + // FIXME: across crates resolve + return Ok(()); + } + } _ => return Ok(()), } } else { -- cgit v1.2.3 From 2caac99ef3731b39c484a23cdab00af94de7b645 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 00:57:13 +0300 Subject: resolve paths across crates --- crates/ra_hir/src/module/nameres.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index dc05c7112..4161442b2 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs @@ -32,7 +32,7 @@ use crate::{ SourceItemId, SourceFileItemId, SourceFileItems, Path, PathKind, HirDatabase, Crate, - module::{ModuleId, ModuleTree}, + module::{Module, ModuleId, ModuleTree}, }; /// Item map is the result of the name resolution. Item map contains, for each @@ -357,14 +357,27 @@ where curr = match def_id.loc(self.db) { DefLoc { kind: DefKind::Module, - module_id, + module_id: target_module_id, source_root_id, .. } => { if source_root_id == self.source_root { - module_id + target_module_id } else { - // FIXME: across crates resolve + let module = Module::new(self.db, source_root_id, target_module_id)?; + let path = Path { + segments: import.path.segments[i + 1..].iter().cloned().collect(), + kind: PathKind::Crate, + }; + if let Some(def_id) = module.resolve_path(self.db, path)? { + self.update(module_id, |items| { + let res = Resolution { + def_id: Some(def_id), + import: Some(ptr), + }; + items.items.insert(name.clone(), res); + }) + } return Ok(()); } } -- cgit v1.2.3 From 2d4582bfc648fd1a1ce92ea677aeb1c82ee8a631 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 01:00:54 +0300 Subject: fixme comment --- crates/ra_hir/src/module/nameres.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 4161442b2..f44abc730 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs @@ -37,6 +37,7 @@ use crate::{ /// Item map is the result of the name resolution. Item map contains, for each /// module, the set of visible items. +// FIXME: currenty we compute item map per source-root. We should do it per crate instead. #[derive(Default, Debug, PartialEq, Eq)] pub struct ItemMap { pub per_module: FxHashMap, -- cgit v1.2.3