From bb5c189b7dae1ea63ccd5d7a0c2e097d7c676f77 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:39:16 +0200 Subject: Rename ra_ide_db -> ide_db --- crates/ide_db/src/imports_locator.rs | 64 ++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 crates/ide_db/src/imports_locator.rs (limited to 'crates/ide_db/src/imports_locator.rs') diff --git a/crates/ide_db/src/imports_locator.rs b/crates/ide_db/src/imports_locator.rs new file mode 100644 index 000000000..1d0c20291 --- /dev/null +++ b/crates/ide_db/src/imports_locator.rs @@ -0,0 +1,64 @@ +//! This module contains an import search funcionality that is provided to the ra_assists module. +//! Later, this should be moved away to a separate crate that is accessible from the ra_assists module. + +use hir::{Crate, MacroDef, ModuleDef, Semantics}; +use syntax::{ast, AstNode, SyntaxKind::NAME}; + +use crate::{ + defs::{classify_name, Definition}, + symbol_index::{self, FileSymbol, Query}, + RootDatabase, +}; +use either::Either; +use rustc_hash::FxHashSet; + +pub fn find_imports<'a>( + sema: &Semantics<'a, RootDatabase>, + krate: Crate, + name_to_import: &str, +) -> Vec> { + let _p = profile::span("search_for_imports"); + let db = sema.db; + + // Query dependencies first. + let mut candidates: FxHashSet<_> = + krate.query_external_importables(db, name_to_import).collect(); + + // Query the local crate using the symbol index. + let local_results = { + let mut query = Query::new(name_to_import.to_string()); + query.exact(); + query.limit(40); + symbol_index::crate_symbols(db, krate.into(), query) + }; + + candidates.extend( + local_results + .into_iter() + .filter_map(|import_candidate| get_name_definition(sema, &import_candidate)) + .filter_map(|name_definition_to_import| match name_definition_to_import { + Definition::ModuleDef(module_def) => Some(Either::Left(module_def)), + Definition::Macro(macro_def) => Some(Either::Right(macro_def)), + _ => None, + }), + ); + + candidates.into_iter().collect() +} + +fn get_name_definition<'a>( + sema: &Semantics<'a, RootDatabase>, + import_candidate: &FileSymbol, +) -> Option { + let _p = profile::span("get_name_definition"); + let file_id = import_candidate.file_id; + + let candidate_node = import_candidate.ptr.to_node(sema.parse(file_id).syntax()); + let candidate_name_node = if candidate_node.kind() != NAME { + candidate_node.children().find(|it| it.kind() == NAME)? + } else { + candidate_node + }; + let name = ast::Name::cast(candidate_name_node)?; + classify_name(sema, &name)?.into_definition(sema.db) +} -- cgit v1.2.3