@@ -5,17 +5,17 @@ use rustc_hash::FxHashMap;
55
66use ra_syntax:: {
77 SmolStr , SyntaxKind :: { self , * } ,
8- ast:: { self , NameOwner , AstNode }
8+ ast:: { self , NameOwner , AstNode , ModuleItemOwner }
99} ;
1010
1111use crate :: {
1212 Cancelable ,
1313 loc2id:: { DefId , DefLoc } ,
1414 descriptors:: {
1515 DescriptorDatabase ,
16- module:: { ModuleId , ModuleTree } ,
16+ module:: { ModuleId , ModuleTree , ModuleSourceNode } ,
1717 } ,
18- syntax_ptr:: { LocalSyntaxPtr , SyntaxPtr } ,
18+ syntax_ptr:: { LocalSyntaxPtr } ,
1919 input:: SourceRootId ,
2020} ;
2121
@@ -25,37 +25,79 @@ use crate::{
2525/// This stands in-between raw syntax and name resolution and alow us to avoid
2626/// recomputing name res: if `InputModuleItems` are the same, we can avoid
2727/// running name resolution.
28- #[ derive( Debug , Default ) ]
29- struct InputModuleItems {
28+ #[ derive( Debug , Default , PartialEq , Eq ) ]
29+ pub ( crate ) struct InputModuleItems {
3030 items : Vec < ModuleItem > ,
3131 glob_imports : Vec < Path > ,
3232 imports : Vec < Path > ,
3333}
3434
35- #[ derive( Debug , Clone ) ]
35+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
3636struct Path {
3737 kind : PathKind ,
3838 segments : Vec < ( LocalSyntaxPtr , SmolStr ) > ,
3939}
4040
41- #[ derive( Debug , Clone , Copy ) ]
41+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
4242enum PathKind {
4343 Abs ,
4444 Self_ ,
4545 Super ,
4646 Crate ,
4747}
4848
49+ pub ( crate ) fn input_module_items (
50+ db : & impl DescriptorDatabase ,
51+ source_root : SourceRootId ,
52+ module_id : ModuleId ,
53+ ) -> Cancelable < Arc < InputModuleItems > > {
54+ let module_tree = db. _module_tree ( source_root) ?;
55+ let source = module_id. source ( & module_tree) ;
56+ let res = match source. resolve ( db) {
57+ ModuleSourceNode :: SourceFile ( it) => {
58+ let items = it. borrowed ( ) . items ( ) ;
59+ InputModuleItems :: new ( items)
60+ }
61+ ModuleSourceNode :: Module ( it) => {
62+ let items = it
63+ . borrowed ( )
64+ . item_list ( )
65+ . into_iter ( )
66+ . flat_map ( |it| it. items ( ) ) ;
67+ InputModuleItems :: new ( items)
68+ }
69+ } ;
70+ Ok ( Arc :: new ( res) )
71+ }
72+
4973pub ( crate ) fn item_map (
5074 db : & impl DescriptorDatabase ,
5175 source_root : SourceRootId ,
5276) -> Cancelable < Arc < ItemMap > > {
53- unimplemented ! ( )
77+ let module_tree = db. _module_tree ( source_root) ?;
78+ let input = module_tree
79+ . modules ( )
80+ . map ( |id| {
81+ let items = db. _input_module_items ( source_root, id) ?;
82+ Ok ( ( id, items) )
83+ } )
84+ . collect :: < Cancelable < FxHashMap < _ , _ > > > ( ) ?;
85+
86+ let mut resolver = Resolver {
87+ db : db,
88+ input : & input,
89+ source_root,
90+ module_tree,
91+ result : ItemMap :: default ( ) ,
92+ } ;
93+ resolver. resolve ( ) ?;
94+ let res = resolver. result ;
95+ Ok ( Arc :: new ( res) )
5496}
5597
5698/// Item map is the result of the name resolution. Item map contains, for each
5799/// module, the set of visible items.
58- #[ derive( Debug , PartialEq , Eq ) ]
100+ #[ derive( Default , Debug , PartialEq , Eq ) ]
59101pub ( crate ) struct ItemMap {
60102 per_module : FxHashMap < ModuleId , ModuleItems > ,
61103}
@@ -86,15 +128,15 @@ struct PerNs<T> {
86128 values : Option < T > ,
87129}
88130
89- #[ derive( Debug ) ]
131+ #[ derive( Debug , PartialEq , Eq ) ]
90132struct ModuleItem {
91133 ptr : LocalSyntaxPtr ,
92134 name : SmolStr ,
93135 kind : SyntaxKind ,
94136 vis : Vis ,
95137}
96138
97- #[ derive( Debug ) ]
139+ #[ derive( Debug , PartialEq , Eq ) ]
98140enum Vis {
99141 Priv ,
100142 Other ,
@@ -116,11 +158,13 @@ impl InputModuleItems {
116158 ast:: ModuleItem :: FnDef ( it) => self . items . push ( ModuleItem :: new ( it) ?) ,
117159 ast:: ModuleItem :: TraitDef ( it) => self . items . push ( ModuleItem :: new ( it) ?) ,
118160 ast:: ModuleItem :: TypeDef ( it) => self . items . push ( ModuleItem :: new ( it) ?) ,
119- ast:: ModuleItem :: ImplItem ( it ) => {
161+ ast:: ModuleItem :: ImplItem ( _ ) => {
120162 // impls don't define items
121163 }
122164 ast:: ModuleItem :: UseItem ( it) => self . add_use_item ( it) ,
123- ast:: ModuleItem :: ExternCrateItem ( it) => ( ) ,
165+ ast:: ModuleItem :: ExternCrateItem ( _) => {
166+ // TODO
167+ }
124168 ast:: ModuleItem :: ConstDef ( it) => self . items . push ( ModuleItem :: new ( it) ?) ,
125169 ast:: ModuleItem :: StaticDef ( it) => self . items . push ( ModuleItem :: new ( it) ?) ,
126170 ast:: ModuleItem :: Module ( it) => self . items . push ( ModuleItem :: new ( it) ?) ,
@@ -227,7 +271,7 @@ impl ModuleItem {
227271
228272struct Resolver < ' a , DB > {
229273 db : & ' a DB ,
230- input : & ' a FxHashMap < ModuleId , InputModuleItems > ,
274+ input : & ' a FxHashMap < ModuleId , Arc < InputModuleItems > > ,
231275 source_root : SourceRootId ,
232276 module_tree : Arc < ModuleTree > ,
233277 result : ItemMap ,
@@ -237,14 +281,16 @@ impl<'a, DB> Resolver<'a, DB>
237281where
238282 DB : DescriptorDatabase ,
239283{
240- fn resolve ( & mut self ) {
284+ fn resolve ( & mut self ) -> Cancelable < ( ) > {
241285 for ( & module_id, items) in self . input . iter ( ) {
242286 self . populate_module ( module_id, items)
243287 }
244288
245289 for & module_id in self . input . keys ( ) {
290+ crate :: db:: check_canceled ( self . db ) ?;
246291 self . resolve_imports ( module_id) ;
247292 }
293+ Ok ( ( ) )
248294 }
249295
250296 fn populate_module ( & mut self , module_id : ModuleId , input : & InputModuleItems ) {
@@ -346,3 +392,46 @@ where
346392 f ( module_items)
347393 }
348394}
395+
396+ #[ cfg( test) ]
397+ mod tests {
398+ use crate :: {
399+ mock_analysis:: analysis_and_position,
400+ descriptors:: { DescriptorDatabase , module:: ModuleDescriptor } ,
401+ input:: FilesDatabase ,
402+ } ;
403+ use super :: * ;
404+
405+ fn item_map ( fixture : & str ) -> ( Arc < ItemMap > , ModuleId ) {
406+ let ( analysis, pos) = analysis_and_position ( fixture) ;
407+ let db = analysis. imp . db ;
408+ let source_root = db. file_source_root ( pos. file_id ) ;
409+ let descr = ModuleDescriptor :: guess_from_position ( & * db, pos)
410+ . unwrap ( )
411+ . unwrap ( ) ;
412+ let module_id = descr. module_id ;
413+ ( db. _item_map ( source_root) . unwrap ( ) , module_id)
414+ }
415+
416+ #[ test]
417+ fn test_item_map ( ) {
418+ let ( item_map, module_id) = item_map (
419+ "
420+ //- /lib.rs
421+ mod foo;
422+
423+ use crate::foo::bar::Baz;
424+ <|>
425+
426+ //- /foo/mod.rs
427+ pub mod bar;
428+
429+ //- /foo/bar.rs
430+ pub struct Baz;
431+ " ,
432+ ) ;
433+ let name = SmolStr :: from ( "Baz" ) ;
434+ let resolution = & item_map. per_module [ & module_id] . items [ & name] ;
435+ assert ! ( resolution. def_id. is_some( ) ) ;
436+ }
437+ }
0 commit comments