@@ -12,16 +12,18 @@ use quote::quote;
12
12
13
13
use crate :: util:: { ident, KvParser , ListParser } ;
14
14
use crate :: ParseResult ;
15
-
16
15
pub struct FieldExport {
17
16
pub export_type : ExportType ,
18
17
pub span : Span ,
19
18
}
20
19
21
20
impl FieldExport {
22
- pub ( crate ) fn new_from_kv ( parser : & mut KvParser ) -> ParseResult < Self > {
21
+ pub ( crate ) fn new_from_kv (
22
+ parser : & mut KvParser ,
23
+ field_ty : venial:: TypeExpr ,
24
+ ) -> ParseResult < Self > {
23
25
let span = parser. span ( ) ;
24
- let export_type = ExportType :: new_from_kv ( parser) ?;
26
+ let export_type = ExportType :: new_from_kv ( parser, field_ty ) ?;
25
27
Ok ( Self { export_type, span } )
26
28
}
27
29
@@ -65,6 +67,7 @@ pub enum ExportType {
65
67
/// ### Property hints
66
68
/// - `RANGE`
67
69
Range {
70
+ field_ty : venial:: TypeExpr ,
68
71
min : TokenStream ,
69
72
max : TokenStream ,
70
73
step : TokenStream ,
@@ -168,13 +171,15 @@ impl ExportType {
168
171
/// - `@export_{flags/enum}("elem1", "elem2:key2", ...)`
169
172
/// becomes
170
173
/// `#[export(flags/enum = (elem1, elem2 = key2, ...))]`
171
- pub ( crate ) fn new_from_kv ( parser : & mut KvParser ) -> ParseResult < Self > {
174
+ pub ( crate ) fn new_from_kv (
175
+ parser : & mut KvParser ,
176
+ field_ty : venial:: TypeExpr ,
177
+ ) -> ParseResult < Self > {
172
178
if parser. handle_alone ( "storage" ) ? {
173
179
return Self :: new_storage ( ) ;
174
180
}
175
-
176
181
if let Some ( list_parser) = parser. handle_list ( "range" ) ? {
177
- return Self :: new_range_list ( list_parser) ;
182
+ return Self :: new_range_list ( list_parser, field_ty ) ;
178
183
}
179
184
180
185
if let Some ( list_parser) = parser. handle_list ( "enum" ) ? {
@@ -300,7 +305,7 @@ impl ExportType {
300
305
Ok ( Self :: Storage )
301
306
}
302
307
303
- fn new_range_list ( mut parser : ListParser ) -> ParseResult < Self > {
308
+ fn new_range_list ( mut parser : ListParser , field_ty : venial :: TypeExpr ) -> ParseResult < Self > {
304
309
const FLAG_OPTIONS : [ & str ; 7 ] = [
305
310
"or_greater" ,
306
311
"or_less" ,
@@ -314,6 +319,7 @@ impl ExportType {
314
319
315
320
let min = parser. next_expr ( ) ?;
316
321
let max = parser. next_expr ( ) ?;
322
+
317
323
// If there is a next element, and it is a literal, we take its tokens directly.
318
324
let step = if parser. peek ( ) . is_some_and ( |kv| kv. as_literal ( ) . is_ok ( ) ) {
319
325
let value = parser
@@ -330,6 +336,7 @@ impl ExportType {
330
336
loop {
331
337
let key_maybe_value =
332
338
parser. next_allowed_key_optional_value ( & FLAG_OPTIONS , & KV_OPTIONS ) ?;
339
+
333
340
match key_maybe_value {
334
341
Some ( ( option, None ) ) => {
335
342
flags. insert ( option. to_string ( ) ) ;
@@ -344,6 +351,7 @@ impl ExportType {
344
351
parser. finish ( ) ?;
345
352
346
353
Ok ( Self :: Range {
354
+ field_ty,
347
355
min,
348
356
max,
349
357
step,
@@ -411,12 +419,19 @@ impl ExportType {
411
419
}
412
420
413
421
macro_rules! quote_export_func {
414
- ( $function_name: ident( $( $tt: tt) * ) ) => {
422
+ ( $function_name: ident ( $( $tt: tt) * ) ) => {
415
423
Some ( quote! {
416
424
:: godot:: register:: property:: export_info_functions:: $function_name( $( $tt) * )
417
425
} )
418
426
} ;
419
427
428
+ // Use [ ] for generic args due to parsing ambiguity with ::< > turbofish.
429
+ ( $function_name: ident [ $( $generic_args: tt) * ] ( $( $tt: tt) * ) ) => {
430
+ Some ( quote! {
431
+ :: godot:: register:: property:: export_info_functions:: $function_name:: < $( $generic_args) * >( $( $tt) * )
432
+ } )
433
+ } ;
434
+
420
435
// Passes in a previously declared local `type FieldType = ...` as first generic argument.
421
436
// Doesn't work if function takes other generic arguments -- in that case it could be converted to a Type<...> parameter.
422
437
( $function_name: ident < T > ( $( $tt: tt) * ) ) => {
@@ -434,6 +449,7 @@ impl ExportType {
434
449
Self :: Storage => quote_export_func ! { export_storage( ) } ,
435
450
436
451
Self :: Range {
452
+ field_ty,
437
453
min,
438
454
max,
439
455
step,
@@ -451,9 +467,11 @@ impl ExportType {
451
467
} else {
452
468
quote ! { None }
453
469
} ;
470
+
454
471
let export_func = quote_export_func ! {
455
- export_range( #min, #max, #step, #or_greater, #or_less, #exp, #radians_as_degrees || #radians, #degrees, #hide_slider, #suffix)
472
+ export_range [ #field_ty ] ( #min, #max, #step, #or_greater, #or_less, #exp, #radians_as_degrees || #radians, #degrees, #hide_slider, #suffix)
456
473
} ?;
474
+
457
475
let deprecation_warning = if * radians {
458
476
// For some reason, rustfmt formatting like this. Probably a bug.
459
477
// See https://github.com/godot-rust/gdext/pull/783#discussion_r1669105958 and
@@ -465,6 +483,7 @@ impl ExportType {
465
483
} else {
466
484
quote ! { #export_func }
467
485
} ;
486
+
468
487
Some ( quote ! {
469
488
#deprecation_warning
470
489
} )
0 commit comments