aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src/imports_locator.rs
diff options
context:
space:
mode:
authorKevin DeLorey <[email protected]>2020-02-09 16:25:47 +0000
committerKevin DeLorey <[email protected]>2020-02-09 16:37:43 +0000
commita957c473fdb79880c39b73dc9e0c923093cf16ac (patch)
treef998b548f530ce604651e0e6af314ed2ec74b3b5 /crates/ra_ide_db/src/imports_locator.rs
parent22caf982b99c54058e2e9200aeea0e61cada284a (diff)
parent1b9b13b4b4a75b5531c3f046ce6bf72d681f2732 (diff)
Merge branch 'master' into kdelorey/complete-trait-impl
Diffstat (limited to 'crates/ra_ide_db/src/imports_locator.rs')
-rw-r--r--crates/ra_ide_db/src/imports_locator.rs72
1 files changed, 72 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..86383bcd0
--- /dev/null
+++ b/crates/ra_ide_db/src/imports_locator.rs
@@ -0,0 +1,72 @@
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_prof::profile;
6use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
7
8use crate::{
9 defs::classify_name,
10 defs::NameKind,
11 symbol_index::{self, FileSymbol, Query},
12 RootDatabase,
13};
14
15pub struct ImportsLocator<'a> {
16 source_binder: SourceBinder<'a, RootDatabase>,
17}
18
19impl<'a> ImportsLocator<'a> {
20 pub fn new(db: &'a RootDatabase) -> Self {
21 Self { source_binder: SourceBinder::new(db) }
22 }
23
24 pub fn find_imports(&mut self, name_to_import: &str) -> Vec<ModuleDef> {
25 let _p = profile("search_for_imports");
26 let db = self.source_binder.db;
27
28 let project_results = {
29 let mut query = Query::new(name_to_import.to_string());
30 query.exact();
31 query.limit(40);
32 symbol_index::world_symbols(db, query)
33 };
34 let lib_results = {
35 let mut query = Query::new(name_to_import.to_string());
36 query.libs();
37 query.exact();
38 query.limit(40);
39 symbol_index::world_symbols(db, query)
40 };
41
42 project_results
43 .into_iter()
44 .chain(lib_results.into_iter())
45 .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate))
46 .filter_map(|name_definition_to_import| match name_definition_to_import {
47 NameKind::ModuleDef(module_def) => Some(module_def),
48 _ => None,
49 })
50 .collect()
51 }
52
53 fn get_name_definition(
54 &mut self,
55 db: &impl HirDatabase,
56 import_candidate: &FileSymbol,
57 ) -> Option<NameKind> {
58 let _p = profile("get_name_definition");
59 let file_id = import_candidate.file_id.into();
60 let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?);
61 let candidate_name_node = if candidate_node.kind() != NAME {
62 candidate_node.children().find(|it| it.kind() == NAME)?
63 } else {
64 candidate_node
65 };
66 classify_name(
67 &mut self.source_binder,
68 hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? },
69 )
70 .map(|it| it.kind)
71 }
72}