namespace Compiler; public sealed class Diagnostic(DiagnosticSeverity severity, string message, string? help, FileInfo? file) { public static DiagnosticBuilder Info(string message) => new DiagnosticBuilder(DiagnosticSeverity.Info, message); public static DiagnosticBuilder Warning(string message) => new DiagnosticBuilder(DiagnosticSeverity.Warning, message); public static DiagnosticBuilder Error(string message) => new DiagnosticBuilder(DiagnosticSeverity.Error, message); public readonly DiagnosticSeverity Severity = severity; public readonly string Message = message; public readonly string? Help = help; public readonly FileInfo? File = file; } public sealed class DiagnosticBuilder(DiagnosticSeverity severity, string message) { private FileInfo? file; private string? help; public DiagnosticBuilder At(string fileName, int line, int column, int length) { file = new FileInfo(fileName, line, column, length); return this; } public DiagnosticBuilder At(string fileName, Token? token) { if (token != null) { At(fileName, token.Line, token.Column, token.Length); } return this; } public DiagnosticBuilder At(string fileName, Node? node) { if (node != null && node.Tokens.Count != 0) { // todo(nub31): Calculate length based on last token At(fileName, node.Tokens[0]); } return this; } public DiagnosticBuilder WithHelp(string helpMessage) { help = helpMessage; return this; } public Diagnostic Build() { return new Diagnostic(severity, message, help, file); } } public sealed class FileInfo(string file, int line, int column, int length) { public readonly string File = file; public readonly int Line = line; public readonly int Column = column; public readonly int Length = length; } public enum DiagnosticSeverity { Info, Warning, Error, } public sealed class CompileException(Diagnostic diagnostic) : Exception { public readonly Diagnostic Diagnostic = diagnostic; }