diff options
author | Kirill Bulatov <[email protected]> | 2021-02-21 22:51:13 +0000 |
---|---|---|
committer | Kirill Bulatov <[email protected]> | 2021-03-08 21:58:33 +0000 |
commit | c395c3311dc2ac59251e86eaa6b86b597358d31f (patch) | |
tree | d35715eecb794064bea787333cada1804aacfeac /crates/ide_db/src/helpers | |
parent | f08c0cdd2a99d2851d472d2c6b3f54d37aa13e8a (diff) |
Filter out path items by the qualifier
Diffstat (limited to 'crates/ide_db/src/helpers')
-rw-r--r-- | crates/ide_db/src/helpers/import_assets.rs | 39 |
1 files changed, 15 insertions, 24 deletions
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs index 66e60b698..976dc92fb 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | //! Look up accessible paths for items. | 1 | //! Look up accessible paths for items. |
2 | use either::Either; | 2 | use either::Either; |
3 | use hir::{ | 3 | use hir::{ |
4 | AsAssocItem, AssocItem, Crate, ItemInNs, MacroDef, ModPath, Module, ModuleDef, PathResolution, | 4 | AsAssocItem, AssocItem, Crate, ItemInNs, MacroDef, ModPath, Module, ModuleDef, PrefixKind, |
5 | PrefixKind, Semantics, | 5 | Semantics, |
6 | }; | 6 | }; |
7 | use rustc_hash::FxHashSet; | 7 | use rustc_hash::FxHashSet; |
8 | use syntax::{ast, AstNode}; | 8 | use syntax::{ast, AstNode}; |
@@ -192,7 +192,7 @@ impl ImportAssets { | |||
192 | let db = sema.db; | 192 | let db = sema.db; |
193 | 193 | ||
194 | match &self.import_candidate { | 194 | match &self.import_candidate { |
195 | ImportCandidate::Path(path_candidate) => Box::new(path_applicable_defs( | 195 | ImportCandidate::Path(path_candidate) => Box::new(path_applicable_items( |
196 | sema, | 196 | sema, |
197 | path_candidate, | 197 | path_candidate, |
198 | unfiltered_defs | 198 | unfiltered_defs |
@@ -223,37 +223,28 @@ impl ImportAssets { | |||
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ||
226 | fn path_applicable_defs<'a>( | 226 | fn path_applicable_items<'a>( |
227 | sema: &'a Semantics<RootDatabase>, | 227 | sema: &'a Semantics<RootDatabase>, |
228 | path_candidate: &PathImportCandidate, | 228 | path_candidate: &PathImportCandidate, |
229 | unfiltered_defs: impl Iterator<Item = (ModPath, ItemInNs)> + 'a, | 229 | unfiltered_defs: impl Iterator<Item = (ModPath, ItemInNs)> + 'a, |
230 | ) -> impl Iterator<Item = (ModPath, ItemInNs)> + 'a { | 230 | ) -> Box<dyn Iterator<Item = (ModPath, ItemInNs)> + 'a> { |
231 | let unresolved_qualifier = match &path_candidate.unresolved_qualifier { | 231 | let unresolved_qualifier = match &path_candidate.unresolved_qualifier { |
232 | Some(qualifier) => qualifier, | 232 | Some(qualifier) => qualifier, |
233 | None => { | 233 | None => { |
234 | return unfiltered_defs; | 234 | return Box::new(unfiltered_defs); |
235 | } | 235 | } |
236 | }; | 236 | }; |
237 | 237 | ||
238 | // TODO kb filter out items: found path should end with `qualifier::Name` or `qualifier::Something` for fuzzy search case. | 238 | let qualifier_string = unresolved_qualifier.to_string(); |
239 | Box::new(unfiltered_defs.filter(move |(candidate_path, _)| { | ||
240 | let mut candidate_qualifier = candidate_path.clone(); | ||
241 | candidate_qualifier.pop_segment(); | ||
239 | 242 | ||
240 | // TODO kb find a way to turn a qualifier into the corresponding ModuleDef. Maybe through the unfiltered data? | 243 | // TODO kb |
241 | if let Some(qualifier_start_resolution) = resolve_qualifier_start(sema, unresolved_qualifier) { | 244 | // * take 1st segment of `unresolved_qualifier` and return it instead of the original `ItemInNs` |
242 | // TODO kb ascend until an unresolved segment part appears | 245 | // * Update `ModPath`: pop until 1st segment of `unresolved_qualifier` reached (do not rely on name comparison, nested mod names can repeat) |
243 | } else { | 246 | candidate_qualifier.to_string().ends_with(&qualifier_string) |
244 | // first segment is already unresolved, need to turn it into ModuleDef somehow | 247 | })) |
245 | } | ||
246 | |||
247 | return unfiltered_defs; | ||
248 | } | ||
249 | |||
250 | fn resolve_qualifier_start( | ||
251 | sema: &Semantics<RootDatabase>, | ||
252 | qualifier: &ast::Path, | ||
253 | ) -> Option<PathResolution> { | ||
254 | let qualifier_start = qualifier.syntax().descendants().find_map(ast::NameRef::cast)?; | ||
255 | let qualifier_start_path = qualifier_start.syntax().ancestors().find_map(ast::Path::cast)?; | ||
256 | sema.resolve_path(&qualifier_start_path) | ||
257 | } | 248 | } |
258 | 249 | ||
259 | fn trait_applicable_defs<'a>( | 250 | fn trait_applicable_defs<'a>( |