bon_macros/builder/
item_fn.rs

1use super::builder_gen::input_fn::{FnInputCtx, FnInputCtxParams};
2use super::builder_gen::{MacroOutput, TopLevelConfig};
3use crate::normalization::SyntaxVariant;
4use crate::util::prelude::*;
5use syn::visit_mut::VisitMut;
6
7pub(crate) fn generate(
8    config: TopLevelConfig,
9    orig_fn: syn::ItemFn,
10    namespace: &crate::normalization::GenericsNamespace,
11) -> Result<TokenStream> {
12    let mut norm_fn = orig_fn.clone();
13
14    crate::normalization::NormalizeLifetimes::new(namespace).visit_item_fn_mut(&mut norm_fn);
15    crate::normalization::NormalizeImplTraits::new(namespace).visit_item_fn_mut(&mut norm_fn);
16
17    let fn_item = SyntaxVariant {
18        orig: orig_fn,
19        norm: norm_fn,
20    };
21
22    let ctx = FnInputCtx::new(FnInputCtxParams {
23        namespace,
24        fn_item,
25        impl_ctx: None,
26        config,
27    });
28
29    let adapted_fn = ctx.adapted_fn()?;
30
31    let MacroOutput {
32        start_fn,
33        other_items,
34    } = ctx.into_builder_gen_ctx()?.output()?;
35
36    Ok(quote! {
37        // Keep original function at the top. It seems like rust-analyzer
38        // does better job of highlighting syntax when it is here. Assuming
39        // this is because rust-analyzer prefers the first occurrence of the
40        // span when highlighting.
41        //
42        // See this issue for details: https://github.com/rust-lang/rust-analyzer/issues/18438
43        #adapted_fn
44
45        #start_fn
46        #other_items
47    })
48}