use brink_syntax::ast::{self, AstNode};
use crate::provenance::NodeClass;
use crate::Stmt;
use super::super::context::{LowerScope, LowerSink};
use super::super::expr::LowerExpr;
use super::sequence::lower_block_sequence;
use super::{LowerConditional, LowerSequence};
pub fn lower_multiline_block(
mb: &ast::MultilineBlock,
scope: &LowerScope,
sink: &mut impl LowerSink,
) -> Option<Stmt> {
let cond_ptr = scope.prov(NodeClass::Conditional, mb.syntax());
let seq_ptr = scope.prov(NodeClass::Sequence, mb.syntax());
if let Some(cond) = mb.conditional()
&& let Ok(mut c) = cond.lower_conditional(scope, sink)
{
c.ptr = cond_ptr;
return Some(Stmt::Conditional(c));
}
if let Some(seq) = mb.sequence()
&& seq.multiline_branches().is_some()
{
let mut s = lower_block_sequence(&seq, scope, sink);
s.ptr = seq_ptr;
return Some(Stmt::Sequence(s));
}
if let Some(branches) = mb.branches_cond()
&& let Ok(mut c) = branches.lower_conditional(scope, sink)
{
c.ptr = cond_ptr;
return Some(Stmt::Conditional(c));
}
None
}
pub fn lower_multiline_block_from_inline(
inline: &ast::InlineLogic,
scope: &LowerScope,
sink: &mut impl LowerSink,
) -> Option<Stmt> {
let cond_ptr = scope.prov(NodeClass::Conditional, inline.syntax());
let seq_ptr = scope.prov(NodeClass::Sequence, inline.syntax());
if let Some(ml_cond) = inline.multiline_conditional()
&& let Ok(mut c) = ml_cond.lower_conditional(scope, sink)
{
c.ptr = cond_ptr;
return Some(Stmt::Conditional(c));
}
if let Some(cond) = inline.conditional()
&& (cond.multiline_branches().is_some() || cond.branchless_body().is_some())
&& let Ok(mut c) = cond.lower_conditional(scope, sink)
{
c.ptr = cond_ptr;
return Some(Stmt::Conditional(c));
}
if let Some(seq) = inline.sequence()
&& seq.multiline_branches().is_some()
{
let mut s = lower_block_sequence(&seq, scope, sink);
s.ptr = seq_ptr;
return Some(Stmt::Sequence(s));
}
None
}
pub fn lower_inline_logic_into_parts(
inline: &ast::InlineLogic,
parts: &mut Vec<crate::ContentPart>,
scope: &LowerScope,
sink: &mut impl LowerSink,
) {
if let Some(inner) = inline.inner_expression()
&& let Some(expr) = inner.expr().and_then(|e| e.lower_expr(scope, sink).ok())
{
parts.push(crate::ContentPart::Interpolation(expr));
return;
}
if let Some(cond) = inline.conditional()
&& let Ok(ic) = cond.lower_conditional(scope, sink)
{
parts.push(crate::ContentPart::InlineConditional(ic));
return;
}
if let Some(seq) = inline.sequence()
&& let Ok(is) = seq.lower_sequence(scope, sink)
{
parts.push(crate::ContentPart::InlineSequence(is));
return;
}
if let Some(imp) = inline.implicit_sequence()
&& let Ok(is) = imp.lower_sequence(scope, sink)
{
parts.push(crate::ContentPart::InlineSequence(is));
}
}