in starlark_derive/src/render.rs [119:234]
fn render_fun(x: StarFun) -> TokenStream {
let span = x.span();
let name_str = ident_string(&x.name);
let signature = render_signature(&x);
let documentation = render_documentation(&x);
let binding = render_binding(&x);
let is_method = x.is_method();
let StarFun {
name,
type_attribute,
attrs,
args: _,
return_type,
return_type_arg: _,
speculative_exec_safe,
body,
source: _,
docstring: _,
} = x;
let typ = match type_attribute {
Some(x) => quote_spanned! {
span=>
std::option::Option::Some({
const TYPE_N: usize = #x.len();
static TYPE: starlark::values::StarlarkStrNRepr<TYPE_N> =
starlark::values::StarlarkStrNRepr::new(#x);
TYPE.unpack()
})
},
None => {
quote_spanned! {
span=>
std::option::Option::None
}
}
};
let signature_arg = signature.as_ref().map(
|_| quote_spanned! {span=> __signature: &starlark::eval::ParametersSpec<starlark::values::FrozenValue>,},
);
let signature_val = signature
.as_ref()
.map(|_| quote_spanned! {span=> __signature});
let signature_val_ref = signature
.as_ref()
.map(|_| quote_spanned! {span=> &__signature});
let (this_param, this_arg, builder_set) = if is_method {
(
quote_spanned! {span=> __this: starlark::values::Value<'v>, },
quote_spanned! {span=> __this, },
quote_spanned! {span=>
#[allow(clippy::redundant_closure)]
globals_builder.set_method(
#name_str,
#speculative_exec_safe,
__documentation_renderer,
#typ,
move |eval, __this, parameters| {#name(eval, __this, parameters, #signature_val_ref)},
);
},
)
} else {
(
quote_spanned! {span=> },
quote_spanned! {span=> },
quote_spanned! {span=>
#[allow(clippy::redundant_closure)]
globals_builder.set_function(
#name_str,
#speculative_exec_safe,
__documentation_renderer,
#typ,
move |eval, parameters| {#name(eval, parameters, #signature_val_ref)},
);
},
)
};
quote_spanned! {
span=>
#( #attrs )*
#[allow(non_snake_case)] // Starlark doesn't have this convention
fn #name<'v>(
eval: &mut starlark::eval::Evaluator<'v, '_>,
#this_param
parameters: &starlark::eval::Arguments<'v, '_>,
#signature_arg
) -> anyhow::Result<starlark::values::Value<'v>> {
fn inner<'v>(
#[allow(unused_variables)]
eval: &mut starlark::eval::Evaluator<'v, '_>,
#this_param
__args: &starlark::eval::Arguments<'v, '_>,
#signature_arg
) -> #return_type {
#[allow(unused_variables)]
let heap = eval.heap();
#binding
#body
}
match inner(eval, #this_arg parameters, #signature_val) {
Ok(v) => Ok(eval.heap().alloc(v)),
Err(e) => Err(e),
}
}
{
#signature
#documentation
#builder_set
}
}
}