@@ -18,31 +18,39 @@ use middle::cstore::InlinedItem;
18
18
19
19
use syntax:: ast:: * ;
20
20
use syntax:: visit;
21
- use syntax:: parse:: token;
21
+ use syntax:: parse:: token:: { self , keywords } ;
22
22
23
23
/// Creates def ids for nodes in the HIR.
24
- pub struct DefCollector < ' ast > {
24
+ pub struct DefCollector < ' a > {
25
25
// If we are walking HIR (c.f., AST), we need to keep a reference to the
26
26
// crate.
27
- hir_crate : Option < & ' ast hir:: Crate > ,
28
- definitions : & ' ast mut Definitions ,
27
+ hir_crate : Option < & ' a hir:: Crate > ,
28
+ definitions : & ' a mut Definitions ,
29
29
parent_def : Option < DefIndex > ,
30
+ pub visit_macro_invoc : Option < & ' a mut FnMut ( MacroInvocationData ) > ,
30
31
}
31
32
32
- impl < ' ast > DefCollector < ' ast > {
33
- pub fn new ( definitions : & ' ast mut Definitions ) -> DefCollector < ' ast > {
33
+ pub struct MacroInvocationData {
34
+ pub id : NodeId ,
35
+ pub def_index : DefIndex ,
36
+ pub const_integer : bool ,
37
+ }
38
+
39
+ impl < ' a > DefCollector < ' a > {
40
+ pub fn new ( definitions : & ' a mut Definitions ) -> Self {
34
41
DefCollector {
35
42
hir_crate : None ,
36
43
definitions : definitions,
37
44
parent_def : None ,
45
+ visit_macro_invoc : None ,
38
46
}
39
47
}
40
48
41
49
pub fn extend ( parent_node : NodeId ,
42
50
parent_def_path : DefPath ,
43
51
parent_def_id : DefId ,
44
- definitions : & ' ast mut Definitions )
45
- -> DefCollector < ' ast > {
52
+ definitions : & ' a mut Definitions )
53
+ -> Self {
46
54
let mut collector = DefCollector :: new ( definitions) ;
47
55
48
56
assert_eq ! ( parent_def_path. krate, parent_def_id. krate) ;
@@ -65,7 +73,7 @@ impl<'ast> DefCollector<'ast> {
65
73
self . create_def_with_parent ( Some ( CRATE_DEF_INDEX ) , DUMMY_NODE_ID , DefPathData :: Misc ) ;
66
74
}
67
75
68
- pub fn walk_item ( & mut self , ii : & ' ast InlinedItem , krate : & ' ast hir:: Crate ) {
76
+ pub fn walk_item ( & mut self , ii : & ' a InlinedItem , krate : & ' a hir:: Crate ) {
69
77
self . hir_crate = Some ( krate) ;
70
78
ii. visit ( self ) ;
71
79
}
@@ -84,29 +92,28 @@ impl<'ast> DefCollector<'ast> {
84
92
self . definitions . create_def_with_parent ( parent, node_id, data)
85
93
}
86
94
87
- fn with_parent < F : FnOnce ( & mut Self ) > ( & mut self , parent_def : DefIndex , f : F ) {
95
+ pub fn with_parent < F : FnOnce ( & mut Self ) > ( & mut self , parent_def : DefIndex , f : F ) {
88
96
let parent = self . parent_def ;
89
97
self . parent_def = Some ( parent_def) ;
90
98
f ( self ) ;
91
99
self . parent_def = parent;
92
100
}
93
101
94
- fn visit_ast_const_integer ( & mut self , expr : & Expr ) {
95
- // Find the node which will be used after lowering.
96
- if let ExprKind :: Paren ( ref inner) = expr. node {
97
- return self . visit_ast_const_integer ( inner) ;
98
- }
99
-
100
- // FIXME(eddyb) Closures should have separate
101
- // function definition IDs and expression IDs.
102
- if let ExprKind :: Closure ( ..) = expr. node {
103
- return ;
102
+ pub fn visit_ast_const_integer ( & mut self , expr : & Expr ) {
103
+ match expr. node {
104
+ // Find the node which will be used after lowering.
105
+ ExprKind :: Paren ( ref inner) => return self . visit_ast_const_integer ( inner) ,
106
+ ExprKind :: Mac ( ..) => return self . visit_macro_invoc ( expr. id , true ) ,
107
+ // FIXME(eddyb) Closures should have separate
108
+ // function definition IDs and expression IDs.
109
+ ExprKind :: Closure ( ..) => return ,
110
+ _ => { }
104
111
}
105
112
106
113
self . create_def ( expr. id , DefPathData :: Initializer ) ;
107
114
}
108
115
109
- fn visit_hir_const_integer ( & mut self , expr : & ' ast hir:: Expr ) {
116
+ fn visit_hir_const_integer ( & mut self , expr : & hir:: Expr ) {
110
117
// FIXME(eddyb) Closures should have separate
111
118
// function definition IDs and expression IDs.
112
119
if let hir:: ExprClosure ( ..) = expr. node {
@@ -115,9 +122,19 @@ impl<'ast> DefCollector<'ast> {
115
122
116
123
self . create_def ( expr. id , DefPathData :: Initializer ) ;
117
124
}
125
+
126
+ fn visit_macro_invoc ( & mut self , id : NodeId , const_integer : bool ) {
127
+ if let Some ( ref mut visit) = self . visit_macro_invoc {
128
+ visit ( MacroInvocationData {
129
+ id : id,
130
+ const_integer : const_integer,
131
+ def_index : self . parent_def . unwrap ( ) ,
132
+ } )
133
+ }
134
+ }
118
135
}
119
136
120
- impl < ' ast > visit:: Visitor for DefCollector < ' ast > {
137
+ impl < ' a > visit:: Visitor for DefCollector < ' a > {
121
138
fn visit_item ( & mut self , i : & Item ) {
122
139
debug ! ( "visit_item: {:?}" , i) ;
123
140
@@ -129,10 +146,14 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
129
146
ItemKind :: Enum ( ..) | ItemKind :: Struct ( ..) | ItemKind :: Union ( ..) | ItemKind :: Trait ( ..) |
130
147
ItemKind :: ExternCrate ( ..) | ItemKind :: ForeignMod ( ..) | ItemKind :: Ty ( ..) =>
131
148
DefPathData :: TypeNs ( i. ident . name . as_str ( ) ) ,
149
+ ItemKind :: Mod ( ..) if i. ident == keywords:: Invalid . ident ( ) => {
150
+ return visit:: walk_item ( self , i) ;
151
+ }
132
152
ItemKind :: Mod ( ..) => DefPathData :: Module ( i. ident . name . as_str ( ) ) ,
133
153
ItemKind :: Static ( ..) | ItemKind :: Const ( ..) | ItemKind :: Fn ( ..) =>
134
154
DefPathData :: ValueNs ( i. ident . name . as_str ( ) ) ,
135
- ItemKind :: Mac ( ..) => DefPathData :: MacroDef ( i. ident . name . as_str ( ) ) ,
155
+ ItemKind :: Mac ( ..) if i. id == DUMMY_NODE_ID => return , // Scope placeholder
156
+ ItemKind :: Mac ( ..) => return self . visit_macro_invoc ( i. id , false ) ,
136
157
ItemKind :: Use ( ..) => DefPathData :: Misc ,
137
158
} ;
138
159
let def = self . create_def ( i. id , def_data) ;
@@ -198,7 +219,7 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
198
219
TraitItemKind :: Method ( ..) | TraitItemKind :: Const ( ..) =>
199
220
DefPathData :: ValueNs ( ti. ident . name . as_str ( ) ) ,
200
221
TraitItemKind :: Type ( ..) => DefPathData :: TypeNs ( ti. ident . name . as_str ( ) ) ,
201
- TraitItemKind :: Macro ( ..) => DefPathData :: MacroDef ( ti. ident . name . as_str ( ) ) ,
222
+ TraitItemKind :: Macro ( ..) => return self . visit_macro_invoc ( ti. id , false ) ,
202
223
} ;
203
224
204
225
let def = self . create_def ( ti. id , def_data) ;
@@ -216,7 +237,7 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
216
237
ImplItemKind :: Method ( ..) | ImplItemKind :: Const ( ..) =>
217
238
DefPathData :: ValueNs ( ii. ident . name . as_str ( ) ) ,
218
239
ImplItemKind :: Type ( ..) => DefPathData :: TypeNs ( ii. ident . name . as_str ( ) ) ,
219
- ImplItemKind :: Macro ( ..) => DefPathData :: MacroDef ( ii. ident . name . as_str ( ) ) ,
240
+ ImplItemKind :: Macro ( ..) => return self . visit_macro_invoc ( ii. id , false ) ,
220
241
} ;
221
242
222
243
let def = self . create_def ( ii. id , def_data) ;
@@ -232,9 +253,13 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
232
253
fn visit_pat ( & mut self , pat : & Pat ) {
233
254
let parent_def = self . parent_def ;
234
255
235
- if let PatKind :: Ident ( _, id, _) = pat. node {
236
- let def = self . create_def ( pat. id , DefPathData :: Binding ( id. node . name . as_str ( ) ) ) ;
237
- self . parent_def = Some ( def) ;
256
+ match pat. node {
257
+ PatKind :: Mac ( ..) => return self . visit_macro_invoc ( pat. id , false ) ,
258
+ PatKind :: Ident ( _, id, _) => {
259
+ let def = self . create_def ( pat. id , DefPathData :: Binding ( id. node . name . as_str ( ) ) ) ;
260
+ self . parent_def = Some ( def) ;
261
+ }
262
+ _ => { }
238
263
}
239
264
240
265
visit:: walk_pat ( self , pat) ;
@@ -244,25 +269,28 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
244
269
fn visit_expr ( & mut self , expr : & Expr ) {
245
270
let parent_def = self . parent_def ;
246
271
247
- if let ExprKind :: Repeat ( _, ref count) = expr. node {
248
- self . visit_ast_const_integer ( count) ;
249
- }
250
-
251
- if let ExprKind :: Closure ( ..) = expr. node {
252
- let def = self . create_def ( expr. id , DefPathData :: ClosureExpr ) ;
253
- self . parent_def = Some ( def) ;
272
+ match expr. node {
273
+ ExprKind :: Mac ( ..) => return self . visit_macro_invoc ( expr. id , false ) ,
274
+ ExprKind :: Repeat ( _, ref count) => self . visit_ast_const_integer ( count) ,
275
+ ExprKind :: Closure ( ..) => {
276
+ let def = self . create_def ( expr. id , DefPathData :: ClosureExpr ) ;
277
+ self . parent_def = Some ( def) ;
278
+ }
279
+ _ => { }
254
280
}
255
281
256
282
visit:: walk_expr ( self , expr) ;
257
283
self . parent_def = parent_def;
258
284
}
259
285
260
286
fn visit_ty ( & mut self , ty : & Ty ) {
261
- if let TyKind :: FixedLengthVec ( _, ref length) = ty. node {
262
- self . visit_ast_const_integer ( length) ;
263
- }
264
- if let TyKind :: ImplTrait ( ..) = ty. node {
265
- self . create_def ( ty. id , DefPathData :: ImplTrait ) ;
287
+ match ty. node {
288
+ TyKind :: Mac ( ..) => return self . visit_macro_invoc ( ty. id , false ) ,
289
+ TyKind :: FixedLengthVec ( _, ref length) => self . visit_ast_const_integer ( length) ,
290
+ TyKind :: ImplTrait ( ..) => {
291
+ self . create_def ( ty. id , DefPathData :: ImplTrait ) ;
292
+ }
293
+ _ => { }
266
294
}
267
295
visit:: walk_ty ( self , ty) ;
268
296
}
@@ -274,6 +302,13 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
274
302
fn visit_macro_def ( & mut self , macro_def : & MacroDef ) {
275
303
self . create_def ( macro_def. id , DefPathData :: MacroDef ( macro_def. ident . name . as_str ( ) ) ) ;
276
304
}
305
+
306
+ fn visit_stmt ( & mut self , stmt : & Stmt ) {
307
+ match stmt. node {
308
+ StmtKind :: Mac ( ..) => self . visit_macro_invoc ( stmt. id , false ) ,
309
+ _ => visit:: walk_stmt ( self , stmt) ,
310
+ }
311
+ }
277
312
}
278
313
279
314
// We walk the HIR rather than the AST when reading items from metadata.
0 commit comments