aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src/imports_locator.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_db/src/imports_locator.rs')
-rw-r--r--crates/ra_ide_db/src/imports_locator.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs
new file mode 100644
index 000000000..21e637608
--- /dev/null
+++ b/crates/ra_ide_db/src/imports_locator.rs
@@ -0,0 +1,75 @@
1//! This module contains an import search funcionality that is provided to the ra_assists module.
2//! Later, this should be moved away to a separate crate that is accessible from the ra_assists module.
3
4use hir::{db::HirDatabase, ModuleDef, SourceBinder};
5use ra_assists::ImportsLocator;
6use ra_prof::profile;
7use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
8
9use crate::{
10 defs::classify_name,
11 defs::NameKind,
12 symbol_index::{self, FileSymbol, Query},
13 RootDatabase,
14};
15
16pub struct ImportsLocatorIde<'a> {
17 source_binder: SourceBinder<'a, RootDatabase>,
18}
19
20impl<'a> ImportsLocatorIde<'a> {
21 pub fn new(db: &'a RootDatabase) -> Self {
22 Self { source_binder: SourceBinder::new(db) }
23 }
24
25 fn get_name_definition(
26 &mut self,
27 db: &impl HirDatabase,
28 import_candidate: &FileSymbol,
29 ) -> Option<NameKind> {
30 let _p = profile("get_name_definition");
31 let file_id = import_candidate.file_id.into();
32 let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?);
33 let candidate_name_node = if candidate_node.kind() != NAME {
34 candidate_node.children().find(|it| it.kind() == NAME)?
35 } else {
36 candidate_node
37 };
38 classify_name(
39 &mut self.source_binder,
40 hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? },
41 )
42 .map(|it| it.kind)
43 }
44}
45
46impl ImportsLocator for ImportsLocatorIde<'_> {
47 fn find_imports(&mut self, name_to_import: &str) -> Vec<ModuleDef> {
48 let _p = profile("search_for_imports");
49 let db = self.source_binder.db;
50
51 let project_results = {
52 let mut query = Query::new(name_to_import.to_string());
53 query.exact();
54 query.limit(40);
55 symbol_index::world_symbols(db, query)
56 };
57 let lib_results = {
58 let mut query = Query::new(name_to_import.to_string());
59 query.libs();
60 query.exact();
61 query.limit(40);
62 symbol_index::world_symbols(db, query)
63 };
64
65 project_results
66 .into_iter()
67 .chain(lib_results.into_iter())
68 .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate))
69 .filter_map(|name_definition_to_import| match name_definition_to_import {
70 NameKind::Def(module_def) => Some(module_def),
71 _ => None,
72 })
73 .collect()
74 }
75}