"""诊断系统 — 收集编译过程中的警告和错误 替代原先静默回退的模式: - return 'i32' → 记录 Warning + 回退到 'i32' - return [] → 记录 Error + 回退到 [] 使用方式: diag = DiagnosticCollector() diag.warn(file, lineno, "无法解析类型,回退到 i32") diag.error(file, lineno, f"加载模块失败: {path}") diag.report() # 打印所有诊断信息 """ from __future__ import annotations import os from dataclasses import dataclass, field from enum import Enum from typing import List, Optional class DiagnosticLevel(Enum): WARNING = "WARNING" ERROR = "ERROR" @dataclass class Diagnostic: level: DiagnosticLevel file: str lineno: int message: str def __str__(self): short_file = os.path.basename(self.file) if self.file else "" return f"[{self.level.value}] {short_file}:{self.lineno} — {self.message}" class DiagnosticCollector: """诊断信息收集器""" def __init__(self): self._diagnostics: List[Diagnostic] = [] def warn(self, file: str, lineno: int, message: str): self._diagnostics.append(Diagnostic(DiagnosticLevel.WARNING, file, lineno, message)) def error(self, file: str, lineno: int, message: str): self._diagnostics.append(Diagnostic(DiagnosticLevel.ERROR, file, lineno, message)) @property def warnings(self) -> List[Diagnostic]: return [d for d in self._diagnostics if d.level == DiagnosticLevel.WARNING] @property def errors(self) -> List[Diagnostic]: return [d for d in self._diagnostics if d.level == DiagnosticLevel.ERROR] @property def has_errors(self) -> bool: return any(d.level == DiagnosticLevel.ERROR for d in self._diagnostics) @property def has_warnings(self) -> bool: return any(d.level == DiagnosticLevel.WARNING for d in self._diagnostics) def report(self, min_level: DiagnosticLevel = DiagnosticLevel.WARNING): """打印所有诊断信息""" for d in self._diagnostics: if d.level.value >= min_level.value: print(d) def clear(self): self._diagnostics.clear() def __len__(self): return len(self._diagnostics) def __bool__(self): return len(self._diagnostics) > 0