diff options
Diffstat (limited to 'crates/ra_hir/src/code_model_impl')
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index e5394d440..73c212de8 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -95,7 +95,7 @@ impl Module { | |||
95 | } | 95 | } |
96 | 96 | ||
97 | /// Finds a child module with the specified name. | 97 | /// Finds a child module with the specified name. |
98 | pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { | 98 | pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { |
99 | let loc = self.def_id.loc(db); | 99 | let loc = self.def_id.loc(db); |
100 | let module_tree = db.module_tree(loc.source_root_id); | 100 | let module_tree = db.module_tree(loc.source_root_id); |
101 | let child_id = loc.module_id.child(&module_tree, name)?; | 101 | let child_id = loc.module_id.child(&module_tree, name)?; |
@@ -103,7 +103,7 @@ impl Module { | |||
103 | } | 103 | } |
104 | 104 | ||
105 | /// Iterates over all child modules. | 105 | /// Iterates over all child modules. |
106 | pub fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { | 106 | pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { |
107 | // FIXME this should be implementable without collecting into a vec, but | 107 | // FIXME this should be implementable without collecting into a vec, but |
108 | // it's kind of hard since the iterator needs to keep a reference to the | 108 | // it's kind of hard since the iterator needs to keep a reference to the |
109 | // module tree. | 109 | // module tree. |
@@ -117,7 +117,7 @@ impl Module { | |||
117 | children.into_iter() | 117 | children.into_iter() |
118 | } | 118 | } |
119 | 119 | ||
120 | pub fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { | 120 | pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { |
121 | let loc = self.def_id.loc(db); | 121 | let loc = self.def_id.loc(db); |
122 | let module_tree = db.module_tree(loc.source_root_id); | 122 | let module_tree = db.module_tree(loc.source_root_id); |
123 | let parent_id = loc.module_id.parent(&module_tree)?; | 123 | let parent_id = loc.module_id.parent(&module_tree)?; |
@@ -125,13 +125,13 @@ impl Module { | |||
125 | } | 125 | } |
126 | 126 | ||
127 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 127 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
128 | pub fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { | 128 | pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { |
129 | let loc = self.def_id.loc(db); | 129 | let loc = self.def_id.loc(db); |
130 | let item_map = db.item_map(loc.source_root_id); | 130 | let item_map = db.item_map(loc.source_root_id); |
131 | item_map.per_module[&loc.module_id].clone() | 131 | item_map.per_module[&loc.module_id].clone() |
132 | } | 132 | } |
133 | 133 | ||
134 | pub fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { | 134 | pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { |
135 | let mut curr_per_ns = PerNs::types( | 135 | let mut curr_per_ns = PerNs::types( |
136 | match path.kind { | 136 | match path.kind { |
137 | PathKind::Crate => self.crate_root(db), | 137 | PathKind::Crate => self.crate_root(db), |
@@ -147,47 +147,54 @@ impl Module { | |||
147 | .def_id, | 147 | .def_id, |
148 | ); | 148 | ); |
149 | 149 | ||
150 | let segments = &path.segments; | 150 | for segment in path.segments.iter() { |
151 | for (idx, name) in segments.iter().enumerate() { | 151 | let curr = match curr_per_ns.as_ref().take_types() { |
152 | let curr = if let Some(r) = curr_per_ns.as_ref().take_types() { | 152 | Some(r) => r, |
153 | r | 153 | None => { |
154 | } else { | 154 | // we still have path segments left, but the path so far |
155 | return PerNs::none(); | 155 | // didn't resolve in the types namespace => no resolution |
156 | // (don't break here because curr_per_ns might contain | ||
157 | // something in the value namespace, and it would be wrong | ||
158 | // to return that) | ||
159 | return PerNs::none(); | ||
160 | } | ||
156 | }; | 161 | }; |
157 | let module = match curr.resolve(db) { | 162 | // resolve segment in curr |
158 | Def::Module(it) => it, | 163 | curr_per_ns = match curr.resolve(db) { |
164 | Def::Module(m) => { | ||
165 | let scope = m.scope(db); | ||
166 | match scope.get(&segment.name) { | ||
167 | Some(r) => r.def_id, | ||
168 | None => PerNs::none(), | ||
169 | } | ||
170 | } | ||
159 | Def::Enum(e) => { | 171 | Def::Enum(e) => { |
160 | if segments.len() == idx + 1 { | 172 | // enum variant |
161 | // enum variant | 173 | let matching_variant = e |
162 | let matching_variant = | 174 | .variants(db) |
163 | e.variants(db).into_iter().find(|(n, _variant)| n == name); | 175 | .into_iter() |
164 | 176 | .find(|(n, _variant)| n == &segment.name); | |
165 | if let Some((_n, variant)) = matching_variant { | 177 | |
166 | return PerNs::both(variant.def_id(), e.def_id()); | 178 | match matching_variant { |
167 | } else { | 179 | Some((_n, variant)) => PerNs::both(variant.def_id(), e.def_id()), |
168 | return PerNs::none(); | 180 | None => PerNs::none(), |
169 | } | ||
170 | } else if segments.len() == idx { | ||
171 | // enum | ||
172 | return PerNs::types(e.def_id()); | ||
173 | } else { | ||
174 | // malformed enum? | ||
175 | return PerNs::none(); | ||
176 | } | 181 | } |
177 | } | 182 | } |
178 | _ => return PerNs::none(), | 183 | _ => { |
179 | }; | 184 | // could be an inherent method call in UFCS form |
180 | let scope = module.scope(db); | 185 | // (`Struct::method`), or some other kind of associated |
181 | curr_per_ns = if let Some(r) = scope.get(&name) { | 186 | // item... Which we currently don't handle (TODO) |
182 | r.def_id | 187 | PerNs::none() |
183 | } else { | 188 | } |
184 | return PerNs::none(); | ||
185 | }; | 189 | }; |
186 | } | 190 | } |
187 | curr_per_ns | 191 | curr_per_ns |
188 | } | 192 | } |
189 | 193 | ||
190 | pub fn problems_impl(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> { | 194 | pub(crate) fn problems_impl( |
195 | &self, | ||
196 | db: &impl HirDatabase, | ||
197 | ) -> Vec<(TreeArc<SyntaxNode>, Problem)> { | ||
191 | let loc = self.def_id.loc(db); | 198 | let loc = self.def_id.loc(db); |
192 | let module_tree = db.module_tree(loc.source_root_id); | 199 | let module_tree = db.module_tree(loc.source_root_id); |
193 | loc.module_id.problems(&module_tree, db) | 200 | loc.module_id.problems(&module_tree, db) |