@@ -398,6 +398,7 @@ fn transform_trait_impl(original_impl: Impl) -> Result<TokenStream, Error> {
398
398
let mut on_notification_fn = quote ! { None } ;
399
399
400
400
let mut virtual_methods = vec ! [ ] ;
401
+ let mut virtual_method_cfg_attrs = vec ! [ ] ;
401
402
let mut virtual_method_names = vec ! [ ] ;
402
403
403
404
let prv = quote ! { :: godot:: private } ;
@@ -409,52 +410,85 @@ fn transform_trait_impl(original_impl: Impl) -> Result<TokenStream, Error> {
409
410
continue ;
410
411
} ;
411
412
413
+ // Transport #[cfg] attributes to the virtual method's FFI glue, to ensure it won't be
414
+ // registered in Godot if conditionally removed from compilation.
415
+ let cfg_attrs = util:: extract_cfg_attrs ( & method. attributes )
416
+ . into_iter ( )
417
+ . collect :: < Vec < _ > > ( ) ;
412
418
let method_name = method. name . to_string ( ) ;
413
419
match method_name. as_str ( ) {
414
420
"register_class" => {
415
421
register_class_impl = quote ! {
422
+ #( #cfg_attrs) *
416
423
impl :: godot:: obj:: cap:: GodotRegisterClass for #class_name {
417
424
fn __godot_register_class( builder: & mut :: godot:: builder:: GodotBuilder <Self >) {
418
425
<Self as #trait_name>:: register_class( builder)
419
426
}
420
427
}
421
428
} ;
422
429
430
+ // Use 'match' as a way to only return 'Some(...)' if the given cfg attrs allow.
431
+ // Needs '#[allow(unreachable_patterns)]' to avoid warnings about the last arm.
423
432
register_fn = quote ! {
424
- Some ( #prv:: ErasedRegisterFn {
425
- raw: #prv:: callbacks:: register_class_by_builder:: <#class_name>
426
- } )
433
+ match ( ) {
434
+ #( #cfg_attrs) *
435
+ ( ) => Some ( #prv:: ErasedRegisterFn {
436
+ raw: #prv:: callbacks:: register_class_by_builder:: <#class_name>
437
+ } ) ,
438
+ _ => None ,
439
+ }
427
440
} ;
428
441
}
429
442
430
443
"init" => {
431
444
godot_init_impl = quote ! {
445
+ #( #cfg_attrs) *
432
446
impl :: godot:: obj:: cap:: GodotInit for #class_name {
433
447
fn __godot_init( base: :: godot:: obj:: Base <Self :: Base >) -> Self {
434
448
<Self as #trait_name>:: init( base)
435
449
}
436
450
}
437
451
} ;
438
- create_fn = quote ! { Some ( #prv:: callbacks:: create:: <#class_name>) } ;
452
+ create_fn = quote ! {
453
+ match ( ) {
454
+ #( #cfg_attrs) *
455
+ ( ) => Some ( #prv:: callbacks:: create:: <#class_name>) ,
456
+ _ => None ,
457
+ }
458
+ } ;
439
459
if cfg ! ( since_api = "4.2" ) {
440
- recreate_fn = quote ! { Some ( #prv:: callbacks:: recreate:: <#class_name>) } ;
460
+ recreate_fn = quote ! {
461
+ match ( ) {
462
+ #( #cfg_attrs) *
463
+ ( ) => Some ( #prv:: callbacks:: recreate:: <#class_name>) ,
464
+ _ => None ,
465
+ }
466
+ } ;
441
467
}
442
468
}
443
469
444
470
"to_string" => {
445
471
to_string_impl = quote ! {
472
+ #( #cfg_attrs) *
446
473
impl :: godot:: obj:: cap:: GodotToString for #class_name {
447
474
fn __godot_to_string( & self ) -> :: godot:: builtin:: GodotString {
448
475
<Self as #trait_name>:: to_string( self )
449
476
}
450
477
}
451
478
} ;
452
479
453
- to_string_fn = quote ! { Some ( #prv:: callbacks:: to_string:: <#class_name>) } ;
480
+ to_string_fn = quote ! {
481
+ match ( ) {
482
+ #( #cfg_attrs) *
483
+ ( ) => Some ( #prv:: callbacks:: to_string:: <#class_name>) ,
484
+ _ => None ,
485
+ }
486
+ } ;
454
487
}
455
488
456
489
"on_notification" => {
457
490
on_notification_impl = quote ! {
491
+ #( #cfg_attrs) *
458
492
impl :: godot:: obj:: cap:: GodotNotification for #class_name {
459
493
fn __godot_notification( & mut self , what: i32 ) {
460
494
if :: godot:: private:: is_class_inactive( Self :: __config( ) . is_tool) {
@@ -467,7 +501,11 @@ fn transform_trait_impl(original_impl: Impl) -> Result<TokenStream, Error> {
467
501
} ;
468
502
469
503
on_notification_fn = quote ! {
470
- Some ( #prv:: callbacks:: on_notification:: <#class_name>)
504
+ match ( ) {
505
+ #( #cfg_attrs) *
506
+ ( ) => Some ( #prv:: callbacks:: on_notification:: <#class_name>) ,
507
+ _ => None ,
508
+ }
471
509
} ;
472
510
}
473
511
@@ -487,6 +525,7 @@ fn transform_trait_impl(original_impl: Impl) -> Result<TokenStream, Error> {
487
525
} else {
488
526
format ! ( "_{method_name}" )
489
527
} ;
528
+ virtual_method_cfg_attrs. push ( cfg_attrs) ;
490
529
virtual_method_names. push ( virtual_method_name) ;
491
530
virtual_methods. push ( method) ;
492
531
}
@@ -517,6 +556,7 @@ fn transform_trait_impl(original_impl: Impl) -> Result<TokenStream, Error> {
517
556
518
557
match name {
519
558
#(
559
+ #( #virtual_method_cfg_attrs) *
520
560
#virtual_method_names => #virtual_method_callbacks,
521
561
) *
522
562
_ => None ,
@@ -526,6 +566,8 @@ fn transform_trait_impl(original_impl: Impl) -> Result<TokenStream, Error> {
526
566
527
567
:: godot:: sys:: plugin_add!( __GODOT_PLUGIN_REGISTRY in #prv; #prv:: ClassPlugin {
528
568
class_name: #class_name_obj,
569
+ #[ allow( unreachable_patterns) ] // due to the cfg-based match statements
570
+ #[ allow( clippy:: match_single_binding) ] // avoid warning on single-arm matches
529
571
component: #prv:: PluginComponent :: UserVirtuals {
530
572
user_register_fn: #register_fn,
531
573
user_create_fn: #create_fn,
0 commit comments