use brink_syntax::ast::{self, AstNode};
use crate::Provenance;
use crate::provenance::NodeClass;
use crate::{Block, CondBranch, CondKind, Conditional, Stmt};
use super::super::block::lower_branch_body;
use super::super::context::{LowerScope, LowerSink, Lowered};
use super::super::expr::LowerExpr;
use super::LowerConditional;
impl LowerConditional for ast::MultilineConditional {
fn lower_conditional(
&self,
scope: &LowerScope,
sink: &mut impl LowerSink,
) -> Lowered<Conditional> {
Ok(lower_if_else_branches(
self.branches(),
scope.prov(NodeClass::Conditional, self.syntax()),
scope,
sink,
))
}
}
impl LowerConditional for ast::MultilineBranchesCond {
fn lower_conditional(
&self,
scope: &LowerScope,
sink: &mut impl LowerSink,
) -> Lowered<Conditional> {
Ok(lower_if_else_branches(
self.branches(),
scope.prov(NodeClass::Conditional, self.syntax()),
scope,
sink,
))
}
}
fn lower_if_else_branches(
branches: impl Iterator<Item = ast::MultilineBranchCond>,
ptr: Provenance,
scope: &LowerScope,
sink: &mut impl LowerSink,
) -> Conditional {
let branches = branches
.map(|b| {
let condition = if b.is_else() {
None
} else {
b.condition().and_then(|e| e.lower_expr(scope, sink).ok())
};
let branch_ptr = scope.prov(NodeClass::ConditionalBranch, b.syntax());
let mut body = b.body().map_or_else(Block::default, |body| {
lower_branch_body(body.syntax(), scope, sink)
});
body.stmts.insert(0, Stmt::EndOfLine);
CondBranch {
ptr: branch_ptr,
condition,
binding: None,
body,
container_id: None,
}
})
.collect();
Conditional {
ptr,
kind: CondKind::IfElse,
branches,
}
}