7
7
8
8
use crate :: class:: RpcAttr ;
9
9
use crate :: util:: { bail_fn, ident, safe_ident} ;
10
- use crate :: { util, ParseResult } ;
10
+ use crate :: { bail , util, KvParser , ParseResult } ;
11
11
use proc_macro2:: { Group , Ident , TokenStream , TokenTree } ;
12
12
use quote:: { format_ident, quote} ;
13
13
@@ -126,6 +126,7 @@ pub fn make_method_registration(
126
126
. iter ( )
127
127
. map ( |ident| ident. to_string ( ) ) ;
128
128
129
+ let default_parameters = extract_default_parameters ( & func_definition. signature_info ) ?;
129
130
// Transport #[cfg] attrs to the FFI glue to ensure functions which were conditionally
130
131
// removed from compilation don't cause errors.
131
132
let cfg_attrs = util:: extract_cfg_attrs ( & func_definition. external_attributes )
@@ -158,6 +159,9 @@ pub fn make_method_registration(
158
159
& [
159
160
#( #param_ident_strs ) , *
160
161
] ,
162
+ vec![
163
+ #( <#default_parameters as :: godot:: meta:: AsArg >. to_variant( ) ) , *
164
+ ]
161
165
)
162
166
} ;
163
167
@@ -175,6 +179,30 @@ pub fn make_method_registration(
175
179
Ok ( registration)
176
180
}
177
181
182
+ fn extract_default_parameters ( sig_info : & SignatureInfo ) -> ParseResult < Vec < TokenStream > > {
183
+ let mut res = vec ! [ ] ;
184
+ let mut allowed = true ;
185
+ for pd in sig_info. param_defaults . iter ( ) . rev ( ) {
186
+ match pd {
187
+ Some ( tk) if allowed => {
188
+ res. push ( tk. clone ( ) ) ; // toreview: if we really care about it, we can use &mut sig_info and mem::take() as we don't use this later
189
+ }
190
+ None if allowed => {
191
+ allowed = false ;
192
+ }
193
+ Some ( tk) if !allowed => {
194
+ return bail ! (
195
+ tk,
196
+ "opt arguments are only allowed at the end of the argument list."
197
+ ) ;
198
+ }
199
+ _ => ( ) ,
200
+ }
201
+ }
202
+ res. reverse ( ) ;
203
+ Ok ( res)
204
+ }
205
+
178
206
// ----------------------------------------------------------------------------------------------------------------------------------------------
179
207
// Implementation
180
208
@@ -199,6 +227,8 @@ pub struct SignatureInfo {
199
227
///
200
228
/// Index points into original venial tokens (i.e. takes into account potential receiver params).
201
229
pub modified_param_types : Vec < ( usize , venial:: TypeExpr ) > ,
230
+ /// Contains expressions of the default values of parameters.
231
+ pub param_defaults : Vec < Option < TokenStream > > ,
202
232
}
203
233
204
234
impl SignatureInfo {
@@ -210,6 +240,7 @@ impl SignatureInfo {
210
240
param_types : vec ! [ ] ,
211
241
return_type : quote ! { ( ) } ,
212
242
modified_param_types : vec ! [ ] ,
243
+ param_defaults : vec ! [ ] ,
213
244
}
214
245
}
215
246
@@ -350,7 +381,7 @@ pub(crate) fn into_signature_info(
350
381
signature : venial:: Function ,
351
382
class_name : & Ident ,
352
383
has_gd_self : bool ,
353
- ) -> SignatureInfo {
384
+ ) -> ParseResult < SignatureInfo > {
354
385
let method_name = signature. name . clone ( ) ;
355
386
let mut receiver_type = if has_gd_self {
356
387
ReceiverType :: GdSelf
@@ -361,6 +392,8 @@ pub(crate) fn into_signature_info(
361
392
let num_params = signature. params . inner . len ( ) ;
362
393
let mut param_idents = Vec :: with_capacity ( num_params) ;
363
394
let mut param_types = Vec :: with_capacity ( num_params) ;
395
+ let mut param_defaults = Vec :: with_capacity ( num_params) ;
396
+
364
397
let ret_type = match signature. return_ty {
365
398
None => quote ! { ( ) } ,
366
399
Some ( ty) => map_self_to_class_name ( ty. tokens , class_name) ,
@@ -398,21 +431,27 @@ pub(crate) fn into_signature_info(
398
431
tokens : map_self_to_class_name ( ty. tokens , class_name) ,
399
432
} ,
400
433
} ;
434
+ let default = match crate :: KvParser :: parse ( & arg. attributes , "opt" ) ? {
435
+ None => None ,
436
+ Some ( mut parser) => Some ( parser. handle_expr_required ( "default" ) ?) ,
437
+ } ;
401
438
402
439
param_types. push ( ty) ;
403
440
param_idents. push ( ident) ;
441
+ param_defaults. push ( default) ;
404
442
}
405
443
}
406
444
}
407
445
408
- SignatureInfo {
446
+ Ok ( SignatureInfo {
409
447
method_name,
410
448
receiver_type,
411
449
param_idents,
412
450
param_types,
413
451
return_type : ret_type,
414
452
modified_param_types,
415
- }
453
+ param_defaults,
454
+ } )
416
455
}
417
456
418
457
/// If `f32` is used for a delta parameter in a virtual process function, transparently use `f64` behind the scenes.
0 commit comments