Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-db/src/items_locator.rs')
| -rw-r--r-- | crates/ide-db/src/items_locator.rs | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/crates/ide-db/src/items_locator.rs b/crates/ide-db/src/items_locator.rs index 47549a1d00..7f66ea0c10 100644 --- a/crates/ide-db/src/items_locator.rs +++ b/crates/ide-db/src/items_locator.rs @@ -3,10 +3,14 @@ //! The main reason for this module to exist is the fact that project's items and dependencies' items //! are located in different caches, with different APIs. use either::Either; -use hir::{import_map, Crate, ItemInNs, Semantics}; +use hir::{import_map, Crate, ItemInNs, Module, Semantics}; use limit::Limit; -use crate::{imports::import_assets::NameToImport, symbol_index, RootDatabase}; +use crate::{ + imports::import_assets::NameToImport, + symbol_index::{self, SymbolsDatabase as _}, + RootDatabase, +}; /// A value to use, when uncertain which limit to pick. pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(100); @@ -20,8 +24,7 @@ pub fn items_with_name<'a>( name: NameToImport, assoc_item_search: AssocSearchMode, ) -> impl Iterator<Item = ItemInNs> + 'a { - let krate_name = krate.display_name(sema.db).map(|name| name.to_string()); - let _p = tracing::info_span!("items_with_name", name = name.text(), assoc_item_search = ?assoc_item_search, crate = ?krate_name) + let _p = tracing::info_span!("items_with_name", name = name.text(), assoc_item_search = ?assoc_item_search, crate = ?krate.display_name(sema.db).map(|name| name.to_string())) .entered(); let prefix = matches!(name, NameToImport::Prefix(..)); @@ -66,6 +69,54 @@ pub fn items_with_name<'a>( find_items(sema, krate, local_query, external_query) } +/// Searches for importable items with the given name in the crate and its dependencies. +pub fn items_with_name_in_module<'a>( + sema: &'a Semantics<'_, RootDatabase>, + module: Module, + name: NameToImport, + assoc_item_search: AssocSearchMode, +) -> impl Iterator<Item = ItemInNs> + 'a { + let _p = tracing::info_span!("items_with_name_in", name = name.text(), assoc_item_search = ?assoc_item_search, ?module) + .entered(); + + let prefix = matches!(name, NameToImport::Prefix(..)); + let local_query = match name { + NameToImport::Prefix(exact_name, case_sensitive) + | NameToImport::Exact(exact_name, case_sensitive) => { + let mut local_query = symbol_index::Query::new(exact_name.clone()); + local_query.assoc_search_mode(assoc_item_search); + if prefix { + local_query.prefix(); + } else { + local_query.exact(); + } + if case_sensitive { + local_query.case_sensitive(); + } + local_query + } + NameToImport::Fuzzy(fuzzy_search_string, case_sensitive) => { + let mut local_query = symbol_index::Query::new(fuzzy_search_string.clone()); + local_query.fuzzy(); + local_query.assoc_search_mode(assoc_item_search); + + if case_sensitive { + local_query.case_sensitive(); + } + + local_query + } + }; + let mut local_results = Vec::new(); + local_query.search(&[sema.db.module_symbols(module)], |local_candidate| { + local_results.push(match local_candidate.def { + hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def), + def => ItemInNs::from(def), + }) + }); + local_results.into_iter() +} + fn find_items<'a>( sema: &'a Semantics<'_, RootDatabase>, krate: Crate, |