@@ -85,6 +85,10 @@ enum PropAttr {
85
85
Get ( Option < syn:: Expr > ) ,
86
86
Set ( Option < syn:: Expr > ) ,
87
87
88
+ // ident [= expr]
89
+ OverrideClass ( syn:: Type ) ,
90
+ OverrideInterface ( syn:: Type ) ,
91
+
88
92
// ident = expr
89
93
Type ( syn:: Type ) ,
90
94
@@ -112,6 +116,8 @@ impl Parse for PropAttr {
112
116
"name" => PropAttr :: Name ( input. parse ( ) ?) ,
113
117
"get" => PropAttr :: Get ( Some ( input. parse ( ) ?) ) ,
114
118
"set" => PropAttr :: Set ( Some ( input. parse ( ) ?) ) ,
119
+ "override_class" => PropAttr :: OverrideClass ( input. parse ( ) ?) ,
120
+ "override_interface" => PropAttr :: OverrideInterface ( input. parse ( ) ?) ,
115
121
"type" => PropAttr :: Type ( input. parse ( ) ?) ,
116
122
"member" => PropAttr :: Member ( input. parse ( ) ?) ,
117
123
// Special case "default = ..." and map it to .default_value(...)
@@ -138,8 +144,7 @@ impl Parse for PropAttr {
138
144
}
139
145
}
140
146
} else {
141
- // attributes with only the identifier
142
- // name
147
+ // attributes with only the identifier name
143
148
match & * name_str {
144
149
"get" => PropAttr :: Get ( None ) ,
145
150
"set" => PropAttr :: Set ( None ) ,
@@ -163,12 +168,15 @@ impl Parse for PropAttr {
163
168
struct ReceivedAttrs {
164
169
get : Option < MaybeCustomFn > ,
165
170
set : Option < MaybeCustomFn > ,
171
+ override_class : Option < syn:: Type > ,
172
+ override_interface : Option < syn:: Type > ,
166
173
ty : Option < syn:: Type > ,
167
174
member : Option < syn:: Ident > ,
168
175
name : Option < syn:: LitStr > ,
169
176
builder : Option < ( Punctuated < syn:: Expr , Token ! [ , ] > , TokenStream2 ) > ,
170
177
builder_fields : HashMap < syn:: Ident , Option < syn:: Expr > > ,
171
178
}
179
+
172
180
impl ReceivedAttrs {
173
181
fn new (
174
182
attrs_span : & proc_macro2:: Span ,
@@ -185,13 +193,24 @@ impl ReceivedAttrs {
185
193
"No `get` or `set` specified: at least one is required." . to_string ( ) ,
186
194
) ) ;
187
195
}
196
+
197
+ if this. override_class . is_some ( ) && this. override_interface . is_some ( ) {
198
+ return Err ( syn:: Error :: new (
199
+ * attrs_span,
200
+ "Both `override_class` and `override_interface` specified." . to_string ( ) ,
201
+ ) ) ;
202
+ }
203
+
188
204
Ok ( this)
189
205
}
206
+
190
207
fn set_from_attr ( & mut self , attr : PropAttr ) {
191
208
match attr {
192
209
PropAttr :: Get ( some_fn) => self . get = Some ( some_fn. into ( ) ) ,
193
210
PropAttr :: Set ( some_fn) => self . set = Some ( some_fn. into ( ) ) ,
194
211
PropAttr :: Name ( lit) => self . name = Some ( lit) ,
212
+ PropAttr :: OverrideClass ( ty) => self . override_class = Some ( ty) ,
213
+ PropAttr :: OverrideInterface ( ty) => self . override_interface = Some ( ty) ,
195
214
PropAttr :: Type ( ty) => self . ty = Some ( ty) ,
196
215
PropAttr :: Member ( member) => self . member = Some ( member) ,
197
216
PropAttr :: Builder ( required_params, optionals) => {
@@ -211,12 +230,15 @@ struct PropDesc {
211
230
field_ident : syn:: Ident ,
212
231
ty : syn:: Type ,
213
232
name : syn:: LitStr ,
233
+ override_class : Option < syn:: Type > ,
234
+ override_interface : Option < syn:: Type > ,
214
235
get : Option < MaybeCustomFn > ,
215
236
set : Option < MaybeCustomFn > ,
216
237
member : Option < syn:: Ident > ,
217
238
builder : Option < ( Punctuated < syn:: Expr , Token ! [ , ] > , TokenStream2 ) > ,
218
239
builder_fields : HashMap < syn:: Ident , Option < syn:: Expr > > ,
219
240
}
241
+
220
242
impl PropDesc {
221
243
fn new (
222
244
attrs_span : proc_macro2:: Span ,
@@ -227,6 +249,8 @@ impl PropDesc {
227
249
let ReceivedAttrs {
228
250
get,
229
251
set,
252
+ override_class,
253
+ override_interface,
230
254
ty,
231
255
member,
232
256
name,
@@ -247,11 +271,13 @@ impl PropDesc {
247
271
Ok ( Self {
248
272
attrs_span,
249
273
field_ident,
274
+ ty,
275
+ name,
276
+ override_class,
277
+ override_interface,
250
278
get,
251
279
set,
252
- ty,
253
280
member,
254
- name,
255
281
builder,
256
282
builder_fields,
257
283
} )
@@ -273,6 +299,19 @@ fn expand_properties_fn(props: &[PropDesc]) -> TokenStream2 {
273
299
( None , None ) => unreachable ! ( "No `get` or `set` specified" ) ,
274
300
} ;
275
301
302
+ match ( & prop. override_class , & prop. override_interface ) {
303
+ ( Some ( c) , None ) => {
304
+ return quote ! ( #crate_ident:: ParamSpecOverride :: for_class:: <#c>( #name) )
305
+ }
306
+ ( None , Some ( i) ) => {
307
+ return quote ! ( #crate_ident:: ParamSpecOverride :: for_interface:: <#i>( #name) )
308
+ }
309
+ ( Some ( _) , Some ( _) ) => {
310
+ unreachable ! ( "Both `override_class` and `override_interface` specified" )
311
+ }
312
+ ( None , None ) => ( ) ,
313
+ } ;
314
+
276
315
let builder_call = builder
277
316
. as_ref ( )
278
317
. cloned ( )
@@ -309,6 +348,7 @@ fn expand_properties_fn(props: &[PropDesc]) -> TokenStream2 {
309
348
}
310
349
)
311
350
}
351
+
312
352
fn expand_property_fn ( props : & [ PropDesc ] ) -> TokenStream2 {
313
353
let crate_ident = crate_ident_new ( ) ;
314
354
let match_branch_get = props. iter ( ) . flat_map ( |p| {
@@ -360,6 +400,7 @@ fn expand_property_fn(props: &[PropDesc]) -> TokenStream2 {
360
400
}
361
401
)
362
402
}
403
+
363
404
fn expand_set_property_fn ( props : & [ PropDesc ] ) -> TokenStream2 {
364
405
let crate_ident = crate_ident_new ( ) ;
365
406
let match_branch_set = props. iter ( ) . flat_map ( |p| {
0 commit comments