From e884ab05c216fc4a4a35d6267d08519dc5dda41d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 25 Jan 2019 10:15:10 +0300 Subject: write path resolution code only once --- crates/ra_hir/src/code_model_impl/module.rs | 63 ++--------------------------- crates/ra_hir/src/nameres.rs | 13 +++++- 2 files changed, 14 insertions(+), 62 deletions(-) (limited to 'crates/ra_hir') diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 6419d3934..a5b190384 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs @@ -3,7 +3,7 @@ use ra_syntax::{ast, SyntaxNode, TreeArc}; use crate::{ Module, ModuleSource, Problem, ModuleDef, - Crate, Name, Path, PathKind, PerNs, + Crate, Name, Path, PerNs, module_tree::ModuleId, nameres::{ModuleScope, lower::ImportId}, db::HirDatabase, @@ -97,65 +97,8 @@ impl Module { } pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs { - let mut curr_per_ns: PerNs = PerNs::types(match path.kind { - PathKind::Crate => self.crate_root(db).into(), - PathKind::Self_ | PathKind::Plain => self.clone().into(), - PathKind::Super => { - if let Some(p) = self.parent(db) { - p.into() - } else { - return PerNs::none(); - } - } - PathKind::Abs => { - // TODO: absolute use is not supported - return PerNs::none(); - } - }); - - for segment in path.segments.iter() { - let curr = match curr_per_ns.as_ref().take_types() { - Some(r) => r, - None => { - // we still have path segments left, but the path so far - // didn't resolve in the types namespace => no resolution - // (don't break here because curr_per_ns might contain - // something in the value namespace, and it would be wrong - // to return that) - return PerNs::none(); - } - }; - // resolve segment in curr - - curr_per_ns = match curr { - ModuleDef::Module(m) => { - let scope = m.scope(db); - match scope.get(&segment.name) { - Some(r) => r.def_id.clone(), - None => PerNs::none(), - } - } - ModuleDef::Enum(e) => { - // enum variant - let matching_variant = e - .variants(db) - .into_iter() - .find(|(n, _variant)| n == &segment.name); - - match matching_variant { - Some((_n, variant)) => PerNs::both(variant.into(), (*e).into()), - None => PerNs::none(), - } - } - _ => { - // could be an inherent method call in UFCS form - // (`Struct::method`), or some other kind of associated - // item... Which we currently don't handle (TODO) - PerNs::none() - } - }; - } - curr_per_ns + let item_map = db.item_map(self.krate); + item_map.resolve_path(db, *self, path) } pub(crate) fn problems_impl( diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 8c8494b46..0046dfebf 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -297,7 +297,7 @@ where }; let (def_id, reached_fixedpoint) = self.result - .resolve_path(self.db, original_module, &import.path); + .resolve_path_fp(self.db, original_module, &import.path); if reached_fixedpoint == ReachedFixedPoint::Yes { let last_segment = import.path.segments.last().unwrap(); @@ -331,10 +331,19 @@ enum ReachedFixedPoint { } impl ItemMap { + pub(crate) fn resolve_path( + &self, + db: &impl HirDatabase, + original_module: Module, + path: &Path, + ) -> PerNs { + self.resolve_path_fp(db, original_module, path).0 + } + // returns true if we are sure that additions to `ItemMap` wouldn't change // the result. That is, if we've reached fixed point at this particular // import. - fn resolve_path( + fn resolve_path_fp( &self, db: &impl HirDatabase, original_module: Module, -- cgit v1.2.3