1
1
/*
2
2
3
- The compiler code necessary to implement the #[auto_serialize2]
4
- extension. The idea here is that type-defining items may be tagged
5
- with #[auto_serialize2], which will cause us to generate a little
6
- companion module with the same name as the item.
3
+ The compiler code necessary to implement the #[auto_serialize2] and
4
+ #[auto_deserialize2] extension. The idea here is that type-defining items may
5
+ be tagged with #[auto_serialize2] and #[auto_deserialize2] , which will cause
6
+ us to generate a little companion module with the same name as the item.
7
7
8
8
For example, a type like:
9
9
10
10
#[auto_serialize2]
11
+ #[auto_deserialize2]
11
12
struct Node {id: uint}
12
13
13
14
would generate two implementations like:
@@ -34,6 +35,7 @@ Other interesting scenarios are whe the item has type parameters or
34
35
references other non-built-in types. A type definition like:
35
36
36
37
#[auto_serialize2]
38
+ #[auto_deserialize2]
37
39
type spanned<T> = {node: T, span: span};
38
40
39
41
would yield functions like:
@@ -75,92 +77,139 @@ use codemap::span;
75
77
use std:: map;
76
78
use std:: map:: HashMap ;
77
79
78
- export expand;
80
+ export expand_auto_serialize;
81
+ export expand_auto_deserialize;
79
82
80
83
// Transitional reexports so qquote can find the paths it is looking for
81
84
mod syntax {
82
85
pub use ext;
83
86
pub use parse;
84
87
}
85
88
86
- fn expand ( cx : ext_ctxt ,
87
- span : span ,
88
- _mitem : ast:: meta_item ,
89
- in_items : ~[ @ast:: item ] ) -> ~[ @ast:: item ] {
90
- fn not_auto_serialize2 ( a : & ast:: attribute ) -> bool {
91
- attr:: get_attr_name ( * a) != ~"auto_serialize2"
89
+ fn expand_auto_serialize (
90
+ cx : ext_ctxt ,
91
+ span : span ,
92
+ _mitem : ast:: meta_item ,
93
+ in_items : ~[ @ast:: item ]
94
+ ) -> ~[ @ast:: item ] {
95
+ fn is_auto_serialize2 ( a : & ast:: attribute ) -> bool {
96
+ attr:: get_attr_name ( * a) == ~"auto_serialize2"
92
97
}
93
98
94
99
fn filter_attrs ( item : @ast:: item ) -> @ast:: item {
95
- @{ attrs: vec:: filter ( item. attrs , not_auto_serialize2 ) ,
100
+ @{ attrs: vec:: filter ( item. attrs , |a| ! is_auto_serialize2 ( a ) ) ,
96
101
.. * item}
97
102
}
98
103
99
104
do vec:: flat_map ( in_items) |item| {
100
- match item. node {
101
- ast:: item_ty( @{ node: ast:: ty_rec( fields) , _} , tps) => {
102
- let ser_impl = mk_rec_ser_impl (
103
- cx,
104
- item. span ,
105
- item. ident ,
106
- fields,
107
- tps
108
- ) ;
109
-
110
- let deser_impl = mk_rec_deser_impl (
111
- cx,
112
- item. span ,
113
- item. ident ,
114
- fields,
115
- tps
116
- ) ;
117
-
118
- ~[ filter_attrs ( * item) , ser_impl, deser_impl]
119
- } ,
120
- ast:: item_class( @{ fields, _} , tps) => {
121
- let ser_impl = mk_struct_ser_impl (
122
- cx,
123
- item. span ,
124
- item. ident ,
125
- fields,
126
- tps
127
- ) ;
128
-
129
- let deser_impl = mk_struct_deser_impl (
130
- cx,
131
- item. span ,
132
- item. ident ,
133
- fields,
134
- tps
135
- ) ;
136
-
137
- ~[ filter_attrs ( * item) , ser_impl, deser_impl]
138
- } ,
139
- ast:: item_enum( enum_def, tps) => {
140
- let ser_impl = mk_enum_ser_impl (
141
- cx,
142
- item. span ,
143
- item. ident ,
144
- enum_def,
145
- tps
146
- ) ;
147
-
148
- let deser_impl = mk_enum_deser_impl (
149
- cx,
150
- item. span ,
151
- item. ident ,
152
- enum_def,
153
- tps
154
- ) ;
155
-
156
- ~[ filter_attrs ( * item) , ser_impl, deser_impl]
157
- } ,
158
- _ => {
159
- cx. span_err ( span, ~"#[ auto_serialize2] can only be applied \
160
- to structs, record types, and enum \
161
- definitions") ;
162
- ~[ * item]
105
+ if item. attrs . any ( is_auto_serialize2) {
106
+ match item. node {
107
+ ast:: item_ty( @{ node: ast:: ty_rec( fields) , _} , tps) => {
108
+ let ser_impl = mk_rec_ser_impl (
109
+ cx,
110
+ item. span ,
111
+ item. ident ,
112
+ fields,
113
+ tps
114
+ ) ;
115
+
116
+ ~[ filter_attrs ( * item) , ser_impl]
117
+ } ,
118
+ ast:: item_class( @{ fields, _} , tps) => {
119
+ let ser_impl = mk_struct_ser_impl (
120
+ cx,
121
+ item. span ,
122
+ item. ident ,
123
+ fields,
124
+ tps
125
+ ) ;
126
+
127
+ ~[ filter_attrs ( * item) , ser_impl]
128
+ } ,
129
+ ast:: item_enum( enum_def, tps) => {
130
+ let ser_impl = mk_enum_ser_impl (
131
+ cx,
132
+ item. span ,
133
+ item. ident ,
134
+ enum_def,
135
+ tps
136
+ ) ;
137
+
138
+ ~[ filter_attrs ( * item) , ser_impl]
139
+ } ,
140
+ _ => {
141
+ cx. span_err ( span, ~"#[ auto_serialize2] can only be \
142
+ applied to structs, record types, \
143
+ and enum definitions") ;
144
+ ~[ * item]
145
+ }
146
+ }
147
+ } else {
148
+ ~[ * item]
149
+ }
150
+ }
151
+ }
152
+
153
+ fn expand_auto_deserialize (
154
+ cx : ext_ctxt ,
155
+ span : span ,
156
+ _mitem : ast:: meta_item ,
157
+ in_items : ~[ @ast:: item ]
158
+ ) -> ~[ @ast:: item ] {
159
+ fn is_auto_deserialize2 ( a : & ast:: attribute ) -> bool {
160
+ attr:: get_attr_name ( * a) == ~"auto_deserialize2"
161
+ }
162
+
163
+ fn filter_attrs ( item : @ast:: item ) -> @ast:: item {
164
+ @{ attrs: vec:: filter ( item. attrs , |a| !is_auto_deserialize2 ( a) ) ,
165
+ .. * item}
166
+ }
167
+
168
+ do vec:: flat_map ( in_items) |item| {
169
+ if item. attrs . any ( is_auto_deserialize2) {
170
+ match item. node {
171
+ ast:: item_ty( @{ node: ast:: ty_rec( fields) , _} , tps) => {
172
+ let deser_impl = mk_rec_deser_impl (
173
+ cx,
174
+ item. span ,
175
+ item. ident ,
176
+ fields,
177
+ tps
178
+ ) ;
179
+
180
+ ~[ filter_attrs ( * item) , deser_impl]
181
+ } ,
182
+ ast:: item_class( @{ fields, _} , tps) => {
183
+ let deser_impl = mk_struct_deser_impl (
184
+ cx,
185
+ item. span ,
186
+ item. ident ,
187
+ fields,
188
+ tps
189
+ ) ;
190
+
191
+ ~[ filter_attrs ( * item) , deser_impl]
192
+ } ,
193
+ ast:: item_enum( enum_def, tps) => {
194
+ let deser_impl = mk_enum_deser_impl (
195
+ cx,
196
+ item. span ,
197
+ item. ident ,
198
+ enum_def,
199
+ tps
200
+ ) ;
201
+
202
+ ~[ filter_attrs ( * item) , deser_impl]
203
+ } ,
204
+ _ => {
205
+ cx. span_err ( span, ~"#[ auto_deserialize2] can only be \
206
+ applied to structs, record types, \
207
+ and enum definitions") ;
208
+ ~[ * item]
209
+ }
163
210
}
211
+ } else {
212
+ ~[ * item]
164
213
}
165
214
}
166
215
}
0 commit comments