7
7
mod attribute_ops;
8
8
mod impl_attribute;
9
9
mod type_paths;
10
+ mod enums;
10
11
11
12
use attribute_ops:: { FieldOpts , GodotScriptOpts } ;
12
- use darling:: { FromAttributes , FromDeriveInput } ;
13
+ use darling:: { util :: SpannedValue , FromAttributes , FromDeriveInput } ;
13
14
use proc_macro2:: TokenStream ;
14
15
use quote:: { quote, quote_spanned, ToTokens } ;
15
16
use syn:: { parse_macro_input, spanned:: Spanned , DeriveInput , Ident , Type } ;
16
- use type_paths:: { godot_types, string_name_ty, variant_ty} ;
17
+ use type_paths:: { godot_types, property_hints , string_name_ty, variant_ty} ;
17
18
18
19
use crate :: attribute_ops:: { FieldExportOps , PropertyOpts } ;
19
20
@@ -27,6 +28,7 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
27
28
let variant_ty = variant_ty ( ) ;
28
29
let string_name_ty = string_name_ty ( ) ;
29
30
let call_error_ty = quote ! ( #godot_types:: sys:: GDExtensionCallErrorType ) ;
31
+ let property_hint_ty = property_hints ( ) ;
30
32
31
33
let base_class = opts
32
34
. base
@@ -63,12 +65,17 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
63
65
. iter ( )
64
66
. any ( |attr| attr. path ( ) . is_ident ( "export" ) ) ;
65
67
66
- let ( hint, hint_string) = {
68
+ let ( hint, hint_string) = exported . then ( || {
67
69
let ops = FieldExportOps :: from_attributes ( & field. attrs )
68
70
. map_err ( |err| err. write_errors ( ) ) ?;
69
71
70
- ops. hint ( & field. ty ) ?
71
- } ;
72
+ ops. hint ( & field. ty )
73
+ } ) . transpose ( ) ?. unwrap_or_else ( || {
74
+ (
75
+ quote_spanned ! ( field. span( ) => #property_hint_ty:: NONE ) ,
76
+ quote_spanned ! ( field. span( ) => String :: new( ) ) ,
77
+ )
78
+ } ) ;
72
79
73
80
let description = get_field_description ( field) ;
74
81
let item = quote ! {
@@ -176,8 +183,9 @@ fn rust_to_variant_type(ty: &syn::Type) -> Result<TokenStream, TokenStream> {
176
183
T :: Path ( path) => Ok ( quote_spanned ! {
177
184
ty. span( ) => {
178
185
use #godot_types:: sys:: GodotFfi ;
186
+ use #godot_types:: meta:: GodotType ;
179
187
180
- <#path as #godot_types:: meta:: GodotType >:: Ffi :: variant_type( )
188
+ << #path as #godot_types:: meta:: GodotConvert > :: Via as GodotType >:: Ffi :: variant_type( )
181
189
}
182
190
} ) ,
183
191
T :: Verbatim ( _) => Err ( syn:: Error :: new (
@@ -197,8 +205,9 @@ fn rust_to_variant_type(ty: &syn::Type) -> Result<TokenStream, TokenStream> {
197
205
Ok ( quote_spanned ! {
198
206
tuple. span( ) => {
199
207
use #godot_types:: sys:: GodotFfi ;
208
+ use #godot_types:: meta:: GodotType ;
200
209
201
- <#tuple as #godot_types:: meta:: GodotType >:: Ffi :: variant_type( )
210
+ << #tuple as #godot_types:: meta:: GodotConvert > :: Via as GodotType >:: Ffi :: variant_type( )
202
211
}
203
212
} )
204
213
}
@@ -218,7 +227,7 @@ fn is_context_type(ty: &syn::Type) -> bool {
218
227
path. path . segments . last ( ) . map ( |segment| segment. ident == "Context" ) . unwrap_or ( false )
219
228
}
220
229
221
- fn derive_default_with_base ( field_opts : & [ FieldOpts ] ) -> TokenStream {
230
+ fn derive_default_with_base ( field_opts : & [ SpannedValue < FieldOpts > ] ) -> TokenStream {
222
231
let godot_types = godot_types ( ) ;
223
232
let fields: TokenStream = field_opts
224
233
. iter ( )
@@ -245,7 +254,7 @@ fn derive_default_with_base(field_opts: &[FieldOpts]) -> TokenStream {
245
254
}
246
255
}
247
256
248
- fn derive_get_fields < ' a > ( public_fields : impl Iterator < Item = & ' a FieldOpts > + ' a ) -> TokenStream {
257
+ fn derive_get_fields < ' a > ( public_fields : impl Iterator < Item = & ' a SpannedValue < FieldOpts > > + ' a ) -> TokenStream {
249
258
let godot_types = godot_types ( ) ;
250
259
let string_name_ty = string_name_ty ( ) ;
251
260
let variant_ty = variant_ty ( ) ;
@@ -262,11 +271,11 @@ fn derive_get_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
262
271
} ;
263
272
264
273
let accessor = match opts. get {
265
- Some ( getter) => quote_spanned ! ( getter. span( ) => #getter( & self ) ) ,
266
- None => quote ! ( self . #field_ident) ,
274
+ Some ( getter) => quote_spanned ! ( getter. span( ) => #getter( & self ) ) ,
275
+ None => quote_spanned ! ( field_ident . span ( ) => self . #field_ident) ,
267
276
} ;
268
277
269
- quote ! {
278
+ quote_spanned ! { field . ty . span ( ) =>
270
279
#[ allow( clippy:: needless_borrow) ]
271
280
#field_name => Some ( #godot_types:: prelude:: ToGodot :: to_variant( & #accessor) ) ,
272
281
}
@@ -284,7 +293,7 @@ fn derive_get_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
284
293
}
285
294
}
286
295
287
- fn derive_set_fields < ' a > ( public_fields : impl Iterator < Item = & ' a FieldOpts > + ' a ) -> TokenStream {
296
+ fn derive_set_fields < ' a > ( public_fields : impl Iterator < Item = & ' a SpannedValue < FieldOpts > > + ' a ) -> TokenStream {
288
297
let string_name_ty = string_name_ty ( ) ;
289
298
let variant_ty = variant_ty ( ) ;
290
299
let godot_types = godot_types ( ) ;
@@ -300,15 +309,14 @@ fn derive_set_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
300
309
Err ( err) => return err. write_errors ( ) ,
301
310
} ;
302
311
303
- let variant_value = quote ! ( #godot_types:: prelude:: FromGodot :: try_from_variant( & value) ) ;
312
+ let variant_value = quote_spanned ! ( field . ty . span ( ) => #godot_types:: prelude:: FromGodot :: try_from_variant( & value) ) ;
304
313
305
314
let assignment = match opts. set {
306
- Some ( setter) => quote_spanned ! ( setter. span( ) => #setter( self , local_value) ) ,
307
- None => quote ! ( self . #field_ident = local_value) ,
315
+ Some ( setter) => quote_spanned ! ( setter. span( ) => #setter( self , local_value) ) ,
316
+ None => quote_spanned ! ( field . ty . span ( ) => self . #field_ident = local_value) ,
308
317
} ;
309
318
310
- quote_spanned ! {
311
- field_ident. span( ) =>
319
+ quote ! {
312
320
#field_name => {
313
321
let local_value = match #variant_value {
314
322
Ok ( v) => v,
@@ -334,7 +342,7 @@ fn derive_set_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
334
342
}
335
343
336
344
fn derive_property_states_export < ' a > (
337
- public_fields : impl Iterator < Item = & ' a FieldOpts > + ' a ,
345
+ public_fields : impl Iterator < Item = & ' a SpannedValue < FieldOpts > > + ' a ,
338
346
) -> TokenStream {
339
347
let string_name_ty = string_name_ty ( ) ;
340
348
let variant_ty = variant_ty ( ) ;
@@ -420,3 +428,8 @@ fn extract_ident_from_type(impl_target: &syn::Type) -> Result<Ident, TokenStream
420
428
_ => Err ( compile_error ( "Unsupported type!" , impl_target) ) ,
421
429
}
422
430
}
431
+
432
+ #[ proc_macro_derive( GodotScriptEnum , attributes( script_enum) ) ]
433
+ pub fn script_enum_derive ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
434
+ enums:: script_enum_derive ( input)
435
+ }
0 commit comments