aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src/imports_locator.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src/imports_locator.rs')
-rw-r--r--crates/ide_db/src/imports_locator.rs74
1 files changed, 44 insertions, 30 deletions
diff --git a/crates/ide_db/src/imports_locator.rs b/crates/ide_db/src/imports_locator.rs
index d111fba92..d69e65960 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
4use hir::{import_map, AsAssocItem, Crate, MacroDef, ModuleDef, Semantics}; 4use hir::{
5 import_map::{self, ImportKind},
6 AsAssocItem, Crate, MacroDef, ModuleDef, Semantics,
7};
5use syntax::{ast, AstNode, SyntaxKind::NAME}; 8use syntax::{ast, AstNode, SyntaxKind::NAME};
6 9
7use crate::{ 10use crate::{
@@ -18,9 +21,9 @@ 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 {
@@ -34,47 +37,58 @@ pub fn find_exact_imports<'a>(
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
43pub enum AssocItemSearch {
44 Include,
45 Exclude,
46 AssocItemsOnly,
38} 47}
39 48
40pub fn find_similar_imports<'a>( 49pub 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) -> Box<dyn Iterator<Item = Either<ModuleDef, MacroDef>> + 'a> {
47) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> + 'a {
48 let _p = profile::span("find_similar_imports"); 55 let _p = profile::span("find_similar_imports");
49 56
50 let mut external_query = import_map::Query::new(fuzzy_search_string.clone()) 57 let mut external_query = import_map::Query::new(fuzzy_search_string.clone())
51 .search_mode(import_map::SearchMode::Fuzzy); 58 .search_mode(import_map::SearchMode::Fuzzy)
52 if name_only { 59 .name_only()
53 external_query = external_query.name_only(); 60 .limit(QUERY_SEARCH_LIMIT);
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 local_query.limit(QUERY_SEARCH_LIMIT);
58 if let Some(limit) = limit {
59 local_query.limit(limit);
60 external_query = external_query.limit(limit);
61 }
62 74
63 let db = sema.db; 75 let db = sema.db;
64 find_imports(sema, krate, local_query, external_query).filter(move |import_candidate| { 76 Box::new(find_imports(sema, krate, local_query, external_query).filter(
65 if ignore_assoc_items { 77 move |import_candidate| match assoc_item_search {
66 match import_candidate { 78 AssocItemSearch::Include => true,
67 Either::Left(ModuleDef::Function(function)) => function.as_assoc_item(db).is_none(), 79 AssocItemSearch::Exclude => !is_assoc_item(import_candidate, db),
68 Either::Left(ModuleDef::Const(const_)) => const_.as_assoc_item(db).is_none(), 80 AssocItemSearch::AssocItemsOnly => is_assoc_item(import_candidate, db),
69 Either::Left(ModuleDef::TypeAlias(type_alias)) => { 81 },
70 type_alias.as_assoc_item(db).is_none() 82 ))
71 } 83}
72 _ => true, 84
73 } 85fn is_assoc_item(import_candidate: &Either<ModuleDef, MacroDef>, db: &RootDatabase) -> bool {
74 } else { 86 match import_candidate {
75 true 87 Either::Left(ModuleDef::Function(function)) => function.as_assoc_item(db).is_some(),
76 } 88 Either::Left(ModuleDef::Const(const_)) => const_.as_assoc_item(db).is_some(),
77 }) 89 Either::Left(ModuleDef::TypeAlias(type_alias)) => type_alias.as_assoc_item(db).is_some(),
90 _ => false,
91 }
78} 92}
79 93
80fn find_imports<'a>( 94fn find_imports<'a>(