1
1
// Decoding metadata from a single crate's metadata
2
2
3
- import core:: { vec, option, str} ;
4
3
import std:: { ebml, io} ;
5
4
import syntax:: { ast, ast_util} ;
6
5
import front:: attr;
7
6
import middle:: ty;
8
7
import common:: * ;
9
- import tydecode:: { parse_def_id, parse_ty_data } ;
8
+ import tydecode:: { parse_ty_data , parse_def_id, parse_bounds_data } ;
10
9
import syntax:: print:: pprust;
11
- import cstore;
10
+ import cmd= cstore:: crate_metadata ;
12
11
13
12
export get_symbol;
14
13
export get_tag_variants;
@@ -24,15 +23,13 @@ export list_crate_metadata;
24
23
export crate_dep;
25
24
export get_crate_deps;
26
25
export get_crate_hash;
27
- export external_resolver;
28
26
export get_impls_for_mod;
29
27
export get_iface_methods;
30
28
// A function that takes a def_id relative to the crate being searched and
31
29
// returns a def_id relative to the compilation environment, i.e. if we hit a
32
30
// def_id for an item defined in another crate, somebody needs to figure out
33
31
// what crate that's in and give us a def_id that makes sense for the current
34
32
// build.
35
- type external_resolver = fn @( ast:: def_id ) -> ast:: def_id ;
36
33
37
34
fn lookup_hash ( d : ebml:: doc , eq_fn : fn @( [ u8 ] ) -> bool , hash : uint ) ->
38
35
[ ebml:: doc ] {
@@ -91,66 +88,50 @@ fn variant_tag_id(d: ebml::doc) -> ast::def_id {
91
88
ret parse_def_id ( ebml:: doc_data ( tagdoc) ) ;
92
89
}
93
90
94
- fn parse_external_def_id ( this_cnum : ast:: crate_num ,
95
- extres : external_resolver , s : str ) ->
96
- ast:: def_id {
97
- let buf = str:: bytes ( s) ;
98
- let external_def_id = parse_def_id ( buf) ;
99
-
100
-
101
- // This item was defined in the crate we're searching if it's has the
102
- // local crate number, otherwise we need to search a different crate
103
- if external_def_id. crate == ast:: local_crate {
104
- ret { crate : this_cnum, node : external_def_id. node } ;
105
- } else { ret extres ( external_def_id) ; }
106
- }
107
-
108
- fn doc_type ( doc : ebml:: doc , this_cnum : ast:: crate_num , tcx : ty:: ctxt ,
109
- extres : external_resolver ) -> ty:: t {
91
+ fn doc_type ( doc : ebml:: doc , tcx : ty:: ctxt , cdata : cmd ) -> ty:: t {
110
92
let tp = ebml:: get_doc ( doc, tag_items_data_item_type) ;
111
- let def_parser = bind parse_external_def_id ( this_cnum, extres, _) ;
112
- parse_ty_data ( tp. data , this_cnum, tp. start , def_parser, tcx)
93
+ parse_ty_data ( tp. data , cdata. cnum , tp. start , tcx, { |did|
94
+ translate_def_id ( cdata, did)
95
+ } )
113
96
}
114
97
115
- fn item_type ( item : ebml:: doc , this_cnum : ast:: crate_num , tcx : ty:: ctxt ,
116
- extres : external_resolver ) -> ty:: t {
117
- let t = doc_type ( item, this_cnum, tcx, extres) ;
98
+ fn item_type ( item : ebml:: doc , tcx : ty:: ctxt , cdata : cmd ) -> ty:: t {
99
+ let t = doc_type ( item, tcx, cdata) ;
118
100
if family_names_type ( item_family ( item) ) {
119
101
ty:: mk_named ( tcx, t, @item_name ( item) )
120
102
} else { t }
121
103
}
122
104
123
- fn item_impl_iface ( item : ebml:: doc , this_cnum : ast :: crate_num , tcx : ty:: ctxt ,
124
- extres : external_resolver ) -> option:: t < ty:: t > {
105
+ fn item_impl_iface ( item : ebml:: doc , tcx : ty:: ctxt , cdata : cmd )
106
+ -> option:: t < ty:: t > {
125
107
let result = none;
126
108
ebml:: tagged_docs ( item, tag_impl_iface) { |ity|
127
- let def_parser = bind parse_external_def_id ( this_cnum , extres , _ ) ;
128
- let t = parse_ty_data ( ity . data , this_cnum , ity . start , def_parser ,
129
- tcx ) ;
109
+ let t = parse_ty_data ( ity . data , cdata . cnum , ity . start , tcx , { |did|
110
+ translate_def_id ( cdata , did )
111
+ } ) ;
130
112
result = some ( t) ;
131
113
}
132
114
result
133
115
}
134
116
135
- fn item_impl_iface_did ( item : ebml:: doc , this_cnum : ast:: crate_num ,
136
- extres : external_resolver )
117
+ fn item_impl_iface_did ( item : ebml:: doc , cdata : cmd )
137
118
-> option:: t < ast:: def_id > {
138
119
let result = none;
139
120
ebml:: tagged_docs ( item, tag_impl_iface_did) { |doc|
140
- let s = str :: unsafe_from_bytes ( ebml:: doc_data ( doc) ) ;
141
- result = some ( parse_external_def_id ( this_cnum , extres , s ) ) ;
121
+ let did = translate_def_id ( cdata , parse_def_id ( ebml:: doc_data ( doc) ) ) ;
122
+ result = some ( did ) ;
142
123
}
143
124
result
144
125
}
145
126
146
- fn item_ty_param_bounds ( item : ebml:: doc , this_cnum : ast:: crate_num ,
147
- tcx : ty:: ctxt , extres : external_resolver )
127
+ fn item_ty_param_bounds ( item : ebml:: doc , tcx : ty:: ctxt , cdata : cmd )
148
128
-> @[ ty:: param_bounds ] {
149
129
let bounds = [ ] ;
150
- let def_parser = bind parse_external_def_id ( this_cnum, extres, _) ;
151
130
ebml:: tagged_docs ( item, tag_items_data_item_ty_param_bounds) { |p|
152
- bounds += [ tydecode:: parse_bounds_data ( p. data , p. start ,
153
- this_cnum, def_parser, tcx) ] ;
131
+ let bd = parse_bounds_data ( p. data , p. start , cdata. cnum , tcx, { |did|
132
+ translate_def_id ( cdata, did)
133
+ } ) ;
134
+ bounds += [ bd] ;
154
135
}
155
136
@bounds
156
137
}
@@ -162,13 +143,12 @@ fn item_ty_param_count(item: ebml::doc) -> uint {
162
143
n
163
144
}
164
145
165
- fn tag_variant_ids ( item : ebml:: doc , this_cnum : ast:: crate_num ) ->
166
- [ ast:: def_id ] {
146
+ fn tag_variant_ids ( item : ebml:: doc , cdata : cmd ) -> [ ast:: def_id ] {
167
147
let ids: [ ast:: def_id ] = [ ] ;
168
148
let v = tag_items_data_item_variant;
169
149
ebml:: tagged_docs ( item, v) { |p|
170
150
let ext = parse_def_id ( ebml:: doc_data ( p) ) ;
171
- ids += [ { crate : this_cnum , node: ext. node } ] ;
151
+ ids += [ { crate : cdata . cnum , node: ext. node } ] ;
172
152
} ;
173
153
ret ids;
174
154
}
@@ -230,12 +210,12 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
230
210
ret def;
231
211
}
232
212
233
- fn get_type ( data : @ [ u8 ] , def : ast:: def_id , tcx : ty:: ctxt ,
234
- extres : external_resolver ) -> ty:: ty_param_bounds_and_ty {
235
- let item = lookup_item ( def . node , data) ;
236
- let t = item_type ( item, def . crate , tcx, extres ) ;
213
+ fn get_type ( cdata : cmd , id : ast:: node_id , tcx : ty:: ctxt )
214
+ -> ty:: ty_param_bounds_and_ty {
215
+ let item = lookup_item ( id , cdata . data ) ;
216
+ let t = item_type ( item, tcx, cdata ) ;
237
217
let tp_bounds = if family_has_type_params ( item_family ( item) ) {
238
- item_ty_param_bounds ( item, def . crate , tcx, extres )
218
+ item_ty_param_bounds ( item, tcx, cdata )
239
219
} else { @[ ] } ;
240
220
ret { bounds : tp_bounds, ty : t} ;
241
221
}
@@ -244,27 +224,25 @@ fn get_type_param_count(data: @[u8], id: ast::node_id) -> uint {
244
224
item_ty_param_count ( lookup_item ( id, data) )
245
225
}
246
226
247
- fn get_impl_iface ( data : @ [ u8 ] , def : ast:: def_id , tcx : ty:: ctxt ,
248
- extres : external_resolver ) -> option:: t < ty:: t > {
249
- item_impl_iface ( lookup_item ( def . node , data) , def . crate , tcx, extres )
227
+ fn get_impl_iface ( cdata : cmd , id : ast:: node_id , tcx : ty:: ctxt )
228
+ -> option:: t < ty:: t > {
229
+ item_impl_iface ( lookup_item ( id , cdata . data ) , tcx, cdata )
250
230
}
251
231
252
232
fn get_symbol ( data : @[ u8 ] , id : ast:: node_id ) -> str {
253
233
ret item_symbol ( lookup_item ( id, data) ) ;
254
234
}
255
235
256
- fn get_tag_variants ( _data : @[ u8 ] , def : ast:: def_id , tcx : ty:: ctxt ,
257
- extres : external_resolver ) -> [ ty:: variant_info ] {
258
- let external_crate_id = def. crate ;
259
- let data =
260
- cstore:: get_crate_data ( tcx. sess . get_cstore ( ) , external_crate_id) . data ;
236
+ fn get_tag_variants ( cdata : cmd , id : ast:: node_id , tcx : ty:: ctxt )
237
+ -> [ ty:: variant_info ] {
238
+ let data = cdata. data ;
261
239
let items = ebml:: get_doc ( ebml:: new_doc ( data) , tag_items) ;
262
- let item = find_item ( def . node , items) ;
240
+ let item = find_item ( id , items) ;
263
241
let infos: [ ty:: variant_info ] = [ ] ;
264
- let variant_ids = tag_variant_ids ( item, external_crate_id ) ;
242
+ let variant_ids = tag_variant_ids ( item, cdata ) ;
265
243
for did: ast:: def_id in variant_ids {
266
244
let item = find_item ( did. node , items) ;
267
- let ctor_ty = item_type ( item, external_crate_id , tcx, extres ) ;
245
+ let ctor_ty = item_type ( item, tcx, cdata ) ;
268
246
let arg_tys: [ ty:: t ] = [ ] ;
269
247
alt ty:: struct ( tcx, ctor_ty) {
270
248
ty:: ty_fn ( f) {
@@ -290,31 +268,32 @@ fn item_impl_methods(data: @[u8], item: ebml::doc, base_tps: uint)
290
268
rslt
291
269
}
292
270
293
- fn get_impls_for_mod ( data : @ [ u8 ] , m_def : ast:: def_id ,
294
- name : option:: t < ast:: ident > , extres : external_resolver )
271
+ fn get_impls_for_mod ( cdata : cmd , m_id : ast:: node_id ,
272
+ name : option:: t < ast:: ident > )
295
273
-> @[ @middle:: resolve:: _impl ] {
296
- let mod_item = lookup_item ( m_def. node , data) , result = [ ] ;
274
+ let data = cdata. data ;
275
+ let mod_item = lookup_item ( m_id, data) , result = [ ] ;
297
276
ebml:: tagged_docs ( mod_item, tag_mod_impl) { |doc|
298
- let did = parse_external_def_id (
299
- m_def. crate , extres, str:: unsafe_from_bytes ( ebml:: doc_data ( doc) ) ) ;
277
+ let did = translate_def_id ( cdata, parse_def_id ( ebml:: doc_data ( doc) ) ) ;
300
278
let item = lookup_item ( did. node , data) , nm = item_name ( item) ;
301
279
if alt name { some ( n) { n == nm } none. { true } } {
302
280
let base_tps = item_ty_param_count ( doc) ;
303
- let i_did = item_impl_iface_did ( item, m_def . crate , extres ) ;
281
+ let i_did = item_impl_iface_did ( item, cdata ) ;
304
282
result += [ @{ did: did, iface_did: i_did, ident: nm,
305
283
methods: item_impl_methods ( data, doc, base_tps) } ] ;
306
284
}
307
285
}
308
286
@result
309
287
}
310
288
311
- fn get_iface_methods ( data : @[ u8 ] , def : ast:: def_id , tcx : ty:: ctxt ,
312
- extres : external_resolver ) -> @[ ty:: method ] {
313
- let item = lookup_item ( def. node , data) , result = [ ] ;
289
+ fn get_iface_methods ( cdata : cmd , id : ast:: node_id , tcx : ty:: ctxt )
290
+ -> @[ ty:: method ] {
291
+ let data = cdata. data ;
292
+ let item = lookup_item ( id, data) , result = [ ] ;
314
293
ebml:: tagged_docs ( item, tag_item_method) { |mth|
315
- let bounds = item_ty_param_bounds ( mth, def . crate , tcx, extres ) ;
294
+ let bounds = item_ty_param_bounds ( mth, tcx, cdata ) ;
316
295
let name = item_name ( mth) ;
317
- let ty = doc_type ( mth, def . crate , tcx, extres ) ;
296
+ let ty = doc_type ( mth, tcx, cdata ) ;
318
297
let fty = alt ty:: struct ( tcx, ty) { ty:: ty_fn ( f) { f } } ;
319
298
result += [ { ident: name, tps: bounds, fty: fty} ] ;
320
299
}
@@ -489,6 +468,22 @@ fn list_crate_metadata(bytes: @[u8], out: io::writer) {
489
468
list_crate_items ( bytes, md, out) ;
490
469
}
491
470
471
+ // Translates a def_id from an external crate to a def_id for the current
472
+ // compilation environment. We use this when trying to load types from
473
+ // external crates - if those types further refer to types in other crates
474
+ // then we must translate the crate number from that encoded in the external
475
+ // crate to the correct local crate number.
476
+ fn translate_def_id ( cdata : cmd , did : ast:: def_id ) -> ast:: def_id {
477
+ if did. crate == ast:: local_crate {
478
+ ret { crate : cdata. cnum , node : did. node } ;
479
+ }
480
+
481
+ alt cdata. cnum_map . find ( did. crate ) {
482
+ option:: some ( n) { ret { crate : n, node : did. node } ; }
483
+ option:: none. { fail "didn't find a crate in the cnum_map" ; }
484
+ }
485
+ }
486
+
492
487
// Local Variables:
493
488
// mode: rust
494
489
// fill-column: 78;
0 commit comments