use crate::utils::syn_error; use syn::{spanned::*, visit_mut::*, *}; pub fn transform(expr: &mut Expr) -> Result<()> { let mut visitor = Visitor::new(); visitor.visit_expr_mut(expr); visitor.result } pub fn transform_chunk(block: &mut Block) -> Result<()> { let mut visitor = Visitor::new(); visitor.visit_block_mut(block); visitor.result } #[derive(Debug)] struct Visitor { result: Result<()>, } impl Visitor { fn new() -> Self { Self { result: Ok(()) } } } impl VisitMut for Visitor { fn visit_expr_unary_mut(&mut self, un: &mut ExprUnary) { match self.transform_unary(un) { res @ Err(_) => self.result = res, _ => visit_expr_unary_mut(self, un), } } fn visit_expr_match_mut(&mut self, mat: &mut ExprMatch) { match self.transform_match(mat) { res @ Err(_) => self.result = res, _ => visit_expr_match_mut(self, mat), } } } impl Visitor { fn transform_unary(&mut self, un: &mut ExprUnary) -> Result<()> { // // separates a nested negation unary operator with parentheses, because the double hyphen // `--` indicates a comment in lua. // // before: // --a // after: // -(-a) // if let UnOp::Neg(_) = un.op && let Expr::Unary(ref inner) = *un.expr && let UnOp::Neg(_) = inner.op { un.expr = Box::new(parse_quote_spanned!(inner.span() => (#inner))); } Ok(()) } fn transform_match(&mut self, mat: &mut ExprMatch) -> Result<()> { // TODO: syn_error!(mat, "match-to-if transformation not yet implemented"); } }