ripex 0.2.0

Multi-language structural parsing and fact extraction.
Documentation
use crate::rust::ast::*;

use super::visitor::Visitor;

pub fn walk_program(visitor: &mut dyn Visitor, program: &Program) {
    for item in &program.items {
        visitor.visit_item(item);
    }
}

pub fn walk_item(visitor: &mut dyn Visitor, item: &Item) {
    match item {
        Item::Fn(f, _) => visitor.visit_fn_decl(f),
        Item::Struct(s, _) => visitor.visit_struct_decl(s),
        Item::Enum(e, _) => visitor.visit_enum_decl(e),
        Item::Trait(t, _) => visitor.visit_trait_decl(t),
        Item::Mod(m, _) => {
            for i in &m.items {
                visitor.visit_item(i);
            }
        }
        Item::Impl(imp, _) => {
            for m in &imp.methods {
                visitor.visit_fn_decl(m);
            }
        }
        _ => {}
    }
}

pub fn walk_block(visitor: &mut dyn Visitor, block: &Block) {
    for s in &block.stmts {
        visitor.visit_stmt(s);
    }
}

pub fn walk_stmt(visitor: &mut dyn Visitor, stmt: &Stmt) {
    match stmt {
        Stmt::Expr(e, _) => visitor.visit_expr(e),
        Stmt::Item(item, _) => visitor.visit_item(item),
        Stmt::Let(l, _) => {
            visitor.visit_pattern(&l.pattern);
            if let Some(ref init) = l.init {
                visitor.visit_expr(init);
            }
        }
        Stmt::Empty(_) => {}
    }
}

pub fn walk_pattern(visitor: &mut dyn Visitor, pat: &Pattern) {
    match pat {
        Pattern::Ident(_, _) | Pattern::Wildcard(_) | Pattern::Lit(_, _) | Pattern::Rest(_) => {}
        Pattern::Tuple(pats, _) => {
            for p in pats {
                visitor.visit_pattern(p);
            }
        }
        Pattern::Struct(_, fields, _) => {
            for f in fields {
                visitor.visit_pattern(&f.pattern);
            }
        }
        Pattern::Range(low, high, _) => {
            visitor.visit_pattern(low);
            visitor.visit_pattern(high);
        }
        Pattern::Or(pats, _) => {
            for p in pats {
                visitor.visit_pattern(p);
            }
        }
        Pattern::Ref(pat, _, _) => visitor.visit_pattern(pat),
        Pattern::Slice(pats, _) => {
            for p in pats {
                visitor.visit_pattern(p);
            }
        }
    }
}

pub fn walk_expr(visitor: &mut dyn Visitor, expr: &Expr) {
    match expr {
        Expr::Binary(left, _, right, _) => {
            visitor.visit_expr(left);
            visitor.visit_expr(right);
        }
        Expr::Unary(_, operand, _) => visitor.visit_expr(operand),
        Expr::Call(callee, args, _) => {
            visitor.visit_expr(callee);
            for a in args {
                visitor.visit_expr(a);
            }
        }
        Expr::MethodCall(obj, _, args, _) => {
            visitor.visit_expr(obj);
            for a in args {
                visitor.visit_expr(a);
            }
        }
        Expr::Index(arr, idx, _) => {
            visitor.visit_expr(arr);
            visitor.visit_expr(idx);
        }
        Expr::Field(obj, _, _) => visitor.visit_expr(obj),
        Expr::Tuple(elems, _) => {
            for e in elems {
                visitor.visit_expr(e);
            }
        }
        Expr::Array(elems, _) => {
            for e in elems {
                visitor.visit_expr(e);
            }
        }
        Expr::Struct(_, fields, base, _) => {
            for f in fields {
                if let Some(ref v) = f.value {
                    visitor.visit_expr(v);
                }
            }
            if let Some(ref b) = base {
                visitor.visit_expr(b);
            }
        }
        Expr::Closure(_, body, _) => visitor.visit_expr(body),
        Expr::Block(b, _) => visitor.visit_block(b),
        Expr::If(cond, body, alt, _) => {
            visitor.visit_expr(cond);
            visitor.visit_block(body);
            if let Some(ref a) = alt {
                visitor.visit_expr(a);
            }
        }
        Expr::Match(expr_, arms, _) => {
            visitor.visit_expr(expr_);
            for a in arms {
                visitor.visit_expr(&a.body);
            }
        }
        Expr::While(cond, body, _) => {
            visitor.visit_expr(cond);
            visitor.visit_block(body);
        }
        Expr::Loop(body, _) => visitor.visit_block(body),
        Expr::For(pat, iter, body, _) => {
            visitor.visit_pattern(pat);
            visitor.visit_expr(iter);
            visitor.visit_block(body);
        }
        Expr::Return(Some(e), _) | Expr::Break(Some(e), _) => visitor.visit_expr(e),
        Expr::Paren(e, _) => visitor.visit_expr(e),
        Expr::Async(e, _) | Expr::Await(e, _) | Expr::Ref(e, _, _) | Expr::Deref(e, _) => {
            visitor.visit_expr(e)
        }
        Expr::Cast(e, _, _) => visitor.visit_expr(e),
        _ => {}
    }
}