diff options
-rw-r--r-- | crates/ra_assists/src/handlers/auto_import.rs | 47 | ||||
-rw-r--r-- | crates/ra_ide_db/src/imports_locator.rs | 46 |
2 files changed, 70 insertions, 23 deletions
diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs index edf96d50e..1f4142747 100644 --- a/crates/ra_assists/src/handlers/auto_import.rs +++ b/crates/ra_assists/src/handlers/auto_import.rs | |||
@@ -130,7 +130,7 @@ impl AutoImportAssets { | |||
130 | fn search_for_imports(&self, db: &RootDatabase) -> BTreeSet<ModPath> { | 130 | fn search_for_imports(&self, db: &RootDatabase) -> BTreeSet<ModPath> { |
131 | let _p = profile("auto_import::search_for_imports"); | 131 | let _p = profile("auto_import::search_for_imports"); |
132 | let current_crate = self.module_with_name_to_import.krate(); | 132 | let current_crate = self.module_with_name_to_import.krate(); |
133 | ImportsLocator::new(db) | 133 | ImportsLocator::new(db, current_crate) |
134 | .find_imports(&self.get_search_query()) | 134 | .find_imports(&self.get_search_query()) |
135 | .into_iter() | 135 | .into_iter() |
136 | .filter_map(|candidate| match &self.import_candidate { | 136 | .filter_map(|candidate| match &self.import_candidate { |
@@ -841,4 +841,49 @@ fn main() { | |||
841 | ", | 841 | ", |
842 | ) | 842 | ) |
843 | } | 843 | } |
844 | |||
845 | #[test] | ||
846 | fn dep_import() { | ||
847 | check_assist( | ||
848 | auto_import, | ||
849 | r" | ||
850 | //- /lib.rs crate:dep | ||
851 | pub struct Struct; | ||
852 | |||
853 | //- /main.rs crate:main deps:dep | ||
854 | fn main() { | ||
855 | Struct<|> | ||
856 | }", | ||
857 | r"use dep::Struct; | ||
858 | |||
859 | fn main() { | ||
860 | Struct | ||
861 | } | ||
862 | ", | ||
863 | ); | ||
864 | } | ||
865 | |||
866 | #[test] | ||
867 | fn whole_segment() { | ||
868 | check_assist( | ||
869 | auto_import, | ||
870 | r" | ||
871 | //- /lib.rs crate:dep | ||
872 | pub mod fmt { | ||
873 | pub trait Display {} | ||
874 | } | ||
875 | |||
876 | pub fn panic_fmt() {} | ||
877 | |||
878 | //- /main.rs crate:main deps:dep | ||
879 | struct S; | ||
880 | |||
881 | impl f<|>mt::Display for S {}", | ||
882 | r"use dep::fmt; | ||
883 | |||
884 | struct S; | ||
885 | impl fmt::Display for S {} | ||
886 | ", | ||
887 | ); | ||
888 | } | ||
844 | } | 889 | } |
diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs index bf0d8db60..fff112e66 100644 --- a/crates/ra_ide_db/src/imports_locator.rs +++ b/crates/ra_ide_db/src/imports_locator.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! This module contains an import search funcionality that is provided to the ra_assists module. | 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. | 2 | //! Later, this should be moved away to a separate crate that is accessible from the ra_assists module. |
3 | 3 | ||
4 | use hir::{MacroDef, ModuleDef, Semantics}; | 4 | use hir::{Crate, MacroDef, ModuleDef, Semantics}; |
5 | use ra_prof::profile; | 5 | use ra_prof::profile; |
6 | use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; | 6 | use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; |
7 | 7 | ||
@@ -11,44 +11,46 @@ use crate::{ | |||
11 | RootDatabase, | 11 | RootDatabase, |
12 | }; | 12 | }; |
13 | use either::Either; | 13 | use either::Either; |
14 | use rustc_hash::FxHashSet; | ||
14 | 15 | ||
15 | pub struct ImportsLocator<'a> { | 16 | pub struct ImportsLocator<'a> { |
16 | sema: Semantics<'a, RootDatabase>, | 17 | sema: Semantics<'a, RootDatabase>, |
18 | krate: Crate, | ||
17 | } | 19 | } |
18 | 20 | ||
19 | impl<'a> ImportsLocator<'a> { | 21 | impl<'a> ImportsLocator<'a> { |
20 | pub fn new(db: &'a RootDatabase) -> Self { | 22 | pub fn new(db: &'a RootDatabase, krate: Crate) -> Self { |
21 | Self { sema: Semantics::new(db) } | 23 | Self { sema: Semantics::new(db), krate } |
22 | } | 24 | } |
23 | 25 | ||
24 | pub fn find_imports(&mut self, name_to_import: &str) -> Vec<Either<ModuleDef, MacroDef>> { | 26 | pub fn find_imports(&mut self, name_to_import: &str) -> Vec<Either<ModuleDef, MacroDef>> { |
25 | let _p = profile("search_for_imports"); | 27 | let _p = profile("search_for_imports"); |
26 | let db = self.sema.db; | 28 | let db = self.sema.db; |
27 | 29 | ||
28 | let project_results = { | 30 | // Query dependencies first. |
29 | let mut query = Query::new(name_to_import.to_string()); | 31 | let mut candidates: FxHashSet<_> = |
30 | query.exact(); | 32 | self.krate.query_external_importables(db, name_to_import).collect(); |
31 | query.limit(40); | 33 | |
32 | symbol_index::world_symbols(db, query) | 34 | // Query the local crate using the symbol index. |
33 | }; | 35 | let local_results = { |
34 | let lib_results = { | ||
35 | let mut query = Query::new(name_to_import.to_string()); | 36 | let mut query = Query::new(name_to_import.to_string()); |
36 | query.libs(); | ||
37 | query.exact(); | 37 | query.exact(); |
38 | query.limit(40); | 38 | query.limit(40); |
39 | symbol_index::world_symbols(db, query) | 39 | symbol_index::crate_symbols(db, self.krate.into(), query) |
40 | }; | 40 | }; |
41 | 41 | ||
42 | project_results | 42 | candidates.extend( |
43 | .into_iter() | 43 | local_results |
44 | .chain(lib_results.into_iter()) | 44 | .into_iter() |
45 | .filter_map(|import_candidate| self.get_name_definition(&import_candidate)) | 45 | .filter_map(|import_candidate| self.get_name_definition(&import_candidate)) |
46 | .filter_map(|name_definition_to_import| match name_definition_to_import { | 46 | .filter_map(|name_definition_to_import| match name_definition_to_import { |
47 | Definition::ModuleDef(module_def) => Some(Either::Left(module_def)), | 47 | Definition::ModuleDef(module_def) => Some(Either::Left(module_def)), |
48 | Definition::Macro(macro_def) => Some(Either::Right(macro_def)), | 48 | Definition::Macro(macro_def) => Some(Either::Right(macro_def)), |
49 | _ => None, | 49 | _ => None, |
50 | }) | 50 | }), |
51 | .collect() | 51 | ); |
52 | |||
53 | candidates.into_iter().collect() | ||
52 | } | 54 | } |
53 | 55 | ||
54 | fn get_name_definition(&mut self, import_candidate: &FileSymbol) -> Option<Definition> { | 56 | fn get_name_definition(&mut self, import_candidate: &FileSymbol) -> Option<Definition> { |