refactor(joinir): Extract legacy binding path to routing_legacy_binding.rs
Phase 179-A Step 2: Separate LoopFrontendBinding JSON construction logic into dedicated module for better organization. Changes: - New file: routing_legacy_binding.rs (223 lines) - routing.rs: cf_loop_joinir_impl() simplified to 15 lines (delegates to legacy path) - Routing now clearly separates pattern-based vs. legacy binding paths Benefits: - Clear separation of concerns (pattern router vs. legacy whitelist) - routing.rs reduced from 364 to 146 lines (60% reduction) - Legacy path isolated for future deprecation
This commit is contained in:
@ -102,6 +102,7 @@ impl CommonPatternInitializer {
|
||||
carriers.push(CarrierVar {
|
||||
name: var_name.clone(),
|
||||
host_id: var_id,
|
||||
join_id: None, // Phase 177-STRUCT-1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,6 +205,7 @@ mod tests {
|
||||
vec![CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
}],
|
||||
);
|
||||
|
||||
@ -243,10 +244,12 @@ mod tests {
|
||||
CarrierVar {
|
||||
name: "printed".to_string(),
|
||||
host_id: ValueId(11),
|
||||
join_id: None,
|
||||
},
|
||||
CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
},
|
||||
],
|
||||
);
|
||||
@ -288,6 +291,7 @@ mod tests {
|
||||
vec![CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
}],
|
||||
);
|
||||
|
||||
@ -315,6 +319,7 @@ mod tests {
|
||||
vec![CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
}],
|
||||
);
|
||||
|
||||
@ -342,6 +347,7 @@ mod tests {
|
||||
vec![CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
}],
|
||||
);
|
||||
|
||||
@ -372,6 +378,7 @@ mod tests {
|
||||
vec![CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(10),
|
||||
join_id: None,
|
||||
}],
|
||||
);
|
||||
|
||||
|
||||
@ -10,12 +10,58 @@ use super::trim_pattern_lowerer::TrimPatternLowerer;
|
||||
/// Phase 194: Detection function for Pattern 2
|
||||
///
|
||||
/// Phase 192: Updated to structure-based detection
|
||||
/// Phase 178: Added string carrier rejection (unsupported by Pattern 2)
|
||||
/// Phase 187-2: No legacy fallback - rejection means error
|
||||
///
|
||||
/// Pattern 2 matches:
|
||||
/// - Pattern kind is Pattern2Break (has break, no continue)
|
||||
/// - No string/complex carrier updates (JoinIR doesn't support string concat)
|
||||
pub fn can_lower(_builder: &MirBuilder, ctx: &super::router::LoopPatternContext) -> bool {
|
||||
use crate::mir::loop_pattern_detection::LoopPatternKind;
|
||||
ctx.pattern_kind == LoopPatternKind::Pattern2Break
|
||||
use crate::mir::join_ir::lowering::loop_update_analyzer::{LoopUpdateAnalyzer, UpdateExpr, UpdateRhs};
|
||||
use crate::mir::join_ir::lowering::carrier_info::CarrierVar;
|
||||
use crate::mir::ValueId;
|
||||
|
||||
// Basic pattern check
|
||||
if ctx.pattern_kind != LoopPatternKind::Pattern2Break {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Phase 178: Check for string/complex carrier updates
|
||||
// Create dummy carriers from body assignment targets for analysis
|
||||
let dummy_carriers: Vec<CarrierVar> = ctx.body.iter().filter_map(|node| {
|
||||
match node {
|
||||
crate::ast::ASTNode::Assignment { target, .. } => {
|
||||
if let crate::ast::ASTNode::Variable { name, .. } = target.as_ref() {
|
||||
Some(CarrierVar {
|
||||
name: name.clone(),
|
||||
host_id: ValueId(0), // Dummy
|
||||
join_id: None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(ctx.body, &dummy_carriers);
|
||||
|
||||
// Check if any update is string/complex
|
||||
for update in updates.values() {
|
||||
if let UpdateExpr::BinOp { rhs, .. } = update {
|
||||
match rhs {
|
||||
UpdateRhs::StringLiteral(_) | UpdateRhs::Other => {
|
||||
eprintln!("[pattern2/can_lower] Phase 178: String/complex update detected, rejecting Pattern 2 (unsupported)");
|
||||
return false;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Phase 194: Lowering function for Pattern 2
|
||||
|
||||
@ -271,14 +271,17 @@ mod tests {
|
||||
CarrierVar {
|
||||
name: "i".to_string(),
|
||||
host_id: ValueId(1),
|
||||
join_id: None,
|
||||
},
|
||||
CarrierVar {
|
||||
name: "sum".to_string(),
|
||||
host_id: ValueId(2),
|
||||
join_id: None,
|
||||
},
|
||||
CarrierVar {
|
||||
name: "M".to_string(),
|
||||
host_id: ValueId(3),
|
||||
join_id: None,
|
||||
},
|
||||
],
|
||||
trim_helper: None,
|
||||
|
||||
@ -39,6 +39,8 @@ use super::super::trace;
|
||||
/// Phase 194+: Detection function for Pattern 4
|
||||
///
|
||||
/// Phase 192: Updated to use pattern_kind for consistency
|
||||
/// Phase 178: Added string carrier rejection (unsupported by Pattern 4)
|
||||
/// Phase 187-2: No legacy fallback - rejection means error
|
||||
///
|
||||
/// Pattern 4 matches loops with continue statements.
|
||||
///
|
||||
@ -54,12 +56,55 @@ use super::super::trace;
|
||||
///
|
||||
/// 1. **Must have continue**: `ctx.has_continue == true`
|
||||
/// 2. **No break statements**: `ctx.has_break == false` (for simplicity in Pattern 4)
|
||||
/// 3. **Phase 178**: No string/complex carrier updates (JoinIR doesn't support string concat)
|
||||
///
|
||||
/// If both conditions are met, Pattern 4 is detected.
|
||||
/// If all conditions are met, Pattern 4 is detected.
|
||||
pub fn can_lower(_builder: &MirBuilder, ctx: &super::router::LoopPatternContext) -> bool {
|
||||
// Phase 192: Use pattern_kind for consistency with other patterns
|
||||
use crate::mir::loop_pattern_detection::LoopPatternKind;
|
||||
ctx.pattern_kind == LoopPatternKind::Pattern4Continue
|
||||
use crate::mir::join_ir::lowering::loop_update_analyzer::{LoopUpdateAnalyzer, UpdateExpr, UpdateRhs};
|
||||
use crate::mir::join_ir::lowering::carrier_info::CarrierVar;
|
||||
use crate::mir::ValueId;
|
||||
|
||||
// Basic pattern check
|
||||
if ctx.pattern_kind != LoopPatternKind::Pattern4Continue {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Phase 178: Check for string/complex carrier updates
|
||||
// Create dummy carriers from body assignment targets for analysis
|
||||
let dummy_carriers: Vec<CarrierVar> = ctx.body.iter().filter_map(|node| {
|
||||
match node {
|
||||
crate::ast::ASTNode::Assignment { target, .. } => {
|
||||
if let crate::ast::ASTNode::Variable { name, .. } = target.as_ref() {
|
||||
Some(CarrierVar {
|
||||
name: name.clone(),
|
||||
host_id: ValueId(0), // Dummy
|
||||
join_id: None,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let updates = LoopUpdateAnalyzer::analyze_carrier_updates(ctx.body, &dummy_carriers);
|
||||
|
||||
// Check if any update is string/complex
|
||||
for update in updates.values() {
|
||||
if let UpdateExpr::BinOp { rhs, .. } = update {
|
||||
match rhs {
|
||||
UpdateRhs::StringLiteral(_) | UpdateRhs::Other => {
|
||||
eprintln!("[pattern4/can_lower] Phase 178: String/complex update detected, rejecting Pattern 4 (unsupported)");
|
||||
return false;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Phase 33-19: Lowering function for Pattern 4
|
||||
|
||||
@ -184,9 +184,10 @@ pub fn route_loop_pattern(
|
||||
}
|
||||
}
|
||||
|
||||
// No pattern matched - fall through to legacy path
|
||||
// No pattern matched - return None (caller will handle error)
|
||||
// Phase 187-2: Legacy LoopBuilder removed, all loops must use JoinIR
|
||||
if ctx.debug {
|
||||
trace::trace().debug("route", &format!("No pattern matched for function '{}', falling back to legacy", ctx.func_name));
|
||||
trace::trace().debug("route", &format!("No pattern matched for function '{}'", ctx.func_name));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user