use super::braces::{find_matching_brace, find_overflow_block_end};
use super::model::OverflowCollapse;
use super::parse::parse_let_assignment;
use super::scan::next_code_line;
const OVERFLOW_BOUNDS: &[&str] = &[
"-2147483648",
"0",
"-9223372036854775808",
"2147483647",
"4294967295",
"9223372036854775807",
"18446744073709551615",
];
pub(super) fn try_match_overflow(statements: &[String], idx: usize) -> Option<OverflowCollapse> {
let line0 = statements[idx].trim();
if line0.is_empty() || line0.starts_with("//") {
return None;
}
let (result_var, expr) = parse_let_assignment(line0)?;
let dup_idx = next_code_line(statements, idx + 1)?;
let line1 = statements[dup_idx].trim();
let (dup_var, dup_rhs) = parse_let_assignment(line1)?;
if dup_rhs != result_var {
return None;
}
let bound_idx = next_code_line(statements, dup_idx + 1)?;
let line2 = statements[bound_idx].trim();
let (_bound_var, bound_val) = parse_let_assignment(line2)?;
if !OVERFLOW_BOUNDS.contains(&bound_val.as_str()) {
return None;
}
let if_idx = next_code_line(statements, bound_idx + 1)?;
let line3 = statements[if_idx].trim();
if !line3.starts_with("if ") || !line3.ends_with('{') {
return None;
}
if !line3.contains(&format!("{dup_var} <"))
&& !line3.contains(&format!("{dup_var} =="))
&& !line3.contains(&format!("{dup_var} >"))
{
return None;
}
let if_block_end = find_matching_brace(statements, if_idx)?;
let first_body = ((if_idx + 1)..statements.len())
.find(|&i| {
let t = statements[i].trim();
!t.is_empty() && !t.starts_with("//")
})
.map(|i| statements[i].trim().to_string());
let is_checked = first_body
.as_deref()
.is_some_and(|s| s.starts_with("throw("));
let (blank_end, else_unwrap) = if is_checked {
let unwrap = next_code_line(statements, if_block_end + 1).and_then(|next| {
let trimmed = statements[next].trim();
if trimmed == "else {" || trimmed == "} else {" {
let else_end = find_matching_brace(statements, next)?;
Some((next, else_end))
} else {
None
}
});
(if_block_end, unwrap)
} else {
(find_overflow_block_end(statements, if_idx)?, None)
};
Some(OverflowCollapse {
op_line: idx,
expr,
result_var,
blank_start: idx + 1,
blank_end,
is_checked,
else_unwrap,
})
}