@@ -95,24 +95,10 @@ impl<'db> Module<'db> {
9595 /// The names returned correspond to the "base" name of the module.
9696 /// That is, `{self.name}.{basename}` should give the full module name.
9797 pub fn all_submodules ( self , db : & ' db dyn Db ) -> & ' db [ Name ] {
98- self . all_submodules_inner ( db) . as_deref ( ) . unwrap_or_default ( )
98+ self . all_submodules_inner ( db) . unwrap_or_default ( )
9999 }
100100
101- #[ allow( clippy:: ref_option) ]
102- #[ salsa:: tracked( returns( ref) ) ]
103- fn all_submodules_inner ( self , db : & ' db dyn Db ) -> Option < Vec < Name > > {
104- fn is_submodule (
105- is_dir : bool ,
106- is_file : bool ,
107- basename : Option < & str > ,
108- extension : Option < & str > ,
109- ) -> bool {
110- is_dir
111- || ( is_file
112- && matches ! ( extension, Some ( "py" | "pyi" ) )
113- && !matches ! ( basename, Some ( "__init__.py" | "__init__.pyi" ) ) )
114- }
115-
101+ fn all_submodules_inner ( self , db : & ' db dyn Db ) -> Option < & ' db [ Name ] > {
116102 // It would be complex and expensive to compute all submodules for
117103 // namespace packages, since a namespace package doesn't correspond
118104 // to a single file; it can span multiple directories across multiple
@@ -124,55 +110,68 @@ impl<'db> Module<'db> {
124110 if !matches ! ( module. kind( db) , ModuleKind :: Package ) {
125111 return None ;
126112 }
113+ all_submodule_names_for_package ( db, module. file ( db) ) . as_deref ( )
114+ }
115+ }
116+
117+ impl std:: fmt:: Debug for Module < ' _ > {
118+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
119+ salsa:: with_attached_database ( |db| {
120+ f. debug_struct ( "Module" )
121+ . field ( "name" , & self . name ( db) )
122+ . field ( "kind" , & self . kind ( db) )
123+ . field ( "file" , & self . file ( db) )
124+ . field ( "search_path" , & self . search_path ( db) )
125+ . field ( "known" , & self . known ( db) )
126+ . finish ( )
127+ } )
128+ . unwrap_or_else ( || f. debug_tuple ( "Module" ) . field ( & self . as_id ( ) ) . finish ( ) )
129+ }
130+ }
131+
132+ #[ allow( clippy:: ref_option) ]
133+ #[ salsa:: tracked( returns( ref) ) ]
134+ fn all_submodule_names_for_package ( db : & dyn Db , file : File ) -> Option < Vec < Name > > {
135+ fn is_submodule (
136+ is_dir : bool ,
137+ is_file : bool ,
138+ basename : Option < & str > ,
139+ extension : Option < & str > ,
140+ ) -> bool {
141+ is_dir
142+ || ( is_file
143+ && matches ! ( extension, Some ( "py" | "pyi" ) )
144+ && !matches ! ( basename, Some ( "__init__.py" | "__init__.pyi" ) ) )
145+ }
127146
128- let path = SystemOrVendoredPathRef :: try_from_file ( db, module. file ( db) ) ?;
129- debug_assert ! (
130- matches!( path. file_name( ) , Some ( "__init__.py" | "__init__.pyi" ) ) ,
131- "expected package file `{:?}` to be `__init__.py` or `__init__.pyi`" ,
132- path. file_name( ) ,
133- ) ;
134-
135- Some ( match path. parent ( ) ? {
136- SystemOrVendoredPathRef :: System ( parent_directory) => {
137- // Read the revision on the corresponding file root to
138- // register an explicit dependency on this directory
139- // tree. When the revision gets bumped, the cache
140- // that Salsa creates does for this routine will be
141- // invalidated.
142- if let Some ( root) = db. files ( ) . root ( db, parent_directory) {
143- let _ = root. revision ( db) ;
144- }
145-
146- db. system ( )
147- . read_directory ( parent_directory)
148- . inspect_err ( |err| {
149- tracing:: debug!(
150- "Failed to read {parent_directory:?} when looking for \
151- its possible submodules: {err}"
152- ) ;
153- } )
154- . ok ( ) ?
155- . flatten ( )
156- . filter ( |entry| {
157- let ty = entry. file_type ( ) ;
158- let path = entry. path ( ) ;
159- is_submodule (
160- ty. is_directory ( ) ,
161- ty. is_file ( ) ,
162- path. file_name ( ) ,
163- path. extension ( ) ,
164- )
165- } )
166- . filter_map ( |entry| {
167- let stem = entry. path ( ) . file_stem ( ) ?;
168- is_identifier ( stem) . then ( || Name :: from ( stem) )
169- } )
170- . collect ( )
147+ let path = SystemOrVendoredPathRef :: try_from_file ( db, file) ?;
148+ debug_assert ! (
149+ matches!( path. file_name( ) , Some ( "__init__.py" | "__init__.pyi" ) ) ,
150+ "expected package file `{:?}` to be `__init__.py` or `__init__.pyi`" ,
151+ path. file_name( ) ,
152+ ) ;
153+
154+ Some ( match path. parent ( ) ? {
155+ SystemOrVendoredPathRef :: System ( parent_directory) => {
156+ // Read the revision on the corresponding file root to
157+ // register an explicit dependency on this directory
158+ // tree. When the revision gets bumped, the cache
159+ // that Salsa creates does for this routine will be
160+ // invalidated.
161+ if let Some ( root) = db. files ( ) . root ( db, parent_directory) {
162+ let _ = root. revision ( db) ;
171163 }
172- SystemOrVendoredPathRef :: Vendored ( parent_directory ) => db
173- . vendored ( )
164+
165+ db . system ( )
174166 . read_directory ( parent_directory)
175- . into_iter ( )
167+ . inspect_err ( |err| {
168+ tracing:: debug!(
169+ "Failed to read {parent_directory:?} when looking for \
170+ its possible submodules: {err}"
171+ ) ;
172+ } )
173+ . ok ( ) ?
174+ . flatten ( )
176175 . filter ( |entry| {
177176 let ty = entry. file_type ( ) ;
178177 let path = entry. path ( ) ;
@@ -187,24 +186,28 @@ impl<'db> Module<'db> {
187186 let stem = entry. path ( ) . file_stem ( ) ?;
188187 is_identifier ( stem) . then ( || Name :: from ( stem) )
189188 } )
190- . collect ( ) ,
191- } )
192- }
193- }
194-
195- impl std:: fmt:: Debug for Module < ' _ > {
196- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
197- salsa:: with_attached_database ( |db| {
198- f. debug_struct ( "Module" )
199- . field ( "name" , & self . name ( db) )
200- . field ( "kind" , & self . kind ( db) )
201- . field ( "file" , & self . file ( db) )
202- . field ( "search_path" , & self . search_path ( db) )
203- . field ( "known" , & self . known ( db) )
204- . finish ( )
205- } )
206- . unwrap_or_else ( || f. debug_tuple ( "Module" ) . field ( & self . as_id ( ) ) . finish ( ) )
207- }
189+ . collect ( )
190+ }
191+ SystemOrVendoredPathRef :: Vendored ( parent_directory) => db
192+ . vendored ( )
193+ . read_directory ( parent_directory)
194+ . into_iter ( )
195+ . filter ( |entry| {
196+ let ty = entry. file_type ( ) ;
197+ let path = entry. path ( ) ;
198+ is_submodule (
199+ ty. is_directory ( ) ,
200+ ty. is_file ( ) ,
201+ path. file_name ( ) ,
202+ path. extension ( ) ,
203+ )
204+ } )
205+ . filter_map ( |entry| {
206+ let stem = entry. path ( ) . file_stem ( ) ?;
207+ is_identifier ( stem) . then ( || Name :: from ( stem) )
208+ } )
209+ . collect ( ) ,
210+ } )
208211}
209212
210213/// A module that resolves to a file (`lib.py` or `package/__init__.py`)
0 commit comments