obelix 0.2.0

Obélix is a tool to reduce Rust source files to produce MVEs
Documentation
use syn::spanned::Spanned;

#[derive(Default)]
pub struct SimplifyFunctionBodyVisitor {
    done: bool,
    visited: std::collections::BTreeSet<(proc_macro2::LineColumn, proc_macro2::LineColumn)>,
}

impl super::Visiter for SimplifyFunctionBodyVisitor {
    fn reset(&mut self) {
        self.done = false;
    }

    fn visited_count(&self) -> usize {
        self.visited.len()
    }
}

impl syn::fold::Fold for SimplifyFunctionBodyVisitor {
    fn fold_item_fn(&mut self, mut func: syn::ItemFn) -> syn::ItemFn {
        if self.done {
            return func;
        }

        let item = func.span();
        let item = (item.start(), item.end());

        if self.visited.insert(item) {
            func.block = Box::new(if let syn::ReturnType::Default = func.sig.output {
                syn::parse_quote! { { } }
            } else {
                syn::parse_quote! { { loop {} } }
            });

            for input in func.sig.inputs.iter_mut() {
                if let syn::FnArg::Typed(input) = input {
                    *input.pat = syn::parse_quote! { _ };
                }
            }

            self.done = true;
            func
        } else {
            syn::fold::fold_item_fn(self, func)
        }
    }

    fn fold_impl_item_method(&mut self, mut func: syn::ImplItemMethod) -> syn::ImplItemMethod {
        if self.done {
            return func;
        }

        let item = func.span();
        let item = (item.start(), item.end());

        if self.visited.insert(item) {
            func.block = if let syn::ReturnType::Default = func.sig.output {
                syn::parse_quote! { { } }
            } else {
                syn::parse_quote! { { loop {} } }
            };

            for input in func.sig.inputs.iter_mut() {
                if let syn::FnArg::Typed(input) = input {
                    *input.pat = syn::parse_quote! { _ };
                }
            }

            self.done = true;
            func
        } else {
            syn::fold::fold_impl_item_method(self, func)
        }
    }
}