@@ -9,7 +9,7 @@ use crate::class::{
9
9
make_signal_registrations, ConstDefinition , FuncDefinition , RpcAttr , RpcMode , SignalDefinition ,
10
10
SignatureInfo , TransferMode ,
11
11
} ;
12
- use crate :: util:: { bail, ident, require_api_version, KvParser } ;
12
+ use crate :: util:: { bail, c_str , ident, require_api_version, KvParser } ;
13
13
use crate :: { handle_mutually_exclusive_keys, util, ParseResult } ;
14
14
15
15
use proc_macro2:: { Delimiter , Group , Ident , TokenStream } ;
@@ -89,7 +89,7 @@ pub fn transform_inherent_impl(mut impl_block: venial::Impl) -> ParseResult<Toke
89
89
let method_registrations: Vec < TokenStream > = funcs
90
90
. into_iter ( )
91
91
. map ( |func_def| make_method_registration ( & class_name, func_def) )
92
- . collect :: < ParseResult < Vec < TokenStream > > > ( ) ?; // <- FIXME transpose this
92
+ . collect :: < ParseResult < Vec < TokenStream > > > ( ) ?;
93
93
94
94
let constant_registration = make_constant_registration ( consts, & class_name, & class_name_obj) ?;
95
95
@@ -196,21 +196,25 @@ fn process_godot_fns(
196
196
197
197
// For virtual methods, rename/mangle existing user method and create a new method with the original name,
198
198
// which performs a dynamic dispatch.
199
- if func. is_virtual {
200
- add_virtual_script_call (
199
+ let registered_name = if func. is_virtual {
200
+ let registered_name = add_virtual_script_call (
201
201
& mut virtual_functions,
202
202
function,
203
203
& signature_info,
204
204
class_name,
205
205
& func. rename ,
206
206
gd_self_parameter,
207
207
) ;
208
+
209
+ Some ( registered_name)
210
+ } else {
211
+ func. rename
208
212
} ;
209
213
210
214
func_definitions. push ( FuncDefinition {
211
215
signature_info,
212
216
external_attributes,
213
- rename : func . rename ,
217
+ registered_name ,
214
218
is_script_virtual : func. is_virtual ,
215
219
rpc_info,
216
220
} ) ;
@@ -295,7 +299,7 @@ fn add_virtual_script_call(
295
299
class_name : & Ident ,
296
300
rename : & Option < String > ,
297
301
gd_self_parameter : Option < Ident > ,
298
- ) {
302
+ ) -> String {
299
303
assert ! ( cfg!( since_api = "4.3" ) ) ;
300
304
301
305
// Update parameter names, so they can be forwarded (e.g. a "_" declared by the user cannot).
@@ -311,9 +315,12 @@ fn add_virtual_script_call(
311
315
312
316
let class_name_str = class_name. to_string ( ) ;
313
317
let early_bound_name = format_ident ! ( "__earlybound_{}" , & function. name) ;
314
- let method_name_str = rename
315
- . clone ( )
316
- . unwrap_or_else ( || format ! ( "_{}" , function. name) ) ;
318
+
319
+ let method_name_str = match rename {
320
+ Some ( rename) => rename. clone ( ) ,
321
+ None => format ! ( "_{}" , function. name) ,
322
+ } ;
323
+ let method_name_cstr = c_str ( & method_name_str) ;
317
324
318
325
let sig_tuple = signature_info. tuple_type ( ) ;
319
326
let arg_names = & signature_info. param_idents ;
@@ -329,7 +336,7 @@ fn add_virtual_script_call(
329
336
330
337
let code = quote ! {
331
338
let object_ptr = #object_ptr;
332
- let method_sname = :: godot:: builtin:: StringName :: from( #method_name_str ) ;
339
+ let method_sname = :: godot:: builtin:: StringName :: from( #method_name_cstr ) ;
333
340
let method_sname_ptr = method_sname. string_sys( ) ;
334
341
let has_virtual_override = unsafe { :: godot:: private:: has_virtual_script_method( object_ptr, method_sname_ptr) } ;
335
342
@@ -360,6 +367,8 @@ fn add_virtual_script_call(
360
367
361
368
std:: mem:: swap ( & mut function. body , & mut early_bound_function. body ) ;
362
369
virtual_functions. push ( early_bound_function) ;
370
+
371
+ method_name_str
363
372
}
364
373
365
374
fn extract_attributes < T > ( item : & mut T ) -> ParseResult < Option < ItemAttr > >
@@ -377,7 +386,7 @@ where
377
386
index += 1 ;
378
387
379
388
let Some ( attr_name) = attr. get_single_path_segment ( ) else {
380
- // Attribute of the form #[segmented::path] can't be what we are looking for
389
+ // Attribute of the form #[segmented::path] can't be what we are looking for.
381
390
continue ;
382
391
} ;
383
392
@@ -412,7 +421,7 @@ where
412
421
413
422
// #[rpc]
414
423
name if name == "rpc" => {
415
- // Safe unwrap since #[rpc] must be present if we got to this point
424
+ // Safe unwrap, since #[rpc] must be present if we got to this point.
416
425
let mut parser = KvParser :: parse ( attributes, "rpc" ) ?. unwrap ( ) ;
417
426
418
427
let rpc_mode = handle_mutually_exclusive_keys (
@@ -445,9 +454,14 @@ where
445
454
let rpc_attr = match ( config_expr, ( & rpc_mode, & transfer_mode, & call_local, & channel) ) {
446
455
// Ok: Only `config = [expr]` is present.
447
456
( Some ( expr) , ( None , None , None , None ) ) => RpcAttr :: Expression ( expr) ,
457
+
448
458
// Err: `config = [expr]` is present along other parameters, which is not allowed.
449
- ( Some ( _) , _) => return bail ! ( & * item, "`#[rpc(config = ...)]` is mutually exclusive with any other parameters(`any_peer`, `reliable`, `call_local`, `channel = 0`)" ) ,
450
- // Ok: `config` is not present, any combination of the other parameters is allowed..
459
+ ( Some ( _) , _) => return bail ! (
460
+ & * item,
461
+ "`#[rpc(config = ...)]` is mutually exclusive with any other parameters(`any_peer`, `reliable`, `call_local`, `channel = 0`)"
462
+ ) ,
463
+
464
+ // Ok: `config` is not present, any combination of the other parameters is allowed.
451
465
_ => RpcAttr :: SeparatedArgs {
452
466
rpc_mode,
453
467
transfer_mode,
@@ -476,19 +490,21 @@ where
476
490
477
491
let attr_name = attr_name. clone ( ) ;
478
492
479
- // Remaining code no longer has attribute -- rest stays
480
- attributes. remove ( index - 1 ) ; // -1 because we bumped the index at the beginning of the loop
493
+ // Remaining code no longer has attribute -- rest stays.
494
+ attributes. remove ( index - 1 ) ; // -1 because we bumped the index at the beginning of the loop.
481
495
index -= 1 ;
482
496
483
497
let ( new_name, new_attr) = match ( found, parsed_attr) {
484
- // First attribute
498
+ // First attribute.
485
499
( None , parsed) => ( attr_name, parsed) ,
500
+
486
501
// Regardless of the order, if we found both `#[func]` and `#[rpc]`, we can just merge them.
487
502
( Some ( ( found_name, AttrParseResult :: Func ( func) ) ) , AttrParseResult :: Rpc ( rpc) )
488
503
| ( Some ( ( found_name, AttrParseResult :: Rpc ( rpc) ) ) , AttrParseResult :: Func ( func) ) => (
489
504
ident ( & format ! ( "{found_name}_{attr_name}" ) ) ,
490
505
AttrParseResult :: FuncRpc ( func, rpc) ,
491
506
) ,
507
+
492
508
// We found two incompatible attributes.
493
509
( Some ( ( found_name, _) ) , _) => {
494
510
return bail ! ( & * item, "The attributes `{found_name}` and `{attr_name}` cannot be used in the same declaration" ) ?;
0 commit comments