@@ -28,13 +28,14 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
28
28
..
29
29
} = parsed;
30
30
31
- let category = & attributes. category . as_ref ( ) . map ( |value| quote ! ( Some ( #value) ) ) . unwrap_or ( quote ! ( None ) ) ;
31
+ let category = & attributes. category . as_ref ( ) . map ( |value| quote_spanned ! ( value . span ( ) => Some ( #value) ) ) . unwrap_or ( quote ! ( None ) ) ;
32
32
let mod_name = format_ident ! ( "_{}_mod" , mod_name) ;
33
33
34
34
let display_name = match & attributes. display_name . as_ref ( ) {
35
35
Some ( lit) => lit. value ( ) ,
36
36
None => struct_name. to_string ( ) . to_case ( Case :: Title ) ,
37
37
} ;
38
+ let struct_name_ident = struct_name;
38
39
let struct_name = format_ident ! ( "{}Node" , struct_name) ;
39
40
40
41
let struct_generics: Vec < Ident > = fields. iter ( ) . enumerate ( ) . map ( |( i, _) | format_ident ! ( "Node{}" , i) ) . collect ( ) ;
@@ -84,50 +85,50 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
84
85
let field_types: Vec < _ > = fields
85
86
. iter ( )
86
87
. map ( |field| match field {
87
- ParsedField :: Regular { ty, .. } => ty. clone ( ) ,
88
+ ParsedField :: Regular { ty, .. } => quote_spanned ! ( ty. span ( ) => #ty ) ,
88
89
ParsedField :: Node { output_type, input_type, .. } => match parsed. is_async {
89
- true => parse_quote ! ( & ' n impl #graphene_core:: Node <' n, #input_type, Output = impl core:: future:: Future <Output =#output_type>>) ,
90
- false => parse_quote ! ( & ' n impl #graphene_core:: Node <' n, #input_type, Output = #output_type>) ,
90
+ true => quote_spanned ! ( output_type . span ( ) => & ' n impl #graphene_core:: Node <' n, #input_type, Output = impl core:: future:: Future <Output =#output_type>>) ,
91
+ false => quote_spanned ! ( output_type . span ( ) => & ' n impl #graphene_core:: Node <' n, #input_type, Output = #output_type>) ,
91
92
} ,
92
93
} )
93
94
. collect ( ) ;
94
95
95
96
let widget_override: Vec < _ > = fields
96
97
. iter ( )
97
98
. map ( |field| {
98
- let parsed_widget_override = match field {
99
- ParsedField :: Regular { widget_override, .. } => widget_override,
100
- ParsedField :: Node { widget_override, .. } => widget_override,
99
+ let ( parsed_widget_override, span ) = match field {
100
+ ParsedField :: Regular { widget_override, pat_ident , .. } => ( widget_override, pat_ident . span ( ) ) ,
101
+ ParsedField :: Node { widget_override, pat_ident , .. } => ( widget_override, pat_ident . span ( ) ) ,
101
102
} ;
102
103
match parsed_widget_override {
103
- ParsedWidgetOverride :: None => quote ! ( RegistryWidgetOverride :: None ) ,
104
- ParsedWidgetOverride :: Hidden => quote ! ( RegistryWidgetOverride :: Hidden ) ,
105
- ParsedWidgetOverride :: String ( lit_str) => quote ! ( RegistryWidgetOverride :: String ( #lit_str) ) ,
106
- ParsedWidgetOverride :: Custom ( lit_str) => quote ! ( RegistryWidgetOverride :: Custom ( #lit_str) ) ,
104
+ ParsedWidgetOverride :: None => quote_spanned ! ( span => RegistryWidgetOverride :: None ) ,
105
+ ParsedWidgetOverride :: Hidden => quote_spanned ! ( span => RegistryWidgetOverride :: Hidden ) ,
106
+ ParsedWidgetOverride :: String ( lit_str) => quote_spanned ! ( lit_str . span ( ) => RegistryWidgetOverride :: String ( #lit_str) ) ,
107
+ ParsedWidgetOverride :: Custom ( lit_str) => quote_spanned ! ( lit_str . span ( ) => RegistryWidgetOverride :: Custom ( #lit_str) ) ,
107
108
}
108
109
} )
109
110
. collect ( ) ;
110
111
111
112
let value_sources: Vec < _ > = fields
112
113
. iter ( )
113
114
. map ( |field| match field {
114
- ParsedField :: Regular { value_source, .. } => match value_source {
115
- ParsedValueSource :: Default ( data) => quote ! ( RegistryValueSource :: Default ( stringify!( #data) ) ) ,
116
- ParsedValueSource :: Scope ( data) => quote ! ( RegistryValueSource :: Scope ( #data) ) ,
117
- _ => quote ! ( RegistryValueSource :: None ) ,
115
+ ParsedField :: Regular { value_source, pat_ident , .. } => match value_source {
116
+ ParsedValueSource :: Default ( data) => quote_spanned ! ( data . span ( ) => RegistryValueSource :: Default ( stringify!( #data) ) ) ,
117
+ ParsedValueSource :: Scope ( data) => quote_spanned ! ( data . span ( ) => RegistryValueSource :: Scope ( #data) ) ,
118
+ _ => quote_spanned ! ( pat_ident . span ( ) => RegistryValueSource :: None ) ,
118
119
} ,
119
- _ => quote ! ( RegistryValueSource :: None ) ,
120
+ ParsedField :: Node { pat_ident , .. } => quote_spanned ! ( pat_ident . span ( ) => RegistryValueSource :: None ) ,
120
121
} )
121
122
. collect ( ) ;
122
123
123
124
let default_types: Vec < _ > = fields
124
125
. iter ( )
125
126
. map ( |field| match field {
126
- ParsedField :: Regular { implementations, .. } => match implementations. first ( ) {
127
- Some ( ty) => quote ! ( Some ( concrete!( #ty) ) ) ,
128
- _ => quote ! ( None ) ,
127
+ ParsedField :: Regular { implementations, pat_ident , .. } => match implementations. first ( ) {
128
+ Some ( ty) => quote_spanned ! ( ty . span ( ) => Some ( concrete!( #ty) ) ) ,
129
+ _ => quote_spanned ! ( pat_ident . span ( ) => None ) ,
129
130
} ,
130
- _ => quote ! ( None ) ,
131
+ ParsedField :: Node { pat_ident , .. } => quote_spanned ! ( pat_ident . span ( ) => None ) ,
131
132
} )
132
133
. collect ( ) ;
133
134
@@ -167,19 +168,23 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
167
168
let exposed: Vec < _ > = fields
168
169
. iter ( )
169
170
. map ( |field| match field {
170
- ParsedField :: Regular { exposed, .. } => quote ! ( #exposed) ,
171
- _ => quote ! ( true ) ,
171
+ ParsedField :: Regular { exposed, pat_ident , .. } => quote_spanned ! ( pat_ident . span ( ) => #exposed) ,
172
+ ParsedField :: Node { pat_ident , .. } => quote_spanned ! ( pat_ident . span ( ) => true ) ,
172
173
} )
173
174
. collect ( ) ;
174
175
175
176
let eval_args = fields. iter ( ) . map ( |field| match field {
176
177
ParsedField :: Regular { pat_ident, .. } => {
177
178
let name = & pat_ident. ident ;
178
- quote ! { let #name = self . #name. eval( __input. clone( ) ) . await ; }
179
+ quote_spanned ! { pat_ident. span( ) =>
180
+ let #name = self . #name. eval( __input. clone( ) ) . await ;
181
+ }
179
182
}
180
183
ParsedField :: Node { pat_ident, .. } => {
181
184
let name = & pat_ident. ident ;
182
- quote ! { let #name = & self . #name; }
185
+ quote_spanned ! { pat_ident. span( ) =>
186
+ let #name = & self . #name;
187
+ }
183
188
}
184
189
} ) ;
185
190
@@ -239,10 +244,10 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
239
244
// Add Clampable bound if this field uses hard_min or hard_max
240
245
if number_hard_min. is_some ( ) || number_hard_max. is_some ( ) {
241
246
// The bound applies to the Output type of the future, which is #ty
242
- clampable_clauses. push ( quote ! ( #ty: #graphene_core:: misc:: Clampable ) ) ;
247
+ clampable_clauses. push ( quote_spanned ! ( ty . span ( ) => #ty: #graphene_core:: misc:: Clampable ) ) ;
243
248
}
244
249
245
- quote ! (
250
+ quote_spanned ! ( ty . span ( ) =>
246
251
#fut_ident: core:: future:: Future <Output = #ty> + #graphene_core:: WasmNotSend + ' n,
247
252
for <' all> #all_lifetime_ty: #graphene_core:: WasmNotSend ,
248
253
#name: #graphene_core:: Node <' n, #input_type, Output = #fut_ident> + #graphene_core:: WasmNotSync
@@ -253,7 +258,7 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
253
258
let fut_ident = format_ident ! ( "F{}" , id) ;
254
259
future_idents. push ( fut_ident. clone ( ) ) ;
255
260
256
- quote ! (
261
+ quote_spanned ! ( output_type . span ( ) =>
257
262
#fut_ident: core:: future:: Future <Output = #output_type> + #graphene_core:: WasmNotSend + ' n,
258
263
#name: #graphene_core:: Node <' n, #input_type, Output = #fut_ident > + #graphene_core:: WasmNotSync
259
264
)
@@ -274,9 +279,7 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
274
279
) ;
275
280
struct_where_clause. predicates . extend ( extra_where) ;
276
281
277
- let new_args = struct_generics. iter ( ) . zip ( field_names. iter ( ) ) . map ( |( r#gen, name) | {
278
- quote ! { #name: #r#gen }
279
- } ) ;
282
+ let new_args = struct_generics. iter ( ) . zip ( field_names. iter ( ) ) . map ( |( r#gen, name) | quote_spanned ! ( name. span( ) => #name: #r#gen) ) ;
280
283
281
284
let async_keyword = is_async. then ( || quote ! ( async ) ) ;
282
285
let await_keyword = is_async. then ( || quote ! ( . await ) ) ;
@@ -295,18 +298,23 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
295
298
}
296
299
} ;
297
300
let path = match parsed. attributes . path {
298
- Some ( ref path) => quote ! ( stringify!( #path) . replace( ' ' , "" ) ) ,
301
+ Some ( ref path) => quote_spanned ! ( path . span ( ) => stringify!( #path) . replace( ' ' , "" ) ) ,
299
302
None => quote ! ( std:: module_path!( ) . rsplit_once( "::" ) . unwrap( ) . 0 ) ,
300
303
} ;
301
- let identifier = quote ! ( format!( "{}::{}" , #path, stringify!( #struct_name) ) ) ;
304
+ let identifier = quote_spanned ! ( struct_name_ident . span ( ) => format!( "{}::{}" , #path, stringify!( #struct_name) ) ) ;
302
305
303
306
let register_node_impl = generate_register_node_impl ( parsed, & field_names, & struct_name, & identifier) ?;
304
307
let import_name = format_ident ! ( "_IMPORT_STUB_{}" , mod_name. to_string( ) . to_case( Case :: UpperSnake ) ) ;
305
308
306
- let properties = & attributes. properties_string . as_ref ( ) . map ( |value| quote ! ( Some ( #value) ) ) . unwrap_or ( quote ! ( None ) ) ;
309
+ let properties = & attributes. properties_string . as_ref ( ) . map ( |value| quote_spanned ! ( value . span ( ) => Some ( #value) ) ) . unwrap_or ( quote ! ( None ) ) ;
307
310
308
311
let node_input_accessor = generate_node_input_references ( parsed, fn_generics, & field_idents, & graphene_core, & identifier) ;
309
- Ok ( quote ! {
312
+
313
+ // ==========================
314
+ // MAIN CODE GENERATION BLOCK
315
+ // ==========================
316
+
317
+ Ok ( quote_spanned ! { parsed. fn_name. span( ) =>
310
318
/// Underlying implementation for [#struct_name]
311
319
#[ inline]
312
320
#[ allow( clippy:: too_many_arguments) ]
@@ -410,17 +418,17 @@ fn generate_node_input_references(parsed: &ParsedNodeFn, fn_generics: &[crate::G
410
418
411
419
// Only create structs with phantom data where necessary.
412
420
generated_input_accessor. push ( if phantom_data_declerations. is_empty ( ) {
413
- quote ! {
421
+ quote_spanned ! { input_ident . span ( ) =>
414
422
pub struct #struct_name;
415
423
}
416
424
} else {
417
- quote ! {
425
+ quote_spanned ! { input_ident . span ( ) =>
418
426
pub struct #struct_name <#( #used) , * >{
419
427
#( #phantom_data_declerations, ) *
420
428
}
421
429
}
422
430
} ) ;
423
- generated_input_accessor. push ( quote ! {
431
+ generated_input_accessor. push ( quote_spanned ! { input_ident . span ( ) =>
424
432
impl <#( #used) , * > #graphene_core:: NodeInputDecleration for #struct_name <#( #fn_generic_params) , * > {
425
433
const INDEX : usize = #input_index;
426
434
fn identifier( ) -> & ' static str {
@@ -457,14 +465,14 @@ fn generate_phantom_data<'a>(fn_generics: impl Iterator<Item = &'a crate::Generi
457
465
crate :: GenericParam :: Lifetime ( lifetime_param) => {
458
466
let lifetime = & lifetime_param. lifetime ;
459
467
460
- fn_generic_params. push ( quote ! { #lifetime} ) ;
461
- phantom_data_declerations. push ( quote ! { #field_name: core:: marker:: PhantomData <& #lifetime ( ) >} )
468
+ fn_generic_params. push ( quote_spanned ! ( lifetime . span ( ) => #lifetime) ) ;
469
+ phantom_data_declerations. push ( quote_spanned ! ( lifetime . span ( ) => #field_name: core:: marker:: PhantomData <& #lifetime ( ) >) )
462
470
}
463
471
crate :: GenericParam :: Type ( type_param) => {
464
472
let generic_name = & type_param. ident ;
465
473
466
- fn_generic_params. push ( quote ! { #generic_name} ) ;
467
- phantom_data_declerations. push ( quote ! { #field_name: core:: marker:: PhantomData <#generic_name>} ) ;
474
+ fn_generic_params. push ( quote_spanned ! ( generic_name . span ( ) => #generic_name) ) ;
475
+ phantom_data_declerations. push ( quote_spanned ! ( generic_name . span ( ) => #field_name: core:: marker:: PhantomData <#generic_name>) ) ;
468
476
}
469
477
_ => { }
470
478
}
@@ -523,21 +531,21 @@ fn generate_register_node_impl(parsed: &ParsedNodeFn, field_names: &[&Ident], st
523
531
524
532
let node = matches ! ( parsed. fields[ j] , ParsedField :: Node { .. } ) ;
525
533
526
- let downcast_node = quote ! (
534
+ let downcast_node = quote_spanned ! ( field_name . span ( ) =>
527
535
let #field_name: DowncastBothNode <#input_type, #output_type> = DowncastBothNode :: new( args[ #j] . clone( ) ) ;
528
536
) ;
529
537
if node && !parsed. is_async {
530
538
return Err ( Error :: new_spanned ( & parsed. fn_name , "Node needs to be async if you want to use lambda parameters" ) ) ;
531
539
}
532
540
temp_constructors. push ( downcast_node) ;
533
- temp_node_io. push ( quote ! ( fn_type_fut!( #input_type, #output_type, alias: #output_type) ) ) ;
534
- panic_node_types. push ( quote ! ( #input_type, DynFuture <' static , #output_type>) ) ;
541
+ temp_node_io. push ( quote_spanned ! ( output_type . span ( ) => fn_type_fut!( #input_type, #output_type, alias: #output_type) ) ) ;
542
+ panic_node_types. push ( quote_spanned ! ( output_type . span ( ) => #input_type, DynFuture <' static , #output_type>) ) ;
535
543
}
536
544
let input_type = match parsed. input . implementations . is_empty ( ) {
537
545
true => parsed. input . ty . clone ( ) ,
538
546
false => parsed. input . implementations [ i. min ( parsed. input . implementations . len ( ) - 1 ) ] . clone ( ) ,
539
547
} ;
540
- constructors. push ( quote ! (
548
+ constructors. push ( quote_spanned ! ( struct_name . span ( ) =>
541
549
(
542
550
|args| {
543
551
Box :: pin( async move {
@@ -580,6 +588,10 @@ fn generate_register_node_impl(parsed: &ParsedNodeFn, field_names: &[&Ident], st
580
588
} )
581
589
}
582
590
591
+ // ========================
592
+ // HELPER STRUCTS AND IMPLS
593
+ // ========================
594
+
583
595
use syn:: visit_mut:: VisitMut ;
584
596
use syn:: { GenericArgument , Lifetime , Type } ;
585
597
0 commit comments