@@ -6,6 +6,7 @@ use rustc_ast as ast;
6
6
use rustc_data_structures:: fingerprint:: Fingerprint ;
7
7
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
8
8
use rustc_data_structures:: svh:: Svh ;
9
+ use rustc_data_structures:: sync:: { par_for_each_in, Send , Sync } ;
9
10
use rustc_hir:: def:: { DefKind , Res } ;
10
11
use rustc_hir:: def_id:: { CrateNum , DefId , LocalDefId , CRATE_DEF_ID , LOCAL_CRATE } ;
11
12
use rustc_hir:: definitions:: { DefKey , DefPath , DefPathHash } ;
@@ -156,6 +157,21 @@ impl<'hir> Map<'hir> {
156
157
self . tcx . hir_crate ( ( ) )
157
158
}
158
159
160
+ pub fn root_module ( & self ) -> & ' hir Mod < ' hir > {
161
+ match self . tcx . hir_owner ( CRATE_DEF_ID ) . map ( |o| o. node ) {
162
+ Some ( OwnerNode :: Crate ( item) ) => item,
163
+ _ => bug ! ( ) ,
164
+ }
165
+ }
166
+
167
+ pub fn items ( & self ) -> impl Iterator < Item = & ' hir Item < ' hir > > + ' hir {
168
+ let krate = self . krate ( ) ;
169
+ krate. owners . iter ( ) . filter_map ( |owner| match owner. as_ref ( ) ? {
170
+ OwnerNode :: Item ( item) => Some ( * item) ,
171
+ _ => None ,
172
+ } )
173
+ }
174
+
159
175
pub fn def_key ( & self , def_id : LocalDefId ) -> DefKey {
160
176
// Accessing the DefKey is ok, since it is part of DefPathHash.
161
177
self . tcx . untracked_resolutions . definitions . def_key ( def_id)
@@ -475,6 +491,17 @@ impl<'hir> Map<'hir> {
475
491
Some ( ccx)
476
492
}
477
493
494
+ /// Returns an iterator of the `DefId`s for all body-owners in this
495
+ /// crate. If you would prefer to iterate over the bodies
496
+ /// themselves, you can do `self.hir().krate().body_ids.iter()`.
497
+ pub fn body_owners ( self ) -> impl Iterator < Item = LocalDefId > + ' hir {
498
+ self . krate ( ) . bodies . keys ( ) . map ( move |& body_id| self . body_owner_def_id ( body_id) )
499
+ }
500
+
501
+ pub fn par_body_owners < F : Fn ( LocalDefId ) + Sync + Send > ( self , f : F ) {
502
+ par_for_each_in ( & self . krate ( ) . bodies , |( & body_id, _) | f ( self . body_owner_def_id ( body_id) ) ) ;
503
+ }
504
+
478
505
pub fn ty_param_owner ( & self , id : HirId ) -> HirId {
479
506
match self . get ( id) {
480
507
Node :: Item ( & Item { kind : ItemKind :: Trait ( ..) | ItemKind :: TraitAlias ( ..) , .. } ) => id,
@@ -531,6 +558,45 @@ impl<'hir> Map<'hir> {
531
558
}
532
559
}
533
560
561
+ /// Visits all items in the crate in some deterministic (but
562
+ /// unspecified) order. If you just need to process every item,
563
+ /// but don't care about nesting, this method is the best choice.
564
+ ///
565
+ /// If you do care about nesting -- usually because your algorithm
566
+ /// follows lexical scoping rules -- then you want a different
567
+ /// approach. You should override `visit_nested_item` in your
568
+ /// visitor and then call `intravisit::walk_crate` instead.
569
+ pub fn visit_all_item_likes < V > ( & self , visitor : & mut V )
570
+ where
571
+ V : itemlikevisit:: ItemLikeVisitor < ' hir > ,
572
+ {
573
+ let krate = self . krate ( ) ;
574
+ for owner in krate. owners . iter ( ) . filter_map ( Option :: as_ref) {
575
+ match owner {
576
+ OwnerNode :: Item ( item) => visitor. visit_item ( item) ,
577
+ OwnerNode :: ForeignItem ( item) => visitor. visit_foreign_item ( item) ,
578
+ OwnerNode :: ImplItem ( item) => visitor. visit_impl_item ( item) ,
579
+ OwnerNode :: TraitItem ( item) => visitor. visit_trait_item ( item) ,
580
+ OwnerNode :: Crate ( _) => { }
581
+ }
582
+ }
583
+ }
584
+
585
+ /// A parallel version of `visit_all_item_likes`.
586
+ pub fn par_visit_all_item_likes < V > ( & self , visitor : & V )
587
+ where
588
+ V : itemlikevisit:: ParItemLikeVisitor < ' hir > + Sync + Send ,
589
+ {
590
+ let krate = self . krate ( ) ;
591
+ par_for_each_in ( & krate. owners . raw , |owner| match owner. as_ref ( ) {
592
+ Some ( OwnerNode :: Item ( item) ) => visitor. visit_item ( item) ,
593
+ Some ( OwnerNode :: ForeignItem ( item) ) => visitor. visit_foreign_item ( item) ,
594
+ Some ( OwnerNode :: ImplItem ( item) ) => visitor. visit_impl_item ( item) ,
595
+ Some ( OwnerNode :: TraitItem ( item) ) => visitor. visit_trait_item ( item) ,
596
+ Some ( OwnerNode :: Crate ( _) ) | None => { }
597
+ } )
598
+ }
599
+
534
600
pub fn visit_item_likes_in_module < V > ( & self , module : LocalDefId , visitor : & mut V )
535
601
where
536
602
V : ItemLikeVisitor < ' hir > ,
0 commit comments