refactor(joinir): split Pattern2 orchestrator into smaller steps
This commit is contained in:
@ -29,12 +29,26 @@ pub fn classify_p5b_escape_derived(
|
||||
body: &[ASTNode],
|
||||
loop_var_name: &str,
|
||||
) -> P5bEscapeDerivedDecision {
|
||||
let strict = joinir_dev::strict_enabled();
|
||||
let has_ch_init = find_local_init_expr(body, "ch").is_some();
|
||||
let has_ch_reassign = has_assignment_to_var(body, "ch");
|
||||
|
||||
let Some(info) = super::super::ast_feature_extractor::detect_escape_skip_pattern(body) else {
|
||||
if strict && has_ch_init && has_ch_reassign {
|
||||
return P5bEscapeDerivedDecision::Reject(error_tags::freeze(
|
||||
"[phase94/body_local_derived/contract/unhandled_reassign] Body-local reassignment to 'ch' detected but escape shape is not recognized",
|
||||
));
|
||||
}
|
||||
return P5bEscapeDerivedDecision::None;
|
||||
};
|
||||
|
||||
if info.counter_name != loop_var_name {
|
||||
// Not the loop counter we lower as the JoinIR loop var; ignore to avoid misrouting.
|
||||
if strict && has_ch_init && has_ch_reassign {
|
||||
return P5bEscapeDerivedDecision::Reject(error_tags::freeze(
|
||||
"[phase94/body_local_derived/contract/loop_counter_mismatch] Body-local reassignment to 'ch' detected but loop counter does not match Pattern2 loop var",
|
||||
));
|
||||
}
|
||||
return P5bEscapeDerivedDecision::None;
|
||||
}
|
||||
|
||||
@ -55,6 +69,29 @@ pub fn classify_p5b_escape_derived(
|
||||
}
|
||||
}
|
||||
|
||||
fn has_assignment_to_var(body: &[ASTNode], name: &str) -> bool {
|
||||
fn node_has_assignment(node: &ASTNode, name: &str) -> bool {
|
||||
match node {
|
||||
ASTNode::Assignment { target, .. } => is_var_named(target.as_ref(), name),
|
||||
ASTNode::If {
|
||||
then_body,
|
||||
else_body,
|
||||
..
|
||||
} => {
|
||||
then_body.iter().any(|n| node_has_assignment(n, name))
|
||||
|| else_body
|
||||
.as_ref()
|
||||
.map_or(false, |e| e.iter().any(|n| node_has_assignment(n, name)))
|
||||
}
|
||||
ASTNode::Loop { body, .. } => body.iter().any(|n| node_has_assignment(n, name)),
|
||||
ASTNode::ScopeBox { body, .. } => body.iter().any(|n| node_has_assignment(n, name)),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
body.iter().any(|n| node_has_assignment(n, name))
|
||||
}
|
||||
|
||||
fn build_recipe_from_info(
|
||||
body: &[ASTNode],
|
||||
info: &EscapeSkipPatternInfo,
|
||||
|
||||
Reference in New Issue
Block a user