in starlark_derive/src/render.rs [369:428]
fn render_documentation(x: &StarFun) -> TokenStream {
let span = x.args_span();
// A signature is not needed to invoke positional-only functions, but we still want
// information like names, order, type, etc to be available to call '.documentation()' on.
let args_count = match &x.source {
StarFunSource::Argument(args_count) => Some(*args_count),
StarFunSource::Positional(required, optional) => Some(required + optional),
StarFunSource::Unknown | StarFunSource::Parameters | StarFunSource::ThisParameters => None,
};
let name_str = ident_string(&x.name);
let documentation_signature = match args_count {
Some(args_count) => {
let sig_args = x.args.map(render_signature_arg);
quote_spanned! {
span=> {
#[allow(unused_mut)]
let mut __signature = starlark::eval::ParametersSpec::with_capacity(#name_str.to_owned(), #args_count);
#( #sig_args )*
__signature
}
}
}
None => {
quote_spanned!(span=> starlark::eval::ParametersSpec::<starlark::values::FrozenValue>::new(#name_str.to_owned()))
}
};
let docs = match x.docstring.as_ref() {
Some(d) => quote_spanned!(span=> Some(#d)),
None => quote_spanned!(span=> None),
};
let return_type_arg = &x.return_type_arg;
let parameter_types: Vec<_> = x.args
.iter()
.filter(|a| !a.is_this()) // "this" gets ignored when creating the signature, so make sure the indexes match up.
.enumerate()
.map(|(i, arg)| {
let typ = &arg.ty;
quote_spanned!(span=> (#i, starlark::values::docs::Type { raw_type: stringify!(#typ).to_owned() }) )
}).collect();
quote_spanned!(span=>
let __documentation_renderer = {
let signature = #documentation_signature;
let parameter_types = std::collections::HashMap::from([#(#parameter_types),*]);
let return_type = Some(
starlark::values::docs::Type {
raw_type: stringify!(#return_type_arg).to_owned()
}
);
starlark::values::function::NativeCallableRawDocs {
rust_docstring: #docs,
signature,
parameter_types,
return_type,
}
};
)
}