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.rs59
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,