77mod attribute_ops;
88mod impl_attribute;
99mod type_paths;
10+ mod enums;
1011
1112use attribute_ops:: { FieldOpts , GodotScriptOpts } ;
12- use darling:: { FromAttributes , FromDeriveInput } ;
13+ use darling:: { util :: SpannedValue , FromAttributes , FromDeriveInput } ;
1314use proc_macro2:: TokenStream ;
1415use quote:: { quote, quote_spanned, ToTokens } ;
1516use 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} ;
1718
1819use crate :: attribute_ops:: { FieldExportOps , PropertyOpts } ;
1920
@@ -27,6 +28,7 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
2728 let variant_ty = variant_ty ( ) ;
2829 let string_name_ty = string_name_ty ( ) ;
2930 let call_error_ty = quote ! ( #godot_types:: sys:: GDExtensionCallErrorType ) ;
31+ let property_hint_ty = property_hints ( ) ;
3032
3133 let base_class = opts
3234 . base
@@ -63,12 +65,17 @@ pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
6365 . iter ( )
6466 . any ( |attr| attr. path ( ) . is_ident ( "export" ) ) ;
6567
66- let ( hint, hint_string) = {
68+ let ( hint, hint_string) = exported . then ( || {
6769 let ops = FieldExportOps :: from_attributes ( & field. attrs )
6870 . map_err ( |err| err. write_errors ( ) ) ?;
6971
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+ } ) ;
7279
7380 let description = get_field_description ( field) ;
7481 let item = quote ! {
@@ -176,8 +183,9 @@ fn rust_to_variant_type(ty: &syn::Type) -> Result<TokenStream, TokenStream> {
176183 T :: Path ( path) => Ok ( quote_spanned ! {
177184 ty. span( ) => {
178185 use #godot_types:: sys:: GodotFfi ;
186+ use #godot_types:: meta:: GodotType ;
179187
180- <#path as #godot_types:: meta:: GodotType >:: Ffi :: variant_type( )
188+ << #path as #godot_types:: meta:: GodotConvert > :: Via as GodotType >:: Ffi :: variant_type( )
181189 }
182190 } ) ,
183191 T :: Verbatim ( _) => Err ( syn:: Error :: new (
@@ -197,8 +205,9 @@ fn rust_to_variant_type(ty: &syn::Type) -> Result<TokenStream, TokenStream> {
197205 Ok ( quote_spanned ! {
198206 tuple. span( ) => {
199207 use #godot_types:: sys:: GodotFfi ;
208+ use #godot_types:: meta:: GodotType ;
200209
201- <#tuple as #godot_types:: meta:: GodotType >:: Ffi :: variant_type( )
210+ << #tuple as #godot_types:: meta:: GodotConvert > :: Via as GodotType >:: Ffi :: variant_type( )
202211 }
203212 } )
204213 }
@@ -218,7 +227,7 @@ fn is_context_type(ty: &syn::Type) -> bool {
218227 path. path . segments . last ( ) . map ( |segment| segment. ident == "Context" ) . unwrap_or ( false )
219228}
220229
221- fn derive_default_with_base ( field_opts : & [ FieldOpts ] ) -> TokenStream {
230+ fn derive_default_with_base ( field_opts : & [ SpannedValue < FieldOpts > ] ) -> TokenStream {
222231 let godot_types = godot_types ( ) ;
223232 let fields: TokenStream = field_opts
224233 . iter ( )
@@ -245,7 +254,7 @@ fn derive_default_with_base(field_opts: &[FieldOpts]) -> TokenStream {
245254 }
246255}
247256
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 {
249258 let godot_types = godot_types ( ) ;
250259 let string_name_ty = string_name_ty ( ) ;
251260 let variant_ty = variant_ty ( ) ;
@@ -262,11 +271,11 @@ fn derive_get_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
262271 } ;
263272
264273 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) ,
267276 } ;
268277
269- quote ! {
278+ quote_spanned ! { field . ty . span ( ) =>
270279 #[ allow( clippy:: needless_borrow) ]
271280 #field_name => Some ( #godot_types:: prelude:: ToGodot :: to_variant( & #accessor) ) ,
272281 }
@@ -284,7 +293,7 @@ fn derive_get_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
284293 }
285294}
286295
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 {
288297 let string_name_ty = string_name_ty ( ) ;
289298 let variant_ty = variant_ty ( ) ;
290299 let godot_types = godot_types ( ) ;
@@ -300,15 +309,14 @@ fn derive_set_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
300309 Err ( err) => return err. write_errors ( ) ,
301310 } ;
302311
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) ) ;
304313
305314 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) ,
308317 } ;
309318
310- quote_spanned ! {
311- field_ident. span( ) =>
319+ quote ! {
312320 #field_name => {
313321 let local_value = match #variant_value {
314322 Ok ( v) => v,
@@ -334,7 +342,7 @@ fn derive_set_fields<'a>(public_fields: impl Iterator<Item = &'a FieldOpts> + 'a
334342}
335343
336344fn derive_property_states_export < ' a > (
337- public_fields : impl Iterator < Item = & ' a FieldOpts > + ' a ,
345+ public_fields : impl Iterator < Item = & ' a SpannedValue < FieldOpts > > + ' a ,
338346) -> TokenStream {
339347 let string_name_ty = string_name_ty ( ) ;
340348 let variant_ty = variant_ty ( ) ;
@@ -420,3 +428,8 @@ fn extract_ident_from_type(impl_target: &syn::Type) -> Result<Ident, TokenStream
420428 _ => Err ( compile_error ( "Unsupported type!" , impl_target) ) ,
421429 }
422430}
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