use crate::syntax::cfg::dispatchers::multifile::{get_condition_deterministic_result, CondBranch};
use crate::syntax::cfg::{SyntaxCfgArgs, SyntaxCfgError};
use crate::syntax::{SyntaxGraph, SyntaxNode};
use crate::NodeId;
const fn true_false_ids(node: &SyntaxNode) -> (Option<NodeId>, Option<NodeId>) {
match node {
SyntaxNode::If {
true_id, false_id, ..
} => (*true_id, *false_id),
SyntaxNode::TernaryOperation {
true_id, false_id, ..
} => (Some(*true_id), Some(*false_id)),
_ => (None, None),
}
}
const fn condition_id(node: &SyntaxNode) -> Option<NodeId> {
match node {
SyntaxNode::If { condition_id, .. } | SyntaxNode::TernaryOperation { condition_id, .. } => {
Some(*condition_id)
}
_ => None,
}
}
fn deterministic_branch_id(graph: &mut SyntaxGraph, n_id: NodeId) -> Option<NodeId> {
let node = graph.nodes.get(&n_id)?;
let cond_id = condition_id(node)?;
let (true_id, false_id) = true_false_ids(node);
match get_condition_deterministic_result(graph, cond_id)? {
CondBranch::TrueId => true_id,
CondBranch::FalseId => false_id,
}
}
pub fn build(
args: &mut SyntaxCfgArgs<'_>,
n_id: NodeId,
nxt_id: Option<NodeId>,
) -> Result<NodeId, SyntaxCfgError> {
if args.is_multifile {
if let Some(f_id) = deterministic_branch_id(args.graph, n_id) {
let built = args.generic(f_id, nxt_id)?;
args.graph.add_cfg_edge(n_id, built);
return Ok(n_id);
}
}
let (true_id, false_id) = args
.graph
.nodes
.get(&n_id)
.map_or((None, None), true_false_ids);
if let Some(true_id) = true_id {
let built = args.generic(true_id, nxt_id)?;
args.graph.add_cfg_edge(n_id, built);
}
if let Some(false_id) = false_id {
let built = args.generic(false_id, nxt_id)?;
args.graph.add_cfg_edge(n_id, built);
}
if let Some(nxt_id) = nxt_id {
args.graph.add_cfg_edge(n_id, nxt_id);
}
Ok(n_id)
}