from __future__ import annotations
import collections
import re
from pathlib import Path
ANSI_REGEX = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
DIAG_HEADER_RE = re.compile(r"^(warning|error)(?:\[([^\]]+)\])?:\s+(.*)$")
SHORT_DIAG_RE = re.compile(r"^([^:\s]+):(\d+):(\d+):\s+(warning|error)(?:\[([^\]]+)\])?:\s+(.*)$")
LOC_RE = re.compile(r"^\s+-->\s+([^:]+):(\d+):(\d+)")
SUMMARY_RE = re.compile(
r"^(warning|error):\s+.*(generated \d+ warning|could not compile|aborting due to|\d+ warnings? emitted)"
)
MITTS_BANNER_RE = re.compile(r"^\[mitts::.*\]")
def _rel_file(raw_file_str: str, ws_root: Path) -> str:
try:
raw_path = Path(raw_file_str)
if raw_file_str.startswith("/mitts/out/"):
tail = raw_file_str[len("/mitts/out/"):].split("/", 1)
return "OUT_DIR/" + (tail[1] if len(tail) > 1 else tail[0])
rel = raw_file_str
if raw_path.is_absolute():
resolved_ws = ws_root.resolve()
resolved_p = raw_path.resolve()
if str(resolved_p).startswith(str(resolved_ws) + "/"):
rel = str(resolved_p.relative_to(resolved_ws))
parts = rel.split("/")
outs = [i for i, p in enumerate(parts[:-1]) if p == "out"]
if outs:
idx = outs[-1]
if "build" in parts[:idx] or raw_path.is_absolute():
return "OUT_DIR/" + "/".join(parts[idx + 1:])
return rel
except Exception:
return raw_file_str
def extract_diagnostics_counter(stderr_text: str, ws_root: Path) -> collections.Counter:
counter: collections.Counter = collections.Counter()
clean = ANSI_REGEX.sub("", stderr_text)
lines = clean.splitlines()
i = 0
n = len(lines)
while i < n:
line = lines[i].strip()
if not line or MITTS_BANNER_RE.match(line) or SUMMARY_RE.match(line):
i += 1
continue
m_short = SHORT_DIAG_RE.match(line)
if m_short:
rel_f = _rel_file(m_short.group(1).strip(), ws_root)
line_num = int(m_short.group(2))
col_num = int(m_short.group(3))
level = m_short.group(4)
code = (m_short.group(5) or "").strip()
msg = m_short.group(6).strip()
if ": help:" in msg:
msg = msg.split(": help:", 1)[0].strip()
counter[(level, code, rel_f, line_num, col_num, msg)] += 1
i += 1
continue
m_diag = DIAG_HEADER_RE.match(line)
if m_diag:
level = m_diag.group(1)
code = (m_diag.group(2) or "").strip()
msg = m_diag.group(3).strip()
rel_f = ""
line_num = 0
col_num = 0
j = i + 1
while j < n and j < i + 12:
next_line = lines[j].strip()
if DIAG_HEADER_RE.match(next_line):
break
m_loc = LOC_RE.match(lines[j])
if m_loc:
rel_f = _rel_file(m_loc.group(1).strip(), ws_root)
line_num = int(m_loc.group(2))
col_num = int(m_loc.group(3))
break
j += 1
if not rel_f:
i += 1
continue
counter[(level, code, rel_f, line_num, col_num, msg)] += 1
i += 1
return counter
def verify_anomaly_present(stderr_text: str, ws_root: Path, anomaly_info: dict | None) -> bool:
if not anomaly_info:
return False
expected_file = anomaly_info.get("relative_file", "")
expected_line = anomaly_info.get("line")
expected_sym = anomaly_info.get("expected_symbol", "unused_test_var")
counter = extract_diagnostics_counter(stderr_text, ws_root)
for (_lvl, _code, rel_f, line_num, _col, msg) in counter:
if expected_sym in msg and (not expected_file or rel_f.endswith(expected_file)):
if expected_line is None or line_num == expected_line:
return True
return expected_sym in stderr_text
def verify_diagnostics_match(cargo_stderr: str, mitts_stderr: str, ws_root: Path) -> tuple[bool, str]:
cargo_c = extract_diagnostics_counter(cargo_stderr, ws_root)
mitts_c = extract_diagnostics_counter(mitts_stderr, ws_root)
cargo_set, mitts_set = set(cargo_c), set(mitts_c)
cargo_dups = sum(cargo_c.values()) - len(cargo_set)
mitts_dups = sum(mitts_c.values()) - len(mitts_set)
if cargo_set == mitts_set:
extra = f" (repeats: Cargo {cargo_dups}, Mitts {mitts_dups})" if cargo_dups or mitts_dups else ""
return True, f"100% matched {len(cargo_set)} distinct diagnostics exactly{extra}"
msg = (
f"Diagnostics mismatch: Cargo has {len(cargo_set - mitts_set)} extra, "
f"Mitts has {len(mitts_set - cargo_set)} extra "
f"(distinct: Cargo {len(cargo_set)}, Mitts {len(mitts_set)}; "
f"repeats: Cargo {cargo_dups}, Mitts {mitts_dups})"
)
return False, msg
def verify_warning_replay(
initial_stderr: str, cached_stderr: str, ws_root: Path, is_anomaly_wt: bool
) -> tuple[bool, str]:
c_init = extract_diagnostics_counter(initial_stderr, ws_root)
c_cached = extract_diagnostics_counter(cached_stderr, ws_root)
if is_anomaly_wt and sum(c_init.values()) == 0:
return False, "Anomaly worktree failed to produce any diagnostics in initial run"
if c_init == c_cached:
return True, f"Replayed all {sum(c_init.values())} diagnostics exactly"
return (
False,
f"Replay mismatch: initial had {sum(c_init.values())}, cached run had {sum(c_cached.values())}",
)