@@ -79,14 +79,14 @@ impl StarFun {
79
79
}
80
80
81
81
/// Evaluator function parameter and call argument.
82
- fn eval_param_arg ( & self ) -> ( Option < syn:: PatType > , Option < TokenStream > ) {
82
+ fn eval_param_arg ( & self ) -> ( Option < syn:: PatType > , Option < syn :: Expr > ) {
83
83
if let Some ( SpecialParam { ident, ty } ) = & self . eval {
84
84
(
85
85
Some ( syn:: parse_quote! {
86
86
#ident: #ty
87
87
} ) ,
88
- Some ( quote ! {
89
- eval,
88
+ Some ( syn :: parse_quote ! {
89
+ eval
90
90
} ) ,
91
91
)
92
92
} else {
@@ -95,14 +95,14 @@ impl StarFun {
95
95
}
96
96
97
97
/// Heap function parameter and call argument.
98
- fn heap_param_arg ( & self ) -> ( Option < syn:: PatType > , Option < TokenStream > ) {
98
+ fn heap_param_arg ( & self ) -> ( Option < syn:: PatType > , Option < syn :: Expr > ) {
99
99
if let Some ( SpecialParam { ident, ty } ) = & self . heap {
100
100
(
101
101
Some ( syn:: parse_quote! {
102
102
#ident: #ty
103
103
} ) ,
104
- Some ( quote ! {
105
- eval. heap( ) ,
104
+ Some ( syn :: parse_quote ! {
105
+ eval. heap( )
106
106
} ) ,
107
107
)
108
108
} else {
@@ -119,7 +119,7 @@ impl StarFun {
119
119
// Inner function parameter.
120
120
Option < syn:: PatType > ,
121
121
Option < syn:: Stmt > ,
122
- Option < TokenStream > ,
122
+ Option < syn :: Expr > ,
123
123
) {
124
124
match & self . this {
125
125
Some ( this) => {
@@ -129,7 +129,7 @@ impl StarFun {
129
129
Some ( syn:: parse_quote! { #outer_param_name: starlark:: values:: Value <' v> } ) ,
130
130
Some ( this. reconstruct_param ( ) ) ,
131
131
Some ( this. render_prepare ( & local_var, & outer_param_name) ) ,
132
- Some ( quote ! { #local_var, } ) ,
132
+ Some ( syn :: parse_quote ! { #local_var } ) ,
133
133
)
134
134
}
135
135
None => ( None , None , None , None ) ,
@@ -161,28 +161,28 @@ impl StarFun {
161
161
}
162
162
163
163
/// Fields and field initializers for the struct implementing the trait.
164
- fn struct_fields ( & self ) -> syn:: Result < ( TokenStream , TokenStream ) > {
164
+ fn struct_fields ( & self ) -> syn:: Result < ( Vec < syn :: Field > , Vec < syn :: FieldValue > ) > {
165
165
let signature = if let StarFunSource :: Signature { .. } = self . source {
166
166
Some ( render_signature ( self ) ?)
167
167
} else {
168
168
None
169
169
} ;
170
170
if let Some ( signature) = signature {
171
171
Ok ( (
172
- quote ! {
173
- signature: starlark:: eval:: ParametersSpec <starlark:: values:: FrozenValue >,
174
- } ,
175
- quote ! {
176
- signature: #signature,
177
- } ,
172
+ vec ! [ syn :: parse_quote ! {
173
+ signature: starlark:: eval:: ParametersSpec <starlark:: values:: FrozenValue >
174
+ } ] ,
175
+ vec ! [ syn :: parse_quote ! {
176
+ signature: #signature
177
+ } ] ,
178
178
) )
179
179
} else {
180
- Ok ( ( TokenStream :: new ( ) , TokenStream :: new ( ) ) )
180
+ Ok ( ( Vec :: new ( ) , Vec :: new ( ) ) )
181
181
}
182
182
}
183
183
184
184
/// Globals builder call to register the function.
185
- fn builder_set ( & self , struct_fields_init : TokenStream ) -> syn:: Result < syn:: Stmt > {
185
+ fn builder_set ( & self , struct_fields_init : Vec < syn :: FieldValue > ) -> syn:: Result < syn:: Stmt > {
186
186
let name_str = self . name_str ( ) ;
187
187
let components = render_native_callable_components ( self ) ?;
188
188
@@ -208,7 +208,7 @@ impl StarFun {
208
208
#name_str,
209
209
#components,
210
210
#struct_name {
211
- #struct_fields_init
211
+ #( # struct_fields_init, ) *
212
212
} ,
213
213
) ;
214
214
} )
@@ -224,7 +224,7 @@ impl StarFun {
224
224
#ty_custom,
225
225
#special_builtin_function,
226
226
#struct_name {
227
- #struct_fields_init
227
+ #( # struct_fields_init, ) *
228
228
} ,
229
229
) ;
230
230
} )
@@ -259,64 +259,79 @@ pub(crate) fn render_fun(x: StarFun) -> syn::Result<syn::Stmt> {
259
259
. chain ( heap_param)
260
260
. collect ( ) ;
261
261
262
+ let invoke_args = iter:: empty ( )
263
+ . chain ( this_arg)
264
+ . chain ( binding_args)
265
+ . chain ( eval_arg)
266
+ . chain ( heap_arg) ;
267
+
262
268
let param_types: Vec < _ > = invoke_params. iter ( ) . map ( |p| & p. ty ) . collect ( ) ;
263
269
264
270
let this_outer_param = this_outer_param. into_iter ( ) ;
265
271
266
- Ok ( syn:: parse_quote! {
267
- {
268
- struct #struct_name {
269
- #struct_fields
270
- }
272
+ let struct_def : syn :: ItemStruct = syn:: parse_quote! {
273
+ struct #struct_name {
274
+ # ( #struct_fields , ) *
275
+ }
276
+ } ;
271
277
272
- impl #struct_name {
273
- // TODO(nga): copy lifetime parameter from declaration,
274
- // so the warning would be precise.
275
- #[ allow( clippy:: extra_unused_lifetimes) ]
276
- #( #attrs ) *
277
- fn invoke_impl<' v>(
278
- #( #invoke_params, ) *
279
- ) -> #return_type {
280
- #body
281
- }
278
+ let impl_struct: syn:: ItemImpl = syn:: parse_quote! {
279
+ impl #struct_name {
280
+ // TODO(nga): copy lifetime parameter from declaration,
281
+ // so the warning would be precise.
282
+ #[ allow( clippy:: extra_unused_lifetimes) ]
283
+ #( #attrs ) *
284
+ fn invoke_impl<' v>(
285
+ #( #invoke_params, ) *
286
+ ) -> #return_type {
287
+ #body
288
+ }
282
289
283
- // When function signature declares return type as `anyhow::Result<impl AllocValue>`,
284
- // we cannot call `T::starlark_type_repr` to render documentation, because there's no T.
285
- // Future Rust will provide syntax `type ReturnType = impl AllocValue`:
286
- // https://github.com/rust-lang/rfcs/pull/2515
287
- // Until then we use this hack as a workaround.
288
- #[ allow( dead_code) ] // Function is not used when return type is specified explicitly.
289
- fn return_type_starlark_type_repr( ) -> starlark:: typing:: Ty {
290
- fn get_impl<' v, T : starlark:: values:: AllocValue <' v>, E >(
291
- _f: fn (
292
- #( #param_types, ) *
293
- ) -> std:: result:: Result <T , E >,
294
- ) -> starlark:: typing:: Ty {
295
- <T as starlark:: values:: type_repr:: StarlarkTypeRepr >:: starlark_type_repr( )
296
- }
297
- get_impl( Self :: invoke_impl)
290
+ // When function signature declares return type as `anyhow::Result<impl AllocValue>`,
291
+ // we cannot call `T::starlark_type_repr` to render documentation, because there's no T.
292
+ // Future Rust will provide syntax `type ReturnType = impl AllocValue`:
293
+ // https://github.com/rust-lang/rfcs/pull/2515
294
+ // Until then we use this hack as a workaround.
295
+ #[ allow( dead_code) ] // Function is not used when return type is specified explicitly.
296
+ fn return_type_starlark_type_repr( ) -> starlark:: typing:: Ty {
297
+ fn get_impl<' v, T : starlark:: values:: AllocValue <' v>, E >(
298
+ _f: fn (
299
+ #( #param_types, ) *
300
+ ) -> std:: result:: Result <T , E >,
301
+ ) -> starlark:: typing:: Ty {
302
+ <T as starlark:: values:: type_repr:: StarlarkTypeRepr >:: starlark_type_repr( )
298
303
}
304
+ get_impl( Self :: invoke_impl)
299
305
}
306
+ }
307
+ } ;
300
308
301
- impl #trait_name for #struct_name {
302
- # [ allow ( non_snake_case ) ] // Starlark doesn't have this convention
303
- fn invoke< ' v> (
304
- & self ,
305
- eval : & mut starlark :: eval :: Evaluator < ' v , ' _ , ' _> ,
306
- # ( #this_outer_param , ) *
307
- parameters : & starlark :: eval :: Arguments < ' v , ' _> ,
308
- ) -> starlark:: Result <starlark :: values :: Value <' v>> {
309
- #this_prepare
310
- #prepare
311
- match Self :: invoke_impl ( #this_arg # ( #binding_args , ) * #eval_arg #heap_arg ) {
312
- Ok ( v ) => Ok ( eval . heap ( ) . alloc ( v ) ) ,
313
- // The `.into()` is an `anyhow -> anyhow` conversion if the return type is `anyhow`
314
- # [ allow ( clippy :: useless_conversion ) ]
315
- Err ( e ) => Err ( e . into ( ) ) ,
316
- }
309
+ let impl_trait : syn :: ItemImpl = syn :: parse_quote! {
310
+ impl #trait_name for #struct_name {
311
+ # [ allow ( non_snake_case ) ] // Starlark doesn't have this convention
312
+ fn invoke< ' v> (
313
+ & self ,
314
+ eval : & mut starlark :: eval :: Evaluator < ' v , ' _ , ' _> ,
315
+ # ( #this_outer_param , ) *
316
+ parameters : & starlark:: eval :: Arguments <' v, ' _> ,
317
+ ) -> starlark :: Result <starlark :: values :: Value < ' v>> {
318
+ #this_prepare
319
+ #prepare
320
+ match Self :: invoke_impl ( # ( #invoke_args , ) * ) {
321
+ Ok ( v ) => Ok ( eval . heap ( ) . alloc ( v ) ) ,
322
+ // The `.into()` is an `anyhow -> anyhow` conversion if the return type is `anyhow`
323
+ # [ allow ( clippy :: useless_conversion ) ]
324
+ Err ( e ) => Err ( e . into ( ) ) ,
317
325
}
318
326
}
327
+ }
328
+ } ;
319
329
330
+ Ok ( syn:: parse_quote! {
331
+ {
332
+ #struct_def
333
+ #impl_struct
334
+ #impl_trait
320
335
#builder_set
321
336
}
322
337
} )
@@ -520,15 +535,15 @@ fn render_signature(x: &StarFun) -> syn::Result<syn::Expr> {
520
535
}
521
536
}
522
537
523
- fn render_none ( ) -> syn:: Expr {
538
+ pub ( crate ) fn render_none ( ) -> syn:: Expr {
524
539
syn:: parse_quote! { std:: option:: Option :: None }
525
540
}
526
541
527
- fn render_some ( expr : syn:: Expr ) -> syn:: Expr {
542
+ pub ( crate ) fn render_some ( expr : syn:: Expr ) -> syn:: Expr {
528
543
syn:: parse_quote! { std:: option:: Option :: Some ( #expr) }
529
544
}
530
545
531
- fn render_option ( expr : Option < syn:: Expr > ) -> syn:: Expr {
546
+ pub ( crate ) fn render_option ( expr : Option < syn:: Expr > ) -> syn:: Expr {
532
547
match expr {
533
548
Some ( x) => render_some ( x) ,
534
549
None => render_none ( ) ,
0 commit comments