use std::collections::BTreeSet;
use crate::hir::common::{HirExpr, HirStmt};
use super::super::visit::{HirVisitor, visit_expr, visit_stmts};
use super::binding::CarryBinding;
#[derive(Default)]
pub(super) struct BindingReadCollector {
pub(super) reads: BTreeSet<CarryBinding>,
}
impl BindingReadCollector {
pub(super) fn collect_stmts(&mut self, stmts: &[HirStmt]) {
visit_stmts(stmts, self);
}
pub(super) fn collect_expr(&mut self, expr: &HirExpr) {
visit_expr(expr, self);
}
pub(super) fn single_read(&self) -> Option<CarryBinding> {
let mut reads = self.reads.iter();
let read = *reads.next()?;
reads.next().is_none().then_some(read)
}
}
impl HirVisitor for BindingReadCollector {
fn visit_expr(&mut self, expr: &HirExpr) {
let binding = match expr {
HirExpr::LocalRef(local) => Some(CarryBinding::Local(*local)),
HirExpr::TempRef(temp) => Some(CarryBinding::Temp(*temp)),
_ => None,
};
if let Some(binding) = binding {
self.reads.insert(binding);
}
}
}