fn render_documentation()

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,
            }
        };
    )
}