aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-01-25 07:15:10 +0000
committerAleksey Kladov <[email protected]>2019-01-25 07:15:10 +0000
commite884ab05c216fc4a4a35d6267d08519dc5dda41d (patch)
treeb947b2b74afb3950eaef87f85ee0107eb4847f8f
parent857c35ddb03ee5db97bbb4743dfeedeb3df350ec (diff)
write path resolution code only once
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs63
-rw-r--r--crates/ra_hir/src/nameres.rs13
-rw-r--r--crates/ra_ide_api/src/marks.rs4
3 files changed, 15 insertions, 65 deletions
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};
3 3
4use crate::{ 4use crate::{
5 Module, ModuleSource, Problem, ModuleDef, 5 Module, ModuleSource, Problem, ModuleDef,
6 Crate, Name, Path, PathKind, PerNs, 6 Crate, Name, Path, PerNs,
7 module_tree::ModuleId, 7 module_tree::ModuleId,
8 nameres::{ModuleScope, lower::ImportId}, 8 nameres::{ModuleScope, lower::ImportId},
9 db::HirDatabase, 9 db::HirDatabase,
@@ -97,65 +97,8 @@ impl Module {
97 } 97 }
98 98
99 pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> { 99 pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> {
100 let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind { 100 let item_map = db.item_map(self.krate);
101 PathKind::Crate => self.crate_root(db).into(), 101 item_map.resolve_path(db, *self, path)
102 PathKind::Self_ | PathKind::Plain => self.clone().into(),
103 PathKind::Super => {
104 if let Some(p) = self.parent(db) {
105 p.into()
106 } else {
107 return PerNs::none();
108 }
109 }
110 PathKind::Abs => {
111 // TODO: absolute use is not supported
112 return PerNs::none();
113 }
114 });
115
116 for segment in path.segments.iter() {
117 let curr = match curr_per_ns.as_ref().take_types() {
118 Some(r) => r,
119 None => {
120 // we still have path segments left, but the path so far
121 // didn't resolve in the types namespace => no resolution
122 // (don't break here because curr_per_ns might contain
123 // something in the value namespace, and it would be wrong
124 // to return that)
125 return PerNs::none();
126 }
127 };
128 // resolve segment in curr
129
130 curr_per_ns = match curr {
131 ModuleDef::Module(m) => {
132 let scope = m.scope(db);
133 match scope.get(&segment.name) {
134 Some(r) => r.def_id.clone(),
135 None => PerNs::none(),
136 }
137 }
138 ModuleDef::Enum(e) => {
139 // enum variant
140 let matching_variant = e
141 .variants(db)
142 .into_iter()
143 .find(|(n, _variant)| n == &segment.name);
144
145 match matching_variant {
146 Some((_n, variant)) => PerNs::both(variant.into(), (*e).into()),
147 None => PerNs::none(),
148 }
149 }
150 _ => {
151 // could be an inherent method call in UFCS form
152 // (`Struct::method`), or some other kind of associated
153 // item... Which we currently don't handle (TODO)
154 PerNs::none()
155 }
156 };
157 }
158 curr_per_ns
159 } 102 }
160 103
161 pub(crate) fn problems_impl( 104 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
297 }; 297 };
298 let (def_id, reached_fixedpoint) = 298 let (def_id, reached_fixedpoint) =
299 self.result 299 self.result
300 .resolve_path(self.db, original_module, &import.path); 300 .resolve_path_fp(self.db, original_module, &import.path);
301 301
302 if reached_fixedpoint == ReachedFixedPoint::Yes { 302 if reached_fixedpoint == ReachedFixedPoint::Yes {
303 let last_segment = import.path.segments.last().unwrap(); 303 let last_segment = import.path.segments.last().unwrap();
@@ -331,10 +331,19 @@ enum ReachedFixedPoint {
331} 331}
332 332
333impl ItemMap { 333impl ItemMap {
334 pub(crate) fn resolve_path(
335 &self,
336 db: &impl HirDatabase,
337 original_module: Module,
338 path: &Path,
339 ) -> PerNs<ModuleDef> {
340 self.resolve_path_fp(db, original_module, path).0
341 }
342
334 // returns true if we are sure that additions to `ItemMap` wouldn't change 343 // returns true if we are sure that additions to `ItemMap` wouldn't change
335 // the result. That is, if we've reached fixed point at this particular 344 // the result. That is, if we've reached fixed point at this particular
336 // import. 345 // import.
337 fn resolve_path( 346 fn resolve_path_fp(
338 &self, 347 &self,
339 db: &impl HirDatabase, 348 db: &impl HirDatabase,
340 original_module: Module, 349 original_module: Module,
diff --git a/crates/ra_ide_api/src/marks.rs b/crates/ra_ide_api/src/marks.rs
index b4a726ef0..dc5b2702a 100644
--- a/crates/ra_ide_api/src/marks.rs
+++ b/crates/ra_ide_api/src/marks.rs
@@ -1,3 +1 @@
1use test_utils::mark; test_utils::marks!(inserts_parens_for_function_calls);
2
3mark!(inserts_parens_for_function_calls);