@@ -31,6 +31,8 @@ import syntax::print::pprust;
31
31
32
32
export encode_inlined_item;
33
33
export decode_inlined_item;
34
+ export encode_inlined_method;
35
+ export decode_inlined_method;
34
36
35
37
type decode_ctxt = @{
36
38
cdata : cstore:: crate_metadata ,
@@ -49,49 +51,125 @@ iface tr {
49
51
}
50
52
51
53
// ______________________________________________________________________
52
- // Enumerating the IDs which appear in an AST
54
+ // Top-level methods.
55
+
56
+ // The type inline_fn should be a type that can represent both methods
57
+ // and top-level items. As it happens, the type ast::method is perfect
58
+ // for this purpose, but I use this typedef just to keep clear when
59
+ // the thing may not, in fact, be an actual method in the AST but
60
+ // rather some sort of function.
61
+ enum inline_fn = @ast:: method;
53
62
54
63
fn encode_inlined_item ( ecx : @e:: encode_ctxt ,
55
64
ebml_w : ebml:: writer ,
56
65
path : ast_map:: path ,
57
66
item : @ast:: item ) {
67
+ let ifn = inline_fn ( alt item. node {
68
+ ast:: item_fn ( decl, tps, body) {
69
+ @{ ident: item. ident ,
70
+ attrs: item. attrs ,
71
+ tps: tps,
72
+ decl: decl,
73
+ body: body,
74
+ id: item. id ,
75
+ span: item. span }
76
+ }
77
+
78
+ _ {
79
+ ecx. ccx . sess . span_bug ( item. span , "Cannot inline non-function" )
80
+ }
81
+ } ) ;
82
+
83
+ encode_inlined_fn ( ecx, ebml_w, path, ifn) ;
84
+ }
85
+
86
+ fn decode_inlined_item ( cdata : cstore:: crate_metadata ,
87
+ tcx : ty:: ctxt ,
88
+ maps : maps ,
89
+ path : ast_map:: path ,
90
+ par_doc : ebml:: doc ) -> option < @ast:: item > {
91
+ let oifn = decode_inlined_fn ( cdata, tcx, maps, path, par_doc) ;
92
+ option:: map ( oifn) { |ifn|
93
+ let item = @{ ident: ifn. ident ,
94
+ attrs: ifn. attrs ,
95
+ id: ifn. id ,
96
+ node: ast:: item_fn ( ifn. decl , ifn. tps , ifn. body ) ,
97
+ span: ifn. span } ;
98
+ ast_map:: map_decoded_item ( tcx. items , path, item) ;
99
+ item
100
+ }
101
+ }
102
+
103
+ fn encode_inlined_method ( ecx : @e:: encode_ctxt ,
104
+ ebml_w : ebml:: writer ,
105
+ path : ast_map:: path ,
106
+ mthd : @ast:: method ) {
107
+ encode_inlined_fn ( ecx, ebml_w, path, inline_fn ( mthd) )
108
+ }
109
+
110
+ fn decode_inlined_method ( cdata : cstore:: crate_metadata ,
111
+ tcx : ty:: ctxt ,
112
+ maps : maps ,
113
+ path : ast_map:: path ,
114
+ par_doc : ebml:: doc ) -> option < @ast:: method > {
115
+ let oifn = decode_inlined_fn ( cdata, tcx, maps, path, par_doc) ;
116
+ option:: map ( oifn) { |ifn|
117
+ ast_map:: map_decoded_method ( tcx. items , path, * ifn) ;
118
+ * ifn
119
+ }
120
+ }
121
+
122
+ fn encode_inlined_fn ( ecx : @e:: encode_ctxt ,
123
+ ebml_w : ebml:: writer ,
124
+ path : ast_map:: path ,
125
+ ifn : inline_fn ) {
126
+
58
127
#debug[ "> Encoding inlined item: %s::%s (%u)" ,
59
128
ast_map:: path_to_str ( path) ,
60
- item . ident ,
129
+ ifn . ident ,
61
130
ebml_w. writer . tell ( ) ] ;
62
- let id_range = compute_id_range ( item) ;
131
+
132
+ let id_range = compute_id_range ( ifn) ;
63
133
ebml_w. wr_tag ( c:: tag_ast as uint ) { ||
64
134
encode_id_range ( ebml_w, id_range) ;
65
- encode_ast ( ebml_w, item ) ;
66
- encode_side_tables_for_item ( ecx, ebml_w, item ) ;
135
+ encode_ast ( ebml_w, ifn ) ;
136
+ encode_side_tables_for_ifn ( ecx, ebml_w, ifn ) ;
67
137
}
68
- #debug[ "< Encoded inlined item: %s (%u)" ,
138
+
139
+ #debug[ "< Encoded inlined fn: %s::%s (%u)" ,
69
140
ast_map:: path_to_str ( path) ,
141
+ ifn. ident ,
70
142
ebml_w. writer . tell ( ) ] ;
71
143
}
72
144
73
- fn decode_inlined_item ( cdata : cstore:: crate_metadata ,
74
- tcx : ty:: ctxt ,
75
- maps : maps ,
76
- path : ast_map:: path ,
77
- par_doc : ebml:: doc ) -> option < @ast:: item > {
145
+ // Decodes the inlined function and associated side tables. Does
146
+ // *not* insert the function into the ast_map, since the correct way
147
+ // to do this depends on whether this is an inlined item or method;
148
+ // therefore, you ought to be invoking decode_inlined_item() or
149
+ // decode_inlined_method() and not this helper function.
150
+ fn decode_inlined_fn ( cdata : cstore:: crate_metadata ,
151
+ tcx : ty:: ctxt ,
152
+ maps : maps ,
153
+ path : ast_map:: path ,
154
+ par_doc : ebml:: doc ) -> option < inline_fn > {
78
155
let dcx = @{ cdata: cdata, tcx: tcx, maps: maps} ;
79
156
alt par_doc. opt_child ( c:: tag_ast) {
80
157
none { none }
81
158
some( ast_doc) {
82
- #debug[ "> Decoding inlined item : %s" , ast_map:: path_to_str ( path) ] ;
159
+ #debug[ "> Decoding inlined fn : %s" , ast_map:: path_to_str ( path) ] ;
83
160
let from_id_range = decode_id_range ( ast_doc) ;
84
161
let to_id_range = reserve_id_range ( dcx. tcx . sess , from_id_range) ;
85
162
let xcx = @{ dcx: dcx,
86
163
from_id_range: from_id_range,
87
164
to_id_range: to_id_range} ;
88
- let raw_item = decode_ast ( ast_doc) ;
89
- let item = renumber_ast ( xcx, raw_item) ;
90
- #debug[ ">> Item named: %s" , item. ident ] ;
91
- ast_map:: map_decoded_item ( dcx. tcx . items , path, item) ;
165
+ let raw_ifn = decode_ast ( ast_doc) ;
166
+ let ifn = renumber_ast ( xcx, raw_ifn) ;
167
+ #debug[ "Fn named: %s" , ifn. ident ] ;
92
168
decode_side_tables ( xcx, ast_doc) ;
93
- #debug[ "< Decoded inlined item: %s" , ast_map:: path_to_str ( path) ] ;
94
- some ( item)
169
+ #debug[ "< Decoded inlined fn: %s::%s" ,
170
+ ast_map:: path_to_str ( path) ,
171
+ ifn. ident ] ;
172
+ some ( ifn)
95
173
}
96
174
}
97
175
}
@@ -105,7 +183,7 @@ fn empty(range: id_range) -> bool {
105
183
range. min >= range. max
106
184
}
107
185
108
- fn visit_ids ( item : @ast :: item , vfn : fn @( ast:: node_id ) ) {
186
+ fn visit_ids ( ifn : inline_fn , vfn : fn @( ast:: node_id ) ) {
109
187
let visitor = visit:: mk_simple_visitor ( @{
110
188
visit_mod : fn @( _m: ast:: _mod, _sp: span, id: ast:: node_id) {
111
189
vfn ( id)
@@ -214,13 +292,13 @@ fn visit_ids(item: @ast::item, vfn: fn@(ast::node_id)) {
214
292
}
215
293
} ) ;
216
294
217
- visitor . visit_item ( item , ( ) , visitor) ;
295
+ visit :: visit_method_helper ( * ifn , ( ) , visitor) ;
218
296
}
219
297
220
- fn compute_id_range ( item : @ast :: item ) -> id_range {
298
+ fn compute_id_range ( ifn : inline_fn ) -> id_range {
221
299
let min = @mutable int:: max_value;
222
300
let max = @mutable int:: min_value;
223
- visit_ids ( item ) { |id|
301
+ visit_ids ( ifn ) { |id|
224
302
* min = int:: min ( * min, id) ;
225
303
* max = int:: max ( * max, id + 1 ) ;
226
304
}
@@ -317,25 +395,25 @@ impl deserializer_helpers<D: serialization::deserializer> for D {
317
395
// We also have to adjust the spans: for now we just insert a dummy span,
318
396
// but eventually we should add entries to the local codemap as required.
319
397
320
- fn encode_ast ( ebml_w : ebml:: writer , item : @ast :: item ) {
398
+ fn encode_ast ( ebml_w : ebml:: writer , ifn : inline_fn ) {
321
399
ebml_w. wr_tag ( c:: tag_tree as uint ) { ||
322
- astencode_gen:: serialize_syntax_ast_item ( ebml_w, * item ) ;
400
+ astencode_gen:: serialize_syntax_ast_method ( ebml_w, * * ifn )
323
401
}
324
402
}
325
403
326
- fn decode_ast ( par_doc : ebml:: doc ) -> @ast :: item {
404
+ fn decode_ast ( par_doc : ebml:: doc ) -> inline_fn {
327
405
let chi_doc = par_doc[ c:: tag_tree] ;
328
406
let d = serialization:: mk_ebml_deserializer ( chi_doc) ;
329
- @astencode_gen:: deserialize_syntax_ast_item ( d )
407
+ inline_fn ( @astencode_gen:: deserialize_syntax_ast_method ( d ) )
330
408
}
331
409
332
- fn renumber_ast ( xcx : extended_decode_ctxt , item : @ast :: item ) -> @ast :: item {
410
+ fn renumber_ast ( xcx : extended_decode_ctxt , ifn : inline_fn ) -> inline_fn {
333
411
let fld = fold:: make_fold ( {
334
412
new_id: xcx. tr_id ( _) ,
335
413
new_span: xcx. tr_span ( _)
336
414
with * fold:: default_ast_fold ( )
337
415
} ) ;
338
- fld. fold_item ( item )
416
+ inline_fn ( fld. fold_method ( * ifn ) )
339
417
}
340
418
341
419
// ______________________________________________________________________
@@ -586,11 +664,11 @@ impl writer for ebml::writer {
586
664
}
587
665
}
588
666
589
- fn encode_side_tables_for_item ( ecx : @e:: encode_ctxt ,
590
- ebml_w : ebml:: writer ,
591
- item : @ast :: item ) {
667
+ fn encode_side_tables_for_ifn ( ecx : @e:: encode_ctxt ,
668
+ ebml_w : ebml:: writer ,
669
+ ifn : inline_fn ) {
592
670
ebml_w. wr_tag ( c:: tag_table as uint ) { ||
593
- visit_ids ( item , fn @( id: ast:: node_id) {
671
+ visit_ids ( ifn , fn @( id: ast:: node_id) {
594
672
// Note: this will cause a copy of ebml_w, which is bad as
595
673
// it has mutable fields. But I believe it's harmless since
596
674
// we generate balanced EBML.
@@ -820,7 +898,21 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
820
898
}
821
899
822
900
// ______________________________________________________________________
823
- // Testing
901
+ // Testing of astencode_gen
902
+
903
+ #[ cfg( test) ]
904
+ fn encode_item_ast ( ebml_w : ebml:: writer , item : @ast:: item ) {
905
+ ebml_w. wr_tag ( c:: tag_tree as uint ) { ||
906
+ astencode_gen:: serialize_syntax_ast_item ( ebml_w, * item) ;
907
+ }
908
+ }
909
+
910
+ #[ cfg( test) ]
911
+ fn decode_item_ast ( par_doc : ebml:: doc ) -> @ast:: item {
912
+ let chi_doc = par_doc[ c:: tag_tree] ;
913
+ let d = serialization:: mk_ebml_deserializer ( chi_doc) ;
914
+ @astencode_gen:: deserialize_syntax_ast_item ( d)
915
+ }
824
916
825
917
#[ cfg( test) ]
826
918
fn new_parse_sess ( ) -> parser:: parse_sess {
@@ -864,9 +956,9 @@ fn roundtrip(in_item: @ast::item) {
864
956
#debug[ "in_item = %s" , pprust:: item_to_str ( in_item) ] ;
865
957
let mbuf = io:: mk_mem_buffer ( ) ;
866
958
let ebml_w = ebml:: mk_writer ( io:: mem_buffer_writer ( mbuf) ) ;
867
- encode_ast ( ebml_w, in_item) ;
959
+ encode_item_ast ( ebml_w, in_item) ;
868
960
let ebml_doc = ebml:: new_doc ( @io:: mem_buffer_buf ( mbuf) ) ;
869
- let out_item = decode_ast ( ebml_doc) ;
961
+ let out_item = decode_item_ast ( ebml_doc) ;
870
962
#debug[ "out_item = %s" , pprust:: item_to_str ( out_item) ] ;
871
963
assert in_item == out_item;
872
964
}
0 commit comments