diff options
Diffstat (limited to 'crates/ide_db/src/imports_locator.rs')
-rw-r--r-- | crates/ide_db/src/imports_locator.rs | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/crates/ide_db/src/imports_locator.rs b/crates/ide_db/src/imports_locator.rs index d111fba92..502e8281a 100644 --- a/crates/ide_db/src/imports_locator.rs +++ b/crates/ide_db/src/imports_locator.rs | |||
@@ -1,7 +1,10 @@ | |||
1 | //! This module contains an import search functionality that is provided to the assists module. | 1 | //! This module contains an import search functionality that is provided to the assists module. |
2 | //! Later, this should be moved away to a separate crate that is accessible from the assists module. | 2 | //! Later, this should be moved away to a separate crate that is accessible from the assists module. |
3 | 3 | ||
4 | use hir::{import_map, AsAssocItem, Crate, MacroDef, ModuleDef, Semantics}; | 4 | use hir::{ |
5 | import_map::{self, ImportKind}, | ||
6 | AsAssocItem, Crate, MacroDef, ModuleDef, Semantics, | ||
7 | }; | ||
5 | use syntax::{ast, AstNode, SyntaxKind::NAME}; | 8 | use syntax::{ast, AstNode, SyntaxKind::NAME}; |
6 | 9 | ||
7 | use crate::{ | 10 | use crate::{ |
@@ -12,69 +15,84 @@ use crate::{ | |||
12 | use either::Either; | 15 | use either::Either; |
13 | use rustc_hash::FxHashSet; | 16 | use rustc_hash::FxHashSet; |
14 | 17 | ||
15 | const QUERY_SEARCH_LIMIT: usize = 40; | 18 | pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40; |
16 | 19 | ||
17 | pub fn find_exact_imports<'a>( | 20 | pub fn find_exact_imports<'a>( |
18 | sema: &Semantics<'a, RootDatabase>, | 21 | sema: &Semantics<'a, RootDatabase>, |
19 | krate: Crate, | 22 | krate: Crate, |
20 | name_to_import: String, | 23 | name_to_import: String, |
21 | ) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> { | 24 | ) -> Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>>> { |
22 | let _p = profile::span("find_exact_imports"); | 25 | let _p = profile::span("find_exact_imports"); |
23 | find_imports( | 26 | Box::new(find_imports( |
24 | sema, | 27 | sema, |
25 | krate, | 28 | krate, |
26 | { | 29 | { |
27 | let mut local_query = symbol_index::Query::new(name_to_import.clone()); | 30 | let mut local_query = symbol_index::Query::new(name_to_import.clone()); |
28 | local_query.exact(); | 31 | local_query.exact(); |
29 | local_query.limit(QUERY_SEARCH_LIMIT); | 32 | local_query.limit(DEFAULT_QUERY_SEARCH_LIMIT); |
30 | local_query | 33 | local_query |
31 | }, | 34 | }, |
32 | import_map::Query::new(name_to_import) | 35 | import_map::Query::new(name_to_import) |
33 | .limit(QUERY_SEARCH_LIMIT) | 36 | .limit(DEFAULT_QUERY_SEARCH_LIMIT) |
34 | .name_only() | 37 | .name_only() |
35 | .search_mode(import_map::SearchMode::Equals) | 38 | .search_mode(import_map::SearchMode::Equals) |
36 | .case_sensitive(), | 39 | .case_sensitive(), |
37 | ) | 40 | )) |
41 | } | ||
42 | |||
43 | pub enum AssocItemSearch { | ||
44 | Include, | ||
45 | Exclude, | ||
46 | AssocItemsOnly, | ||
38 | } | 47 | } |
39 | 48 | ||
40 | pub fn find_similar_imports<'a>( | 49 | pub fn find_similar_imports<'a>( |
41 | sema: &Semantics<'a, RootDatabase>, | 50 | sema: &Semantics<'a, RootDatabase>, |
42 | krate: Crate, | 51 | krate: Crate, |
43 | limit: Option<usize>, | ||
44 | fuzzy_search_string: String, | 52 | fuzzy_search_string: String, |
45 | ignore_assoc_items: bool, | 53 | assoc_item_search: AssocItemSearch, |
46 | name_only: bool, | 54 | limit: Option<usize>, |
47 | ) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> + 'a { | 55 | ) -> Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a> { |
48 | let _p = profile::span("find_similar_imports"); | 56 | let _p = profile::span("find_similar_imports"); |
49 | 57 | ||
50 | let mut external_query = import_map::Query::new(fuzzy_search_string.clone()) | 58 | let mut external_query = import_map::Query::new(fuzzy_search_string.clone()) |
51 | .search_mode(import_map::SearchMode::Fuzzy); | 59 | .search_mode(import_map::SearchMode::Fuzzy) |
52 | if name_only { | 60 | .name_only(); |
53 | external_query = external_query.name_only(); | 61 | |
62 | match assoc_item_search { | ||
63 | AssocItemSearch::Include => {} | ||
64 | AssocItemSearch::Exclude => { | ||
65 | external_query = external_query.exclude_import_kind(ImportKind::AssociatedItem); | ||
66 | } | ||
67 | AssocItemSearch::AssocItemsOnly => { | ||
68 | external_query = external_query.assoc_items_only(); | ||
69 | } | ||
54 | } | 70 | } |
55 | 71 | ||
56 | let mut local_query = symbol_index::Query::new(fuzzy_search_string); | 72 | let mut local_query = symbol_index::Query::new(fuzzy_search_string); |
57 | 73 | ||
58 | if let Some(limit) = limit { | 74 | if let Some(limit) = limit { |
59 | local_query.limit(limit); | ||
60 | external_query = external_query.limit(limit); | 75 | external_query = external_query.limit(limit); |
76 | local_query.limit(limit); | ||
61 | } | 77 | } |
62 | 78 | ||
63 | let db = sema.db; | 79 | let db = sema.db; |
64 | find_imports(sema, krate, local_query, external_query).filter(move |import_candidate| { | 80 | Box::new(find_imports(sema, krate, local_query, external_query).filter( |
65 | if ignore_assoc_items { | 81 | move |import_candidate| match assoc_item_search { |
66 | match import_candidate { | 82 | AssocItemSearch::Include => true, |
67 | Either::Left(ModuleDef::Function(function)) => function.as_assoc_item(db).is_none(), | 83 | AssocItemSearch::Exclude => !is_assoc_item(import_candidate, db), |
68 | Either::Left(ModuleDef::Const(const_)) => const_.as_assoc_item(db).is_none(), | 84 | AssocItemSearch::AssocItemsOnly => is_assoc_item(import_candidate, db), |
69 | Either::Left(ModuleDef::TypeAlias(type_alias)) => { | 85 | }, |
70 | type_alias.as_assoc_item(db).is_none() | 86 | )) |
71 | } | 87 | } |
72 | _ => true, | 88 | |
73 | } | 89 | fn is_assoc_item(import_candidate: &Either<ModuleDef, MacroDef>, db: &RootDatabase) -> bool { |
74 | } else { | 90 | match import_candidate { |
75 | true | 91 | Either::Left(ModuleDef::Function(function)) => function.as_assoc_item(db).is_some(), |
76 | } | 92 | Either::Left(ModuleDef::Const(const_)) => const_.as_assoc_item(db).is_some(), |
77 | }) | 93 | Either::Left(ModuleDef::TypeAlias(type_alias)) => type_alias.as_assoc_item(db).is_some(), |
94 | _ => false, | ||
95 | } | ||
78 | } | 96 | } |
79 | 97 | ||
80 | fn find_imports<'a>( | 98 | fn find_imports<'a>( |