@@ -7,87 +7,66 @@ use ide_db::RootDatabase;
77use super :: { completion_context:: CompletionContext , completion_item:: Completions } ;
88
99/// Complete mod declaration, i.e. `mod <|> ;`
10- pub ( super ) fn complete_mod ( acc : & mut Completions , ctx : & CompletionContext ) {
11- let module_names_for_import = ctx
12- . scope
13- . module ( )
14- . and_then ( |current_module| {
15- let module_path = path_to_closest_containing_module_file ( current_module, ctx. db ) ;
16- // TODO kb filter out declarations in possible_sudmobule_names
17- // let declaration_source = current_module.declaration_source(ctx.db);
18- let module_definition_source_file =
19- current_module. definition_source ( ctx. db ) . file_id . original_file ( ctx. db ) ;
10+ pub ( super ) fn complete_mod ( acc : & mut Completions , ctx : & CompletionContext ) -> Option < ( ) > {
11+ let current_module = ctx. scope . module ( ) ?;
2012
21- let source_root_id = ctx. db . file_source_root ( module_definition_source_file) ;
22- let source_root = ctx. db . source_root ( source_root_id) ;
23- let directory_to_look_for_submodules = source_root
24- . path_for_file ( & module_definition_source_file)
25- . and_then ( |module_file_path| get_directory_with_submodules ( module_file_path) ) ?;
13+ // TODO kb filter out declarations in possible_sudmobule_names
14+ // let declaration_source = current_module.declaration_source(ctx.db);
15+ let module_definition_source_file =
16+ current_module. definition_source ( ctx. db ) . file_id . original_file ( ctx. db ) ;
17+ let source_root = ctx. db . source_root ( ctx. db . file_source_root ( module_definition_source_file) ) ;
18+ let directory_to_look_for_submodules = directory_to_look_for_submodules (
19+ current_module,
20+ ctx. db ,
21+ source_root. path_for_file ( & module_definition_source_file) ?,
22+ ) ?;
2623
27- let mod_declaration_candidates = source_root
28- . iter ( )
29- . filter ( |submodule_file| submodule_file != & module_definition_source_file)
30- . filter_map ( |submodule_file| {
31- let submodule_path = source_root. path_for_file ( & submodule_file) ?;
32- if submodule_path. parent ( ) ? == directory_to_look_for_submodules {
33- submodule_path. file_name_and_extension ( )
24+ let mod_declaration_candidates = source_root
25+ . iter ( )
26+ . filter ( |submodule_file| submodule_file != & module_definition_source_file)
27+ . filter_map ( |submodule_file| {
28+ let submodule_path = source_root. path_for_file ( & submodule_file) ?;
29+ if submodule_path. parent ( ) ? == directory_to_look_for_submodules {
30+ submodule_path. file_name_and_extension ( )
31+ } else {
32+ None
33+ }
34+ } )
35+ . filter_map ( |file_name_and_extension| {
36+ match file_name_and_extension {
37+ // TODO kb in src/bin when a module is included into another,
38+ // the included file gets "moved" into a directory below and now cannot add any other modules
39+ ( "mod" , Some ( "rs" ) ) | ( "lib" , Some ( "rs" ) ) | ( "main" , Some ( "rs" ) ) => None ,
40+ ( file_name, Some ( "rs" ) ) => Some ( file_name. to_owned ( ) ) ,
41+ ( subdirectory_name, None ) => {
42+ let mod_rs_path =
43+ directory_to_look_for_submodules. join ( subdirectory_name) ?. join ( "mod.rs" ) ?;
44+ if source_root. file_for_path ( & mod_rs_path) . is_some ( ) {
45+ Some ( subdirectory_name. to_owned ( ) )
3446 } else {
3547 None
3648 }
37- } )
38- . filter_map ( |file_name_and_extension| {
39- match file_name_and_extension {
40- // TODO kb wrong resolution for nested non-file modules (mod tests { mod <|> })
41- // TODO kb in src/bin when a module is included into another,
42- // the included file gets "moved" into a directory below and now cannot add any other modules
43- ( "mod" , Some ( "rs" ) ) | ( "lib" , Some ( "rs" ) ) | ( "main" , Some ( "rs" ) ) => None ,
44- ( file_name, Some ( "rs" ) ) => Some ( file_name. to_owned ( ) ) ,
45- ( subdirectory_name, None ) => {
46- let mod_rs_path = directory_to_look_for_submodules
47- . join ( subdirectory_name) ?
48- . join ( "mod.rs" ) ?;
49- if source_root. file_for_path ( & mod_rs_path) . is_some ( ) {
50- Some ( subdirectory_name. to_owned ( ) )
51- } else {
52- None
53- }
54- }
55- _ => None ,
56- }
57- } )
58- . collect :: < Vec < _ > > ( ) ;
59- dbg ! ( mod_declaration_candidates) ;
60- // TODO kb exlude existing children from the candidates
61- let existing_children = current_module. children ( ctx. db ) . collect :: < Vec < _ > > ( ) ;
62- None :: < Vec < String > >
49+ }
50+ _ => None ,
51+ }
6352 } )
64- . unwrap_or_default ( ) ;
65- }
53+ . collect :: < Vec < _ > > ( ) ;
54+ dbg ! ( mod_declaration_candidates ) ;
6655
67- fn path_to_closest_containing_module_file (
68- current_module : Module ,
69- db : & RootDatabase ,
70- ) -> Vec < Module > {
71- let mut path = Vec :: new ( ) ;
72-
73- let mut current_module = Some ( current_module) ;
74- while let Some ( ModuleSource :: Module ( _) ) =
75- current_module. map ( |module| module. definition_source ( db) . value )
76- {
77- if let Some ( module) = current_module {
78- path. insert ( 0 , module) ;
79- current_module = module. parent ( db) ;
80- } else {
81- current_module = None ;
82- }
83- }
56+ // TODO kb exlude existing children from the candidates
57+ let existing_children = current_module. children ( ctx. db ) . collect :: < Vec < _ > > ( ) ;
8458
85- path
59+ Some ( ( ) )
8660}
8761
88- fn get_directory_with_submodules ( module_file_path : & VfsPath ) -> Option < VfsPath > {
62+ fn directory_to_look_for_submodules (
63+ module : Module ,
64+ db : & RootDatabase ,
65+ module_file_path : & VfsPath ,
66+ ) -> Option < VfsPath > {
8967 let module_directory_path = module_file_path. parent ( ) ?;
90- match module_file_path. file_name_and_extension ( ) ? {
68+
69+ let base_directory = match module_file_path. file_name_and_extension ( ) ? {
9170 ( "mod" , Some ( "rs" ) ) | ( "lib" , Some ( "rs" ) ) | ( "main" , Some ( "rs" ) ) => {
9271 Some ( module_directory_path)
9372 }
@@ -109,5 +88,35 @@ fn get_directory_with_submodules(module_file_path: &VfsPath) -> Option<VfsPath>
10988 }
11089 }
11190 _ => None ,
91+ } ?;
92+
93+ let mut resulting_path = base_directory;
94+ for module in module_chain_to_containing_module_file ( module, db) {
95+ if let Some ( name) = module. name ( db) {
96+ resulting_path = resulting_path. join ( & name. to_string ( ) ) ?;
97+ }
98+ }
99+
100+ Some ( resulting_path)
101+ }
102+
103+ fn module_chain_to_containing_module_file (
104+ current_module : Module ,
105+ db : & RootDatabase ,
106+ ) -> Vec < Module > {
107+ let mut path = Vec :: new ( ) ;
108+
109+ let mut current_module = Some ( current_module) ;
110+ while let Some ( ModuleSource :: Module ( _) ) =
111+ current_module. map ( |module| module. definition_source ( db) . value )
112+ {
113+ if let Some ( module) = current_module {
114+ path. insert ( 0 , module) ;
115+ current_module = module. parent ( db) ;
116+ } else {
117+ current_module = None ;
118+ }
112119 }
120+
121+ path
113122}
0 commit comments