use crate::hir::common::{
HirBlock, HirCallExpr, HirDecisionExpr, HirExpr, HirLValue, HirProto, HirStmt,
HirTableConstructor,
};
use super::traverse::{
traverse_hir_call_children, traverse_hir_decision_children, traverse_hir_expr_children,
traverse_hir_lvalue_children, traverse_hir_stmt_children,
traverse_hir_table_constructor_children,
};
pub(super) trait HirVisitor {
fn visit_block(&mut self, _block: &HirBlock) {}
fn visit_stmt(&mut self, _stmt: &HirStmt) {}
fn visit_expr(&mut self, _expr: &HirExpr) {}
fn visit_lvalue(&mut self, _lvalue: &HirLValue) {}
fn visit_call(&mut self, _call: &HirCallExpr) {}
}
pub(super) fn visit_proto(proto: &HirProto, visitor: &mut impl HirVisitor) {
visit_block(&proto.body, visitor);
}
pub(super) fn visit_block(block: &HirBlock, visitor: &mut impl HirVisitor) {
visitor.visit_block(block);
visit_stmts(&block.stmts, visitor);
}
pub(super) fn visit_stmts(stmts: &[HirStmt], visitor: &mut impl HirVisitor) {
for stmt in stmts {
visit_stmt(stmt, visitor);
}
}
fn visit_stmt(stmt: &HirStmt, visitor: &mut impl HirVisitor) {
visitor.visit_stmt(stmt);
traverse_hir_stmt_children!(
stmt,
iter = iter,
opt = as_ref,
borrow = [&],
expr(expr) => {
visit_expr(expr, visitor);
},
lvalue(lvalue) => {
visit_lvalue(lvalue, visitor);
},
block(block) => {
visit_block(block, visitor);
},
call(call) => {
visit_call(call, visitor);
},
condition(cond) => {
visit_expr(cond, visitor);
}
);
}
pub(super) fn visit_call(call: &HirCallExpr, visitor: &mut impl HirVisitor) {
visitor.visit_call(call);
traverse_hir_call_children!(call, iter = iter, borrow = [&], expr(expr) => {
visit_expr(expr, visitor);
});
}
pub(super) fn visit_lvalue(lvalue: &HirLValue, visitor: &mut impl HirVisitor) {
visitor.visit_lvalue(lvalue);
traverse_hir_lvalue_children!(lvalue, borrow = [&], expr(expr) => {
visit_expr(expr, visitor);
});
}
pub(super) fn visit_expr(expr: &HirExpr, visitor: &mut impl HirVisitor) {
visitor.visit_expr(expr);
traverse_hir_expr_children!(
expr,
iter = iter,
borrow = [&],
expr(e) => {
visit_expr(e, visitor);
},
call(c) => {
visit_call(c, visitor);
},
decision(d) => {
visit_decision_expr(d, visitor);
},
table_constructor(t) => {
visit_table_constructor(t, visitor);
}
);
}
fn visit_decision_expr(decision: &HirDecisionExpr, visitor: &mut impl HirVisitor) {
traverse_hir_decision_children!(
decision,
iter = iter,
borrow = [&],
expr(e) => {
visit_expr(e, visitor);
},
condition(cond) => {
visit_expr(cond, visitor);
}
);
}
fn visit_table_constructor(table: &HirTableConstructor, visitor: &mut impl HirVisitor) {
traverse_hir_table_constructor_children!(
table,
iter = iter,
opt = as_ref,
borrow = [&],
expr(e) => {
visit_expr(e, visitor);
}
);
}