diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 9584875410..f49e7f909b 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -214,6 +214,13 @@ impl ModuleId { .find(|it| it.name == name)?; Some(*link.points_to.first()?) } + fn children<'a>(self, tree: &'a ModuleTree) -> impl Iterator + 'a { + tree.module(self).children.iter().filter_map(move |&it| { + let link = tree.link(it); + let module = *link.points_to.first()?; + Some((link.name.clone(), module)) + }) + } fn problems(self, tree: &ModuleTree, db: &impl SyntaxDatabase) -> Vec<(SyntaxNode, Problem)> { tree.module(self) .children diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs index 18e8342b34..6ff8e61f55 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs @@ -1,15 +1,21 @@ //! Name resolution algorithm +use std::sync::Arc; + use rustc_hash::FxHashMap; use ra_syntax::{ - SmolStr, SyntaxKind, + SmolStr, SyntaxKind::{self, *}, ast::{self, NameOwner, AstNode} }; use crate::{ - loc2id::DefId, - descriptors::module::ModuleId, - syntax_ptr::LocalSyntaxPtr, + loc2id::{DefId, DefLoc}, + descriptors::{ + DescriptorDatabase, + module::{ModuleId, ModuleTree}, + }, + syntax_ptr::{LocalSyntaxPtr, SyntaxPtr}, + input::SourceRootId, }; /// A set of items and imports declared inside a module, without relation to @@ -44,9 +50,9 @@ struct ItemMap { per_module: FxHashMap, } -#[derive(Debug)] +#[derive(Debug, Default)] struct ModuleItems { - items: FxHashMap>, + items: FxHashMap, import_resolutions: FxHashMap, } @@ -201,13 +207,61 @@ impl ModuleItem { } } -struct Resolver { +struct Resolver<'a, DB> { + db: &'a DB, + source_root: SourceRootId, + module_tree: Arc, input: FxHashMap, - result: ModuleItems, + result: ItemMap, } -impl Resolver { - fn resolve(&mut self){ - +impl<'a, DB> Resolver<'a, DB> +where + DB: DescriptorDatabase, +{ + fn resolve(&mut self) { + for (&module_id, items) in self.input.iter() { + populate_module( + self.db, + self.source_root, + &*self.module_tree, + &mut self.result, + module_id, + items, + ) + } } } + +fn populate_module( + db: &impl DescriptorDatabase, + source_root: SourceRootId, + module_tree: &ModuleTree, + item_map: &mut ItemMap, + module_id: ModuleId, + input: &InputModuleItems, +) { + let file_id = module_id.source(module_tree).file_id(); + + let mut module_items = ModuleItems::default(); + + for item in input.items.iter() { + if item.kind == MODULE { + // handle submodules separatelly + continue; + } + let ptr = item.ptr.into_global(file_id); + let def_loc = DefLoc::Item { ptr }; + let def_id = db.id_maps().def_id(def_loc); + module_items.items.insert(item.name.clone(), def_id); + } + + for (name, mod_id) in module_id.children(module_tree) { + let def_loc = DefLoc::Module { + id: mod_id, + source_root, + }; + } + + item_map.per_module.insert(module_id, module_items); +} diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs index 87417df94b..e4b55f9b0a 100644 --- a/crates/ra_analysis/src/loc2id.rs +++ b/crates/ra_analysis/src/loc2id.rs @@ -96,14 +96,14 @@ pub(crate) struct DefId(u32); impl_numeric_id!(DefId); #[derive(Clone, Debug, PartialEq, Eq, Hash)] -enum DefLoc { +pub(crate) enum DefLoc { Module { id: ModuleId, source_root: SourceRootId, }, Item { ptr: SyntaxPtr, - } + }, } pub(crate) trait IdDatabase: salsa::Database { @@ -122,6 +122,13 @@ impl IdMaps { pub(crate) fn fn_ptr(&self, fn_id: FnId) -> SyntaxPtr { self.inner.fns.lock().id2loc(fn_id) } + + pub(crate) fn def_id(&self, loc: DefLoc) -> DefId { + self.inner.defs.lock().loc2id(&loc) + } + pub(crate) fn def_loc(&self, def_id: DefId) -> DefLoc { + self.inner.defs.lock().id2loc(def_id) + } } #[derive(Debug, Default)]