@@ -14,52 +14,76 @@ use super::MapEntry::*;
14
14
use rustc_front:: hir:: * ;
15
15
use rustc_front:: util;
16
16
use rustc_front:: visit:: { self , Visitor } ;
17
+ use middle:: def_id:: { CRATE_DEF_INDEX , DefIndex } ;
17
18
use std:: iter:: repeat;
18
19
use syntax:: ast:: { NodeId , CRATE_NODE_ID , DUMMY_NODE_ID } ;
19
20
use syntax:: codemap:: Span ;
20
- use util:: nodemap:: NodeSet ;
21
21
22
22
/// A Visitor that walks over an AST and collects Node's into an AST
23
23
/// Map.
24
24
pub struct NodeCollector < ' ast > {
25
25
pub map : Vec < MapEntry < ' ast > > ,
26
- pub definitions_map : NodeSet ,
26
+ pub definitions : Definitions ,
27
27
pub parent_node : NodeId ,
28
28
}
29
29
30
30
impl < ' ast > NodeCollector < ' ast > {
31
31
pub fn root ( ) -> NodeCollector < ' ast > {
32
32
let mut collector = NodeCollector {
33
33
map : vec ! [ ] ,
34
- definitions_map : NodeSet ( ) ,
34
+ definitions : Definitions :: new ( ) ,
35
35
parent_node : CRATE_NODE_ID ,
36
36
} ;
37
37
collector. insert_entry ( CRATE_NODE_ID , RootCrate ) ;
38
- collector. create_def ( CRATE_NODE_ID ) ;
39
- collector. create_def ( DUMMY_NODE_ID ) ;
38
+
39
+ let result = collector. create_def_with_parent ( None , CRATE_NODE_ID , DefPathData :: CrateRoot ) ;
40
+ assert_eq ! ( result, CRATE_DEF_INDEX ) ;
41
+
42
+ collector. create_def_with_parent ( Some ( CRATE_DEF_INDEX ) , DUMMY_NODE_ID , DefPathData :: Misc ) ;
43
+
40
44
collector
41
45
}
42
46
43
47
pub fn extend ( parent : & ' ast InlinedParent ,
44
48
parent_node : NodeId ,
49
+ parent_def_path : DefPath ,
45
50
map : Vec < MapEntry < ' ast > > ,
46
- definitions_map : NodeSet )
51
+ definitions : Definitions )
47
52
-> NodeCollector < ' ast > {
48
53
let mut collector = NodeCollector {
49
54
map : map,
50
- definitions_map : definitions_map ,
51
- parent_node : parent_node
55
+ parent_node : parent_node ,
56
+ definitions : definitions ,
52
57
} ;
58
+
53
59
collector. insert_entry ( parent_node, RootInlinedParent ( parent) ) ;
60
+ collector. create_def ( parent_node, DefPathData :: InlinedRoot ( parent_def_path) ) ;
54
61
55
62
collector
56
63
}
57
64
58
- fn create_def ( & mut self , node : NodeId ) {
59
- let is_new = self . definitions_map . insert ( node) ;
60
- assert ! ( is_new,
61
- "two entries for node id `{}` -- previous is `{:?}`" ,
62
- node, node) ;
65
+ fn parent_def ( & self ) -> Option < DefIndex > {
66
+ let mut parent_node = Some ( self . parent_node ) ;
67
+ while let Some ( p) = parent_node {
68
+ if let Some ( q) = self . definitions . opt_def_index ( p) {
69
+ return Some ( q) ;
70
+ }
71
+ parent_node = self . map [ p as usize ] . parent_node ( ) ;
72
+ }
73
+ None
74
+ }
75
+
76
+ fn create_def ( & mut self , node_id : NodeId , data : DefPathData ) -> DefIndex {
77
+ let parent_def = self . parent_def ( ) ;
78
+ self . definitions . create_def_with_parent ( parent_def, node_id, data)
79
+ }
80
+
81
+ fn create_def_with_parent ( & mut self ,
82
+ parent : Option < DefIndex > ,
83
+ node_id : NodeId ,
84
+ data : DefPathData )
85
+ -> DefIndex {
86
+ self . definitions . create_def_with_parent ( parent, node_id, data)
63
87
}
64
88
65
89
fn insert_entry ( & mut self , id : NodeId , entry : MapEntry < ' ast > ) {
@@ -71,6 +95,11 @@ impl<'ast> NodeCollector<'ast> {
71
95
self . map [ id as usize ] = entry;
72
96
}
73
97
98
+ fn insert_def ( & mut self , id : NodeId , node : Node < ' ast > , data : DefPathData ) -> DefIndex {
99
+ self . insert ( id, node) ;
100
+ self . create_def ( id, data)
101
+ }
102
+
74
103
fn insert ( & mut self , id : NodeId , node : Node < ' ast > ) {
75
104
let entry = MapEntry :: from_node ( self . parent_node , node) ;
76
105
self . insert_entry ( id, entry) ;
@@ -85,47 +114,61 @@ impl<'ast> NodeCollector<'ast> {
85
114
86
115
impl < ' ast > Visitor < ' ast > for NodeCollector < ' ast > {
87
116
fn visit_item ( & mut self , i : & ' ast Item ) {
88
- self . insert ( i. id , NodeItem ( i) ) ;
117
+ // Pick the def data. This need not be unique, but the more
118
+ // information we encapsulate into
119
+ let def_data = match i. node {
120
+ ItemDefaultImpl ( ..) | ItemImpl ( ..) => DefPathData :: Impl ,
121
+ ItemEnum ( ..) | ItemStruct ( ..) | ItemTrait ( ..) => DefPathData :: Type ( i. name ) ,
122
+ ItemExternCrate ( ..) | ItemMod ( ..) => DefPathData :: Mod ( i. name ) ,
123
+ ItemStatic ( ..) | ItemConst ( ..) | ItemFn ( ..) => DefPathData :: Value ( i. name ) ,
124
+ _ => DefPathData :: Misc ,
125
+ } ;
126
+
127
+ self . insert_def ( i. id , NodeItem ( i) , def_data) ;
89
128
90
129
let parent_node = self . parent_node ;
91
130
self . parent_node = i. id ;
92
131
93
- self . create_def ( i. id ) ;
94
-
95
132
match i. node {
96
- ItemImpl ( ..) => { }
133
+ ItemImpl ( ..) => { }
97
134
ItemEnum ( ref enum_definition, _) => {
98
135
for v in & enum_definition. variants {
99
- self . insert ( v. node . id , NodeVariant ( & * * v) ) ;
100
- self . create_def ( v. node . id ) ;
136
+ let variant_def_index =
137
+ self . insert_def ( v. node . id ,
138
+ NodeVariant ( & * * v) ,
139
+ DefPathData :: EnumVariant ( v. node . name ) ) ;
101
140
102
141
match v. node . kind {
103
142
TupleVariantKind ( ref args) => {
104
143
for arg in args {
105
- self . create_def ( arg. id ) ;
144
+ self . create_def_with_parent ( Some ( variant_def_index) ,
145
+ arg. id ,
146
+ DefPathData :: PositionalField ) ;
106
147
}
107
148
}
108
149
StructVariantKind ( ref def) => {
109
150
for field in & def. fields {
110
- self . create_def ( field. node . id ) ;
151
+ self . create_def_with_parent (
152
+ Some ( variant_def_index) ,
153
+ field. node . id ,
154
+ DefPathData :: Field ( field. node . kind ) ) ;
111
155
}
112
156
}
113
157
}
114
158
}
115
159
}
116
- ItemForeignMod ( ..) => { }
160
+ ItemForeignMod ( ..) => {
161
+ }
117
162
ItemStruct ( ref struct_def, _) => {
118
163
// If this is a tuple-like struct, register the constructor.
119
- match struct_def. ctor_id {
120
- Some ( ctor_id) => {
121
- self . insert ( ctor_id, NodeStructCtor ( & * * struct_def) ) ;
122
- self . create_def ( ctor_id) ;
123
- }
124
- None => { }
164
+ if let Some ( ctor_id) = struct_def. ctor_id {
165
+ self . insert_def ( ctor_id,
166
+ NodeStructCtor ( & * * struct_def) ,
167
+ DefPathData :: StructCtor ) ;
125
168
}
126
169
127
170
for field in & struct_def. fields {
128
- self . create_def ( field. node . id ) ;
171
+ self . create_def ( field. node . id , DefPathData :: Field ( field . node . kind ) ) ;
129
172
}
130
173
}
131
174
ItemTrait ( _, _, ref bounds, _) => {
@@ -152,8 +195,9 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
152
195
}
153
196
154
197
fn visit_foreign_item ( & mut self , foreign_item : & ' ast ForeignItem ) {
155
- self . insert ( foreign_item. id , NodeForeignItem ( foreign_item) ) ;
156
- self . create_def ( foreign_item. id ) ;
198
+ self . insert_def ( foreign_item. id ,
199
+ NodeForeignItem ( foreign_item) ,
200
+ DefPathData :: Value ( foreign_item. name ) ) ;
157
201
158
202
let parent_node = self . parent_node ;
159
203
self . parent_node = foreign_item. id ;
@@ -163,58 +207,71 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
163
207
164
208
fn visit_generics ( & mut self , generics : & ' ast Generics ) {
165
209
for ty_param in generics. ty_params . iter ( ) {
166
- self . create_def ( ty_param. id ) ;
167
- self . insert ( ty_param. id , NodeTyParam ( ty_param) ) ;
210
+ self . insert_def ( ty_param. id ,
211
+ NodeTyParam ( ty_param) ,
212
+ DefPathData :: TypeParam ( ty_param. name ) ) ;
168
213
}
169
214
170
215
visit:: walk_generics ( self , generics) ;
171
216
}
172
217
173
218
fn visit_trait_item ( & mut self , ti : & ' ast TraitItem ) {
219
+ let def_data = match ti. node {
220
+ MethodTraitItem ( ..) | ConstTraitItem ( ..) => DefPathData :: Value ( ti. name ) ,
221
+ TypeTraitItem ( ..) => DefPathData :: Type ( ti. name ) ,
222
+ } ;
223
+
174
224
self . insert ( ti. id , NodeTraitItem ( ti) ) ;
175
- self . create_def ( ti. id ) ;
225
+ self . create_def ( ti. id , def_data) ;
226
+
227
+ let parent_node = self . parent_node ;
228
+ self . parent_node = ti. id ;
176
229
177
230
match ti. node {
178
231
ConstTraitItem ( _, Some ( ref expr) ) => {
179
- self . create_def ( expr. id ) ;
232
+ self . create_def ( expr. id , DefPathData :: Initializer ) ;
180
233
}
181
234
_ => { }
182
235
}
183
236
184
- let parent_node = self . parent_node ;
185
- self . parent_node = ti. id ;
186
237
visit:: walk_trait_item ( self , ti) ;
238
+
187
239
self . parent_node = parent_node;
188
240
}
189
241
190
242
fn visit_impl_item ( & mut self , ii : & ' ast ImplItem ) {
191
- self . insert ( ii. id , NodeImplItem ( ii) ) ;
192
- self . create_def ( ii. id ) ;
243
+ let def_data = match ii. node {
244
+ MethodImplItem ( ..) | ConstImplItem ( ..) => DefPathData :: Value ( ii. name ) ,
245
+ TypeImplItem ( ..) => DefPathData :: Type ( ii. name ) ,
246
+ } ;
247
+
248
+ self . insert_def ( ii. id , NodeImplItem ( ii) , def_data) ;
249
+
250
+ let parent_node = self . parent_node ;
251
+ self . parent_node = ii. id ;
193
252
194
253
match ii. node {
195
254
ConstImplItem ( _, ref expr) => {
196
- self . create_def ( expr. id ) ;
255
+ self . create_def ( expr. id , DefPathData :: Initializer ) ;
197
256
}
198
257
_ => { }
199
258
}
200
259
201
- let parent_node = self . parent_node ;
202
- self . parent_node = ii. id ;
203
260
visit:: walk_impl_item ( self , ii) ;
261
+
204
262
self . parent_node = parent_node;
205
263
}
206
264
207
265
fn visit_pat ( & mut self , pat : & ' ast Pat ) {
208
266
let maybe_binding = match pat. node {
209
- PatIdent ( .. ) => true ,
210
- _ => false
267
+ PatIdent ( _ , id , _ ) => Some ( id . node ) ,
268
+ _ => None
211
269
} ;
212
270
213
- self . insert ( pat. id ,
214
- if maybe_binding { NodeLocal ( pat) } else { NodePat ( pat) } ) ;
215
-
216
- if maybe_binding {
217
- self . create_def ( pat. id ) ;
271
+ if let Some ( id) = maybe_binding {
272
+ self . insert_def ( pat. id , NodeLocal ( pat) , DefPathData :: Binding ( id. name ) ) ;
273
+ } else {
274
+ self . insert ( pat. id , NodePat ( pat) ) ;
218
275
}
219
276
220
277
let parent_node = self . parent_node ;
@@ -227,8 +284,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
227
284
self . insert ( expr. id , NodeExpr ( expr) ) ;
228
285
229
286
match expr. node {
230
- ExprClosure ( ..) => self . create_def ( expr. id ) ,
231
- _ => ( ) ,
287
+ ExprClosure ( ..) => { self . create_def ( expr. id , DefPathData :: ClosureExpr ) ; }
288
+ _ => { }
232
289
}
233
290
234
291
let parent_node = self . parent_node ;
@@ -276,12 +333,12 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
276
333
}
277
334
278
335
fn visit_lifetime_def ( & mut self , def : & ' ast LifetimeDef ) {
279
- self . create_def ( def. lifetime . id ) ;
336
+ self . create_def ( def. lifetime . id , DefPathData :: LifetimeDef ( def . lifetime . name ) ) ;
280
337
self . visit_lifetime ( & def. lifetime ) ;
281
338
}
282
339
283
340
fn visit_macro_def ( & mut self , macro_def : & ' ast MacroDef ) {
284
- self . create_def ( macro_def. id ) ;
341
+ self . create_def ( macro_def. id , DefPathData :: MacroDef ( macro_def . name ) ) ;
285
342
}
286
343
}
287
344
0 commit comments