@@ -121,27 +121,28 @@ pub enum Node<'ast> {
121
121
NodeLifetime ( & ' ast Lifetime ) ,
122
122
}
123
123
124
- /// Represents an entry and its parent Node ID
124
+ /// Represents an entry and its parent NodeID and parent_node NodeID, see
125
+ /// get_parent_node for the distinction.
125
126
/// The odd layout is to bring down the total size.
126
127
#[ derive( Copy , Debug ) ]
127
128
enum MapEntry < ' ast > {
128
129
/// Placeholder for holes in the map.
129
130
NotPresent ,
130
131
131
- /// All the node types, with a parent ID.
132
- EntryItem ( NodeId , & ' ast Item ) ,
133
- EntryForeignItem ( NodeId , & ' ast ForeignItem ) ,
134
- EntryTraitItem ( NodeId , & ' ast TraitItem ) ,
135
- EntryImplItem ( NodeId , & ' ast ImplItem ) ,
136
- EntryVariant ( NodeId , & ' ast Variant ) ,
137
- EntryExpr ( NodeId , & ' ast Expr ) ,
138
- EntryStmt ( NodeId , & ' ast Stmt ) ,
139
- EntryArg ( NodeId , & ' ast Pat ) ,
140
- EntryLocal ( NodeId , & ' ast Pat ) ,
141
- EntryPat ( NodeId , & ' ast Pat ) ,
142
- EntryBlock ( NodeId , & ' ast Block ) ,
143
- EntryStructCtor ( NodeId , & ' ast StructDef ) ,
144
- EntryLifetime ( NodeId , & ' ast Lifetime ) ,
132
+ /// All the node types, with a parent and scope ID.
133
+ EntryItem ( NodeId , NodeId , & ' ast Item ) ,
134
+ EntryForeignItem ( NodeId , NodeId , & ' ast ForeignItem ) ,
135
+ EntryTraitItem ( NodeId , NodeId , & ' ast TraitItem ) ,
136
+ EntryImplItem ( NodeId , NodeId , & ' ast ImplItem ) ,
137
+ EntryVariant ( NodeId , NodeId , & ' ast Variant ) ,
138
+ EntryExpr ( NodeId , NodeId , & ' ast Expr ) ,
139
+ EntryStmt ( NodeId , NodeId , & ' ast Stmt ) ,
140
+ EntryArg ( NodeId , NodeId , & ' ast Pat ) ,
141
+ EntryLocal ( NodeId , NodeId , & ' ast Pat ) ,
142
+ EntryPat ( NodeId , NodeId , & ' ast Pat ) ,
143
+ EntryBlock ( NodeId , NodeId , & ' ast Block ) ,
144
+ EntryStructCtor ( NodeId , NodeId , & ' ast StructDef ) ,
145
+ EntryLifetime ( NodeId , NodeId , & ' ast Lifetime ) ,
145
146
146
147
/// Roots for node trees.
147
148
RootCrate ,
@@ -161,58 +162,77 @@ struct InlinedParent {
161
162
}
162
163
163
164
impl < ' ast > MapEntry < ' ast > {
164
- fn from_node ( p : NodeId , node : Node < ' ast > ) -> MapEntry < ' ast > {
165
+ fn from_node ( p : NodeId , s : NodeId , node : Node < ' ast > ) -> MapEntry < ' ast > {
165
166
match node {
166
- NodeItem ( n) => EntryItem ( p, n) ,
167
- NodeForeignItem ( n) => EntryForeignItem ( p, n) ,
168
- NodeTraitItem ( n) => EntryTraitItem ( p, n) ,
169
- NodeImplItem ( n) => EntryImplItem ( p, n) ,
170
- NodeVariant ( n) => EntryVariant ( p, n) ,
171
- NodeExpr ( n) => EntryExpr ( p, n) ,
172
- NodeStmt ( n) => EntryStmt ( p, n) ,
173
- NodeArg ( n) => EntryArg ( p, n) ,
174
- NodeLocal ( n) => EntryLocal ( p, n) ,
175
- NodePat ( n) => EntryPat ( p, n) ,
176
- NodeBlock ( n) => EntryBlock ( p, n) ,
177
- NodeStructCtor ( n) => EntryStructCtor ( p, n) ,
178
- NodeLifetime ( n) => EntryLifetime ( p, n)
167
+ NodeItem ( n) => EntryItem ( p, s , n) ,
168
+ NodeForeignItem ( n) => EntryForeignItem ( p, s , n) ,
169
+ NodeTraitItem ( n) => EntryTraitItem ( p, s , n) ,
170
+ NodeImplItem ( n) => EntryImplItem ( p, s , n) ,
171
+ NodeVariant ( n) => EntryVariant ( p, s , n) ,
172
+ NodeExpr ( n) => EntryExpr ( p, s , n) ,
173
+ NodeStmt ( n) => EntryStmt ( p, s , n) ,
174
+ NodeArg ( n) => EntryArg ( p, s , n) ,
175
+ NodeLocal ( n) => EntryLocal ( p, s , n) ,
176
+ NodePat ( n) => EntryPat ( p, s , n) ,
177
+ NodeBlock ( n) => EntryBlock ( p, s , n) ,
178
+ NodeStructCtor ( n) => EntryStructCtor ( p, s , n) ,
179
+ NodeLifetime ( n) => EntryLifetime ( p, s , n)
179
180
}
180
181
}
181
182
182
183
fn parent ( self ) -> Option < NodeId > {
183
184
Some ( match self {
184
- EntryItem ( id, _) => id,
185
- EntryForeignItem ( id, _) => id,
186
- EntryTraitItem ( id, _) => id,
187
- EntryImplItem ( id, _) => id,
188
- EntryVariant ( id, _) => id,
189
- EntryExpr ( id, _) => id,
190
- EntryStmt ( id, _) => id,
191
- EntryArg ( id, _) => id,
192
- EntryLocal ( id, _) => id,
193
- EntryPat ( id, _) => id,
194
- EntryBlock ( id, _) => id,
195
- EntryStructCtor ( id, _) => id,
196
- EntryLifetime ( id, _) => id,
185
+ EntryItem ( id, _, _) => id,
186
+ EntryForeignItem ( id, _, _) => id,
187
+ EntryTraitItem ( id, _, _) => id,
188
+ EntryImplItem ( id, _, _) => id,
189
+ EntryVariant ( id, _, _) => id,
190
+ EntryExpr ( id, _, _) => id,
191
+ EntryStmt ( id, _, _) => id,
192
+ EntryArg ( id, _, _) => id,
193
+ EntryLocal ( id, _, _) => id,
194
+ EntryPat ( id, _, _) => id,
195
+ EntryBlock ( id, _, _) => id,
196
+ EntryStructCtor ( id, _, _) => id,
197
+ EntryLifetime ( id, _, _) => id,
198
+ _ => return None
199
+ } )
200
+ }
201
+
202
+ fn parent_node ( self ) -> Option < NodeId > {
203
+ Some ( match self {
204
+ EntryItem ( _, id, _) => id,
205
+ EntryForeignItem ( _, id, _) => id,
206
+ EntryTraitItem ( _, id, _) => id,
207
+ EntryImplItem ( _, id, _) => id,
208
+ EntryVariant ( _, id, _) => id,
209
+ EntryExpr ( _, id, _) => id,
210
+ EntryStmt ( _, id, _) => id,
211
+ EntryArg ( _, id, _) => id,
212
+ EntryLocal ( _, id, _) => id,
213
+ EntryPat ( _, id, _) => id,
214
+ EntryBlock ( _, id, _) => id,
215
+ EntryStructCtor ( _, id, _) => id,
216
+ EntryLifetime ( _, id, _) => id,
197
217
_ => return None
198
218
} )
199
219
}
200
220
201
221
fn to_node ( self ) -> Option < Node < ' ast > > {
202
222
Some ( match self {
203
- EntryItem ( _, n) => NodeItem ( n) ,
204
- EntryForeignItem ( _, n) => NodeForeignItem ( n) ,
205
- EntryTraitItem ( _, n) => NodeTraitItem ( n) ,
206
- EntryImplItem ( _, n) => NodeImplItem ( n) ,
207
- EntryVariant ( _, n) => NodeVariant ( n) ,
208
- EntryExpr ( _, n) => NodeExpr ( n) ,
209
- EntryStmt ( _, n) => NodeStmt ( n) ,
210
- EntryArg ( _, n) => NodeArg ( n) ,
211
- EntryLocal ( _, n) => NodeLocal ( n) ,
212
- EntryPat ( _, n) => NodePat ( n) ,
213
- EntryBlock ( _, n) => NodeBlock ( n) ,
214
- EntryStructCtor ( _, n) => NodeStructCtor ( n) ,
215
- EntryLifetime ( _, n) => NodeLifetime ( n) ,
223
+ EntryItem ( _, _ , n) => NodeItem ( n) ,
224
+ EntryForeignItem ( _, _ , n) => NodeForeignItem ( n) ,
225
+ EntryTraitItem ( _, _ , n) => NodeTraitItem ( n) ,
226
+ EntryImplItem ( _, _ , n) => NodeImplItem ( n) ,
227
+ EntryVariant ( _, _ , n) => NodeVariant ( n) ,
228
+ EntryExpr ( _, _ , n) => NodeExpr ( n) ,
229
+ EntryStmt ( _, _ , n) => NodeStmt ( n) ,
230
+ EntryArg ( _, _ , n) => NodeArg ( n) ,
231
+ EntryLocal ( _, _ , n) => NodeLocal ( n) ,
232
+ EntryPat ( _, _ , n) => NodePat ( n) ,
233
+ EntryBlock ( _, _ , n) => NodeBlock ( n) ,
234
+ EntryStructCtor ( _, _ , n) => NodeStructCtor ( n) ,
235
+ EntryLifetime ( _, _ , n) => NodeLifetime ( n) ,
216
236
_ => return None
217
237
} )
218
238
}
@@ -289,6 +309,18 @@ impl<'ast> Map<'ast> {
289
309
self . find_entry ( id) . and_then ( |x| x. parent ( ) ) . unwrap_or ( id)
290
310
}
291
311
312
+ /// Similar to get_parent, returns the parent node id or id if there is no
313
+ /// parent.
314
+ /// This function returns the most direct parent in the AST, whereas get_parent
315
+ /// returns the enclosing item. Note that this might not be the actual parent
316
+ /// node in the AST - some kinds of nodes are not in the map and these will
317
+ /// never appear as the parent_node. So you can always walk the parent_nodes
318
+ /// from a node to the root of the ast (unless you get the same id back here
319
+ /// that can happen if the id is not in the map itself or is just weird).
320
+ pub fn get_parent_node ( & self , id : NodeId ) -> NodeId {
321
+ self . find_entry ( id) . and_then ( |x| x. parent_node ( ) ) . unwrap_or ( id)
322
+ }
323
+
292
324
pub fn get_parent_did ( & self , id : NodeId ) -> DefId {
293
325
let parent = self . get_parent ( id) ;
294
326
match self . find_entry ( parent) {
@@ -301,7 +333,7 @@ impl<'ast> Map<'ast> {
301
333
pub fn get_foreign_abi ( & self , id : NodeId ) -> abi:: Abi {
302
334
let parent = self . get_parent ( id) ;
303
335
let abi = match self . find_entry ( parent) {
304
- Some ( EntryItem ( _, i) ) => {
336
+ Some ( EntryItem ( _, _ , i) ) => {
305
337
match i. node {
306
338
ItemForeignMod ( ref nm) => Some ( nm. abi ) ,
307
339
_ => None
@@ -591,11 +623,11 @@ impl<'a, 'ast> Iterator for NodesMatchingSuffix<'a, 'ast> {
591
623
}
592
624
self . idx += 1 ;
593
625
let ( p, name) = match self . map . find_entry ( idx) {
594
- Some ( EntryItem ( p, n) ) => ( p, n. name ( ) ) ,
595
- Some ( EntryForeignItem ( p, n) ) => ( p, n. name ( ) ) ,
596
- Some ( EntryTraitItem ( p, n) ) => ( p, n. name ( ) ) ,
597
- Some ( EntryImplItem ( p, n) ) => ( p, n. name ( ) ) ,
598
- Some ( EntryVariant ( p, n) ) => ( p, n. name ( ) ) ,
626
+ Some ( EntryItem ( p, _ , n) ) => ( p, n. name ( ) ) ,
627
+ Some ( EntryForeignItem ( p, _ , n) ) => ( p, n. name ( ) ) ,
628
+ Some ( EntryTraitItem ( p, _ , n) ) => ( p, n. name ( ) ) ,
629
+ Some ( EntryImplItem ( p, _ , n) ) => ( p, n. name ( ) ) ,
630
+ Some ( EntryVariant ( p, _ , n) ) => ( p, n. name ( ) ) ,
599
631
_ => continue ,
600
632
} ;
601
633
if self . matches_names ( p, name) {
@@ -648,7 +680,8 @@ impl<F: FoldOps> Folder for IdAndSpanUpdater<F> {
648
680
struct NodeCollector < ' ast > {
649
681
map : Vec < MapEntry < ' ast > > ,
650
682
/// The node in which we are currently mapping (an item or a method).
651
- parent : NodeId
683
+ parent : NodeId ,
684
+ parent_node : NodeId ,
652
685
}
653
686
654
687
impl < ' ast > NodeCollector < ' ast > {
@@ -662,7 +695,7 @@ impl<'ast> NodeCollector<'ast> {
662
695
}
663
696
664
697
fn insert ( & mut self , id : NodeId , node : Node < ' ast > ) {
665
- let entry = MapEntry :: from_node ( self . parent , node) ;
698
+ let entry = MapEntry :: from_node ( self . parent , self . parent_node , node) ;
666
699
self . insert_entry ( id, entry) ;
667
700
}
668
701
@@ -678,6 +711,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
678
711
self . insert ( i. id , NodeItem ( i) ) ;
679
712
let parent = self . parent ;
680
713
self . parent = i. id ;
714
+ let parent_node = self . parent_node ;
715
+ self . parent_node = i. id ;
681
716
match i. node {
682
717
ItemImpl ( _, _, _, _, _, ref impl_items) => {
683
718
for ii in impl_items {
@@ -728,64 +763,93 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
728
763
}
729
764
visit:: walk_item ( self , i) ;
730
765
self . parent = parent;
766
+ self . parent_node = parent_node;
731
767
}
732
768
733
769
fn visit_trait_item ( & mut self , ti : & ' ast TraitItem ) {
734
770
let parent = self . parent ;
735
771
self . parent = ti. id ;
772
+ let parent_node = self . parent_node ;
773
+ self . parent_node = ti. id ;
736
774
visit:: walk_trait_item ( self , ti) ;
737
775
self . parent = parent;
776
+ self . parent_node = parent_node;
738
777
}
739
778
740
779
fn visit_impl_item ( & mut self , ii : & ' ast ImplItem ) {
741
780
let parent = self . parent ;
742
781
self . parent = ii. id ;
782
+ let parent_node = self . parent_node ;
783
+ self . parent_node = ii. id ;
743
784
visit:: walk_impl_item ( self , ii) ;
744
785
self . parent = parent;
786
+ self . parent_node = parent_node;
745
787
}
746
788
747
789
fn visit_pat ( & mut self , pat : & ' ast Pat ) {
790
+ let parent_node = self . parent_node ;
791
+ self . parent_node = pat. id ;
748
792
self . insert ( pat. id , match pat. node {
749
793
// Note: this is at least *potentially* a pattern...
750
794
PatIdent ( ..) => NodeLocal ( pat) ,
751
795
_ => NodePat ( pat)
752
796
} ) ;
753
797
visit:: walk_pat ( self , pat) ;
798
+ self . parent_node = parent_node;
754
799
}
755
800
756
801
fn visit_expr ( & mut self , expr : & ' ast Expr ) {
802
+ let parent_node = self . parent_node ;
803
+ self . parent_node = expr. id ;
757
804
self . insert ( expr. id , NodeExpr ( expr) ) ;
758
805
visit:: walk_expr ( self , expr) ;
806
+ self . parent_node = parent_node;
759
807
}
760
808
761
809
fn visit_stmt ( & mut self , stmt : & ' ast Stmt ) {
762
- self . insert ( ast_util:: stmt_id ( stmt) , NodeStmt ( stmt) ) ;
810
+ let id = ast_util:: stmt_id ( stmt) ;
811
+ let parent_node = self . parent_node ;
812
+ self . parent_node = id;
813
+ self . insert ( id, NodeStmt ( stmt) ) ;
763
814
visit:: walk_stmt ( self , stmt) ;
815
+ self . parent_node = parent_node;
764
816
}
765
817
766
818
fn visit_fn ( & mut self , fk : visit:: FnKind < ' ast > , fd : & ' ast FnDecl ,
767
- b : & ' ast Block , s : Span , _: NodeId ) {
819
+ b : & ' ast Block , s : Span , id : NodeId ) {
820
+ let parent_node = self . parent_node ;
821
+ self . parent_node = id;
768
822
self . visit_fn_decl ( fd) ;
769
823
visit:: walk_fn ( self , fk, fd, b, s) ;
824
+ self . parent_node = parent_node;
770
825
}
771
826
772
827
fn visit_ty ( & mut self , ty : & ' ast Ty ) {
828
+ let parent_node = self . parent_node ;
829
+ self . parent_node = ty. id ;
773
830
match ty. node {
774
831
TyBareFn ( ref fd) => {
775
832
self . visit_fn_decl ( & * fd. decl ) ;
776
833
}
777
834
_ => { }
778
835
}
779
836
visit:: walk_ty ( self , ty) ;
837
+ self . parent_node = parent_node;
780
838
}
781
839
782
840
fn visit_block ( & mut self , block : & ' ast Block ) {
841
+ let parent_node = self . parent_node ;
842
+ self . parent_node = block. id ;
783
843
self . insert ( block. id , NodeBlock ( block) ) ;
784
844
visit:: walk_block ( self , block) ;
845
+ self . parent_node = parent_node;
785
846
}
786
847
787
848
fn visit_lifetime_ref ( & mut self , lifetime : & ' ast Lifetime ) {
849
+ let parent_node = self . parent_node ;
850
+ self . parent_node = lifetime. id ;
788
851
self . insert ( lifetime. id , NodeLifetime ( lifetime) ) ;
852
+ self . parent_node = parent_node;
789
853
}
790
854
791
855
fn visit_lifetime_def ( & mut self , def : & ' ast LifetimeDef ) {
@@ -809,7 +873,8 @@ pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map
809
873
810
874
let mut collector = NodeCollector {
811
875
map : vec ! [ ] ,
812
- parent : CRATE_NODE_ID
876
+ parent : CRATE_NODE_ID ,
877
+ parent_node : CRATE_NODE_ID ,
813
878
} ;
814
879
collector. insert_entry ( CRATE_NODE_ID , RootCrate ) ;
815
880
visit:: walk_crate ( & mut collector, & forest. krate ) ;
@@ -866,7 +931,8 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
866
931
867
932
let mut collector = NodeCollector {
868
933
map : mem:: replace ( & mut * map. map . borrow_mut ( ) , vec ! [ ] ) ,
869
- parent : fld. new_id ( DUMMY_NODE_ID )
934
+ parent : fld. new_id ( DUMMY_NODE_ID ) ,
935
+ parent_node : fld. new_id ( DUMMY_NODE_ID ) ,
870
936
} ;
871
937
let ii_parent_id = collector. parent ;
872
938
collector. insert_entry ( ii_parent_id, RootInlinedParent ( ii_parent) ) ;
0 commit comments