spb/air Public MIT
AIR — The Language of Accounting.
Python 100%
1# =============================================================================2# Projet : AIR — Accounting Intermediate Representation3# Auteur : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# Fichier : diagnostics.py6# Description : Clang-style diagnostics — precise location, cause, suggestion.7# =============================================================================8"""Compiler-quality diagnostics for AIC.910Modeled on clang: every diagnostic names WHERE (event id / field path),11WHAT (computed cause, e.g. the exact imbalance), and HOW TO FIX (suggestion).12Errors abort compilation; warnings and notes ride along in the result.13"""14from __future__ import annotations1516import enum17from dataclasses import dataclass181920class Severity(enum.Enum):21 ERROR = "error"22 WARNING = "warning"23 NOTE = "note"242526@dataclass(frozen=True, slots=True)27class Diagnostic:28 code: str # e.g. "AIR-E101"29 severity: Severity30 message: str31 location: str # e.g. "event evt_01H..., field items[0].unit_price"32 suggestion: str | None = None33 origin_pass: str | None = None3435 def render(self) -> str:36 head = f"{self.severity.value}[{self.code}]: {self.message}"37 lines = [head, f" --> {self.location}"]38 if self.origin_pass:39 lines.append(f" pass: {self.origin_pass}")40 if self.suggestion:41 lines.append(f" help: {self.suggestion}")42 return "\n".join(lines)434445class CompilationError(Exception):46 """Raised when any ERROR diagnostic is produced; carries all diagnostics."""4748 def __init__(self, diagnostics: list[Diagnostic]):49 self.diagnostics = diagnostics50 errors = [d for d in diagnostics if d.severity is Severity.ERROR]51 super().__init__(52 f"{len(errors)} error(s):\n" + "\n".join(d.render() for d in errors)53 )54