11use self :: collector:: NodeCollector ;
22
3- use crate :: hir:: { AttributeMap , IndexedHir , Owner } ;
3+ use crate :: hir:: { AttributeMap , IndexedHir , ModuleItems , Owner } ;
44use crate :: ty:: TyCtxt ;
55use rustc_ast as ast;
66use rustc_data_structures:: fingerprint:: Fingerprint ;
77use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
88use rustc_data_structures:: svh:: Svh ;
9+ use rustc_data_structures:: sync:: { self , par_iter} ;
910use rustc_hir:: def:: { DefKind , Res } ;
1011use rustc_hir:: def_id:: { CrateNum , DefId , LocalDefId , CRATE_DEF_ID , CRATE_DEF_INDEX , LOCAL_CRATE } ;
1112use rustc_hir:: definitions:: { DefKey , DefPath , DefPathHash } ;
@@ -19,6 +20,7 @@ use rustc_span::source_map::Spanned;
1920use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
2021use rustc_span:: Span ;
2122use rustc_target:: spec:: abi:: Abi ;
23+ use std:: collections:: BTreeSet ;
2224
2325pub mod blocks;
2426mod collector;
@@ -558,6 +560,31 @@ impl<'hir> Map<'hir> {
558560 }
559561 }
560562
563+ pub fn for_each_module ( & self , f : impl Fn ( LocalDefId ) ) {
564+ let mut queue = BTreeSet :: default ( ) ;
565+ queue. insert ( CRATE_DEF_ID ) ;
566+
567+ while let Some ( id) = queue. pop_first ( ) {
568+ f ( id) ;
569+ let items = self . tcx . hir_module_items ( id) ;
570+ queue. extend ( items. submodules . iter ( ) . copied ( ) )
571+ }
572+ }
573+
574+ pub fn par_for_each_module ( & self , f : impl Fn ( LocalDefId ) + sync:: Sync ) {
575+ use rustc_data_structures:: sync:: ParallelIterator ;
576+ par_iter_submodules ( self . tcx , CRATE_DEF_ID , & f) ;
577+
578+ fn par_iter_submodules < F > ( tcx : TyCtxt < ' _ > , module : LocalDefId , f : & F )
579+ where
580+ F : Fn ( LocalDefId ) + sync:: Sync ,
581+ {
582+ ( * f) ( module) ;
583+ let items = tcx. hir_module_items ( module) ;
584+ par_iter ( & items. submodules ) . for_each ( |& sm| par_iter_submodules ( tcx, sm, f) ) ;
585+ }
586+ }
587+
561588 /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
562589 /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`.
563590 pub fn parent_iter ( & self , current_id : HirId ) -> ParentHirIterator < ' _ , ' hir > {
@@ -1118,3 +1145,63 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String {
11181145 None => format ! ( "unknown node{}" , id_str) ,
11191146 }
11201147}
1148+
1149+ pub ( super ) fn hir_module_items ( tcx : TyCtxt < ' _ > , module_id : LocalDefId ) -> ModuleItems {
1150+ let mut collector = ModuleCollector {
1151+ tcx,
1152+ submodules : BTreeSet :: default ( ) ,
1153+ items : BTreeSet :: default ( ) ,
1154+ trait_items : BTreeSet :: default ( ) ,
1155+ impl_items : BTreeSet :: default ( ) ,
1156+ foreign_items : BTreeSet :: default ( ) ,
1157+ } ;
1158+
1159+ let ( hir_mod, span, hir_id) = tcx. hir ( ) . get_module ( module_id) ;
1160+ collector. visit_mod ( hir_mod, span, hir_id) ;
1161+
1162+ let ModuleCollector { submodules, items, trait_items, impl_items, foreign_items, .. } =
1163+ collector;
1164+ return ModuleItems { submodules, items, trait_items, impl_items, foreign_items } ;
1165+
1166+ struct ModuleCollector < ' tcx > {
1167+ tcx : TyCtxt < ' tcx > ,
1168+ submodules : BTreeSet < LocalDefId > ,
1169+ items : BTreeSet < ItemId > ,
1170+ trait_items : BTreeSet < TraitItemId > ,
1171+ impl_items : BTreeSet < ImplItemId > ,
1172+ foreign_items : BTreeSet < ForeignItemId > ,
1173+ }
1174+
1175+ impl < ' hir > Visitor < ' hir > for ModuleCollector < ' hir > {
1176+ type Map = Map < ' hir > ;
1177+
1178+ fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
1179+ intravisit:: NestedVisitorMap :: All ( self . tcx . hir ( ) )
1180+ }
1181+
1182+ fn visit_item ( & mut self , item : & ' hir Item < ' hir > ) {
1183+ self . items . insert ( item. item_id ( ) ) ;
1184+ if let ItemKind :: Mod ( ..) = item. kind {
1185+ // If this declares another module, do not recurse inside it.
1186+ self . submodules . insert ( item. def_id ) ;
1187+ } else {
1188+ intravisit:: walk_item ( self , item)
1189+ }
1190+ }
1191+
1192+ fn visit_trait_item ( & mut self , item : & ' hir TraitItem < ' hir > ) {
1193+ self . trait_items . insert ( item. trait_item_id ( ) ) ;
1194+ intravisit:: walk_trait_item ( self , item)
1195+ }
1196+
1197+ fn visit_impl_item ( & mut self , item : & ' hir ImplItem < ' hir > ) {
1198+ self . impl_items . insert ( item. impl_item_id ( ) ) ;
1199+ intravisit:: walk_impl_item ( self , item)
1200+ }
1201+
1202+ fn visit_foreign_item ( & mut self , item : & ' hir ForeignItem < ' hir > ) {
1203+ self . foreign_items . insert ( item. foreign_item_id ( ) ) ;
1204+ intravisit:: walk_foreign_item ( self , item)
1205+ }
1206+ }
1207+ }
0 commit comments