use syn::spanned::Spanned;
#[derive(Default)]
pub struct RemoveReturnValueVisitor {
done: bool,
visited: std::collections::BTreeSet<(proc_macro2::LineColumn, proc_macro2::LineColumn)>,
}
impl super::Visiter for RemoveReturnValueVisitor {
fn reset(&mut self) {
self.done = false;
}
fn visited_count(&self) -> usize {
self.visited.len()
}
}
impl syn::fold::Fold for RemoveReturnValueVisitor {
fn fold_expr(&mut self, expr: syn::Expr) -> syn::Expr {
if self.done {
return expr;
}
let span = expr.span();
let span = (span.start(), span.end());
if self.visited.insert(span) {
if let syn::Expr::Return(mut ret) = expr {
ret.expr = Some(syn::parse_quote! { loop { } });
self.done = true;
return syn::Expr::Return(ret);
}
}
syn::fold::fold_expr(self, expr)
}
fn fold_block(&mut self, mut block: syn::Block) -> syn::Block {
if self.done {
return block;
}
let span = block.span();
let span = (span.start(), span.end());
if self.visited.insert(span) {
if let Some(syn::Stmt::Expr(expr)) = block.stmts.last_mut() {
*expr = syn::parse_quote! { loop { } };
self.done = true;
return block;
}
}
syn::fold::fold_block(self, block)
}
}