diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-11 11:07:52 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-11 11:07:52 +0100 |
commit | f320c38aec185de2a02e0febff133da1f6a3462b (patch) | |
tree | f22c1d5af6dcd994667d656833c3a27c568961ff /crates/ra_ide_db/src/imports_locator.rs | |
parent | dfbd81e84a699005db4e88e9fbf8d4440525a097 (diff) | |
parent | 6766a6b0e189f47d7a405c872598bca9a2395360 (diff) |
Merge #4819
4819: Add an FST index to `ImportMap` and use it to speed up auto import r=matklad a=jonas-schievink
For the importing crate, we still use the symbol index, but I've modified it to only look at files that comprise that crate (instead of the whole workspace).
Oh, and since now the symbol query limit is respected correctly, it's possible that some results from the local crate now disappear if there are many matches.
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/4763
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_ide_db/src/imports_locator.rs')
-rw-r--r-- | crates/ra_ide_db/src/imports_locator.rs | 46 |
1 files changed, 24 insertions, 22 deletions
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> { |