1
1
//! This module contains an import search funcionality that is provided to the ra_assists module.
2
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
5
use ra_prof:: profile;
6
6
use ra_syntax:: { ast, AstNode , SyntaxKind :: NAME } ;
7
7
@@ -11,44 +11,46 @@ use crate::{
11
11
RootDatabase ,
12
12
} ;
13
13
use either:: Either ;
14
+ use rustc_hash:: FxHashSet ;
14
15
15
16
pub struct ImportsLocator < ' a > {
16
17
sema : Semantics < ' a , RootDatabase > ,
18
+ krate : Crate ,
17
19
}
18
20
19
21
impl < ' a > ImportsLocator < ' a > {
20
- pub fn new ( db : & ' a RootDatabase ) -> Self {
21
- Self { sema : Semantics :: new ( db) }
22
+ pub fn new ( db : & ' a RootDatabase , krate : Crate ) -> Self {
23
+ Self { sema : Semantics :: new ( db) , krate }
22
24
}
23
25
24
26
pub fn find_imports ( & mut self , name_to_import : & str ) -> Vec < Either < ModuleDef , MacroDef > > {
25
27
let _p = profile ( "search_for_imports" ) ;
26
28
let db = self . sema . db ;
27
29
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 = {
30
+ // Query dependencies first.
31
+ let mut candidates: FxHashSet < _ > =
32
+ self . krate . query_external_importables ( db, name_to_import) . collect ( ) ;
33
+
34
+ // Query the local crate using the symbol index.
35
+ let local_results = {
35
36
let mut query = Query :: new ( name_to_import. to_string ( ) ) ;
36
- query. libs ( ) ;
37
37
query. exact ( ) ;
38
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
43
- . into_iter ( )
44
- . chain ( lib_results. into_iter ( ) )
45
- . filter_map ( |import_candidate| self . get_name_definition ( & import_candidate) )
46
- . filter_map ( |name_definition_to_import| match name_definition_to_import {
47
- Definition :: ModuleDef ( module_def) => Some ( Either :: Left ( module_def) ) ,
48
- Definition :: Macro ( macro_def) => Some ( Either :: Right ( macro_def) ) ,
49
- _ => None ,
50
- } )
51
- . collect ( )
42
+ candidates. extend (
43
+ local_results
44
+ . into_iter ( )
45
+ . filter_map ( |import_candidate| self . get_name_definition ( & import_candidate) )
46
+ . filter_map ( |name_definition_to_import| match name_definition_to_import {
47
+ Definition :: ModuleDef ( module_def) => Some ( Either :: Left ( module_def) ) ,
48
+ Definition :: Macro ( macro_def) => Some ( Either :: Right ( macro_def) ) ,
49
+ _ => None ,
50
+ } ) ,
51
+ ) ;
52
+
53
+ candidates. into_iter ( ) . collect ( )
52
54
}
53
55
54
56
fn get_name_definition ( & mut self , import_candidate : & FileSymbol ) -> Option < Definition > {
0 commit comments