diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/assists.rs | 7 | ||||
-rw-r--r-- | crates/ra_ide/src/imports_locator.rs | 76 | ||||
-rw-r--r-- | crates/ra_ide/src/lib.rs | 1 |
3 files changed, 81 insertions, 3 deletions
diff --git a/crates/ra_ide/src/assists.rs b/crates/ra_ide/src/assists.rs index a936900da..c43c45c65 100644 --- a/crates/ra_ide/src/assists.rs +++ b/crates/ra_ide/src/assists.rs | |||
@@ -2,8 +2,9 @@ | |||
2 | 2 | ||
3 | use ra_db::{FilePosition, FileRange}; | 3 | use ra_db::{FilePosition, FileRange}; |
4 | 4 | ||
5 | use crate::{db::RootDatabase, FileId, SourceChange, SourceFileEdit}; | 5 | use crate::{ |
6 | 6 | db::RootDatabase, imports_locator::ImportsLocatorIde, FileId, SourceChange, SourceFileEdit, | |
7 | }; | ||
7 | use either::Either; | 8 | use either::Either; |
8 | pub use ra_assists::AssistId; | 9 | pub use ra_assists::AssistId; |
9 | use ra_assists::{AssistAction, AssistLabel}; | 10 | use ra_assists::{AssistAction, AssistLabel}; |
@@ -16,7 +17,7 @@ pub struct Assist { | |||
16 | } | 17 | } |
17 | 18 | ||
18 | pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<Assist> { | 19 | pub(crate) fn assists(db: &RootDatabase, frange: FileRange) -> Vec<Assist> { |
19 | ra_assists::assists(db, frange) | 20 | ra_assists::assists_with_imports_locator(db, frange, ImportsLocatorIde::new(db)) |
20 | .into_iter() | 21 | .into_iter() |
21 | .map(|assist| { | 22 | .map(|assist| { |
22 | let file_id = frange.file_id; | 23 | let file_id = frange.file_id; |
diff --git a/crates/ra_ide/src/imports_locator.rs b/crates/ra_ide/src/imports_locator.rs new file mode 100644 index 000000000..48b014c7d --- /dev/null +++ b/crates/ra_ide/src/imports_locator.rs | |||
@@ -0,0 +1,76 @@ | |||
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 | |||
4 | use crate::{ | ||
5 | db::RootDatabase, | ||
6 | references::{classify_name, NameDefinition, NameKind}, | ||
7 | symbol_index::{self, FileSymbol}, | ||
8 | Query, | ||
9 | }; | ||
10 | use hir::{db::HirDatabase, ModuleDef, SourceBinder}; | ||
11 | use ra_assists::ImportsLocator; | ||
12 | use ra_prof::profile; | ||
13 | use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; | ||
14 | |||
15 | pub(crate) struct ImportsLocatorIde<'a> { | ||
16 | source_binder: SourceBinder<'a, RootDatabase>, | ||
17 | } | ||
18 | |||
19 | impl<'a> ImportsLocatorIde<'a> { | ||
20 | pub(crate) fn new(db: &'a RootDatabase) -> Self { | ||
21 | Self { source_binder: SourceBinder::new(db) } | ||
22 | } | ||
23 | |||
24 | fn get_name_definition( | ||
25 | &mut self, | ||
26 | db: &impl HirDatabase, | ||
27 | import_candidate: &FileSymbol, | ||
28 | ) -> Option<NameDefinition> { | ||
29 | let _p = profile("get_name_definition"); | ||
30 | let file_id = import_candidate.file_id.into(); | ||
31 | let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); | ||
32 | let candidate_name_node = if candidate_node.kind() != NAME { | ||
33 | candidate_node.children().find(|it| it.kind() == NAME)? | ||
34 | } else { | ||
35 | candidate_node | ||
36 | }; | ||
37 | classify_name( | ||
38 | &mut self.source_binder, | ||
39 | hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, | ||
40 | ) | ||
41 | } | ||
42 | } | ||
43 | |||
44 | impl ImportsLocator for ImportsLocatorIde<'_> { | ||
45 | fn find_imports(&mut self, name_to_import: &str) -> Vec<ModuleDef> { | ||
46 | let _p = profile("search_for_imports"); | ||
47 | let db = self.source_binder.db; | ||
48 | |||
49 | let project_results = { | ||
50 | let mut query = Query::new(name_to_import.to_string()); | ||
51 | query.exact(); | ||
52 | query.limit(40); | ||
53 | symbol_index::world_symbols(db, query) | ||
54 | }; | ||
55 | let lib_results = { | ||
56 | let mut query = Query::new(name_to_import.to_string()); | ||
57 | query.libs(); | ||
58 | query.exact(); | ||
59 | query.limit(40); | ||
60 | symbol_index::world_symbols(db, query) | ||
61 | }; | ||
62 | |||
63 | project_results | ||
64 | .into_iter() | ||
65 | .chain(lib_results.into_iter()) | ||
66 | .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) | ||
67 | .filter_map(|name_definition_to_import| { | ||
68 | if let NameKind::Def(module_def) = name_definition_to_import.kind { | ||
69 | Some(module_def) | ||
70 | } else { | ||
71 | None | ||
72 | } | ||
73 | }) | ||
74 | .collect() | ||
75 | } | ||
76 | } | ||
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index 62fe6d2a9..03ad6b2c1 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -30,6 +30,7 @@ mod syntax_highlighting; | |||
30 | mod parent_module; | 30 | mod parent_module; |
31 | mod references; | 31 | mod references; |
32 | mod impls; | 32 | mod impls; |
33 | mod imports_locator; | ||
33 | mod assists; | 34 | mod assists; |
34 | mod diagnostics; | 35 | mod diagnostics; |
35 | mod syntax_tree; | 36 | mod syntax_tree; |