From e8e8d7e5c8eee5fe29add5aac0c07bf08a2debad Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Fri, 18 Jul 2025 20:17:39 -0700 Subject: [PATCH] resinator: Update for latest aro --- lib/compiler/resinator/main.zig | 131 ++++++++------------------ lib/compiler/resinator/preprocess.zig | 32 +++---- 2 files changed, 51 insertions(+), 112 deletions(-) diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 1d87f21d2b..4faf3feb02 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -120,7 +120,20 @@ pub fn main() !void { defer aro_arena_state.deinit(); const aro_arena = aro_arena_state.allocator(); - var comp = aro.Compilation.init(aro_arena, std.fs.cwd()); + var stderr_buf: [512]u8 = undefined; + var stderr_writer = stderr.writer(&stderr_buf); + var diagnostics: aro.Diagnostics = switch (zig_integration) { + false => .{ .output = .{ .to_writer = .{ + .writer = &stderr_writer.interface, + .color = stderr_config, + } } }, + true => .{ .output = .{ .to_list = .{ + .arena = .init(allocator), + } } }, + }; + defer diagnostics.deinit(); + + var comp = aro.Compilation.init(aro_arena, aro_arena, &diagnostics, std.fs.cwd()); defer comp.deinit(); var argv: std.ArrayList([]const u8) = .empty; @@ -143,20 +156,24 @@ pub fn main() !void { try stdout.flush(); } - preprocess.preprocess(&comp, &preprocessed_buf.writer, argv.items, maybe_dependencies) catch |err| switch (err) { + preprocess.preprocess(&comp, &preprocessed_buf.writer, argv.items, maybe_dependencies_list) catch |err| switch (err) { error.GeneratedSourceError => { - try error_handler.emitAroDiagnostics(allocator, "failed during preprocessor setup (this is always a bug):", &comp); + try error_handler.emitAroDiagnostics(allocator, "failed during preprocessor setup (this is always a bug)", &comp); std.process.exit(1); }, // ArgError can occur if e.g. the .rc file is not found error.ArgError, error.PreprocessError => { - try error_handler.emitAroDiagnostics(allocator, "failed during preprocessing:", &comp); + try error_handler.emitAroDiagnostics(allocator, "failed during preprocessing", &comp); std.process.exit(1); }, - error.StreamTooLong => { + error.FileTooBig => { try error_handler.emitMessage(allocator, .err, "failed during preprocessing: maximum file size exceeded", .{}); std.process.exit(1); }, + error.WriteFailed => { + try error_handler.emitMessage(allocator, .err, "failed during preprocessing: error writing the preprocessed output", .{}); + std.process.exit(1); + }, error.OutOfMemory => |e| return e, }; @@ -660,11 +677,10 @@ const ErrorHandler = union(enum) { try server.serveErrorBundle(error_bundle); }, .tty => { - // extra newline to separate this line from the aro errors + // aro errors have already been emitted const stderr = std.debug.lockStderrWriter(&.{}); defer std.debug.unlockStderrWriter(); - try renderErrorMessage(stderr, self.tty, .err, "{s}\n", .{fail_msg}); - aro.Diagnostics.render(comp, self.tty); + try renderErrorMessage(stderr, self.tty, .err, "{s}", .{fail_msg}); }, } } @@ -883,12 +899,10 @@ fn aroDiagnosticsToErrorBundle( .msg = try bundle.addString(fail_msg), }); - var msg_writer = MsgWriter.init(gpa); - defer msg_writer.deinit(); var cur_err: ?ErrorBundle.ErrorMessage = null; var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty; defer cur_notes.deinit(gpa); - for (comp.diagnostics.list.items) |msg| { + for (comp.diagnostics.output.to_list.messages.items) |msg| { switch (msg.kind) { // Clear the current error so that notes don't bleed into unassociated errors .off, .warning => { @@ -897,28 +911,19 @@ fn aroDiagnosticsToErrorBundle( }, .note => if (cur_err == null) continue, .@"fatal error", .@"error" => {}, - .default => unreachable, } - msg_writer.resetRetainingCapacity(); - aro.Diagnostics.renderMessage(comp, &msg_writer, msg); const src_loc = src_loc: { - if (msg_writer.path) |src_path| { - var src_loc: ErrorBundle.SourceLocation = .{ - .src_path = try bundle.addString(src_path), - .line = msg_writer.line - 1, // 1-based -> 0-based - .column = msg_writer.col - 1, // 1-based -> 0-based - .span_start = 0, - .span_main = 0, - .span_end = 0, - }; - if (msg_writer.source_line) |source_line| { - src_loc.span_start = msg_writer.span_main; - src_loc.span_main = msg_writer.span_main; - src_loc.span_end = msg_writer.span_main; - src_loc.source_line = try bundle.addString(source_line); - } - break :src_loc try bundle.addSourceLocation(src_loc); + if (msg.location) |location| { + break :src_loc try bundle.addSourceLocation(.{ + .src_path = try bundle.addString(location.path), + .line = location.line_no - 1, // 1-based -> 0-based + .column = location.col - 1, // 1-based -> 0-based + .span_start = location.width, + .span_main = location.width, + .span_end = location.width, + .source_line = try bundle.addString(location.line), + }); } break :src_loc ErrorBundle.SourceLocationIndex.none; }; @@ -929,7 +934,7 @@ fn aroDiagnosticsToErrorBundle( try flushErrorMessageIntoBundle(&bundle, err, cur_notes.items); } cur_err = .{ - .msg = try bundle.addString(msg_writer.buf.items), + .msg = try bundle.addString(msg.text), .src_loc = src_loc, }; cur_notes.clearRetainingCapacity(); @@ -937,11 +942,11 @@ fn aroDiagnosticsToErrorBundle( .note => { cur_err.?.notes_len += 1; try cur_notes.append(gpa, .{ - .msg = try bundle.addString(msg_writer.buf.items), + .msg = try bundle.addString(msg.text), .src_loc = src_loc, }); }, - .off, .warning, .default => unreachable, + .off, .warning => unreachable, } } if (cur_err) |err| { @@ -950,63 +955,3 @@ fn aroDiagnosticsToErrorBundle( return try bundle.toOwnedBundle(""); } - -// Similar to aro.Diagnostics.MsgWriter but: -// - Writers to an ArrayList -// - Only prints the message itself (no location, source line, error: prefix, etc) -// - Keeps track of source path/line/col instead -const MsgWriter = struct { - buf: std.array_list.Managed(u8), - path: ?[]const u8 = null, - // 1-indexed - line: u32 = undefined, - col: u32 = undefined, - source_line: ?[]const u8 = null, - span_main: u32 = undefined, - - fn init(allocator: std.mem.Allocator) MsgWriter { - return .{ - .buf = std.array_list.Managed(u8).init(allocator), - }; - } - - fn deinit(m: *MsgWriter) void { - m.buf.deinit(); - } - - fn resetRetainingCapacity(m: *MsgWriter) void { - m.buf.clearRetainingCapacity(); - m.path = null; - m.source_line = null; - } - - pub fn print(m: *MsgWriter, comptime fmt: []const u8, args: anytype) void { - m.buf.print(fmt, args) catch {}; - } - - pub fn write(m: *MsgWriter, msg: []const u8) void { - m.buf.appendSlice(msg) catch {}; - } - - pub fn setColor(m: *MsgWriter, color: std.Io.tty.Color) void { - _ = m; - _ = color; - } - - pub fn location(m: *MsgWriter, path: []const u8, line: u32, col: u32) void { - m.path = path; - m.line = line; - m.col = col; - } - - pub fn start(m: *MsgWriter, kind: aro.Diagnostics.Kind) void { - _ = m; - _ = kind; - } - - pub fn end(m: *MsgWriter, maybe_line: ?[]const u8, col: u32, end_with_splice: bool) void { - _ = end_with_splice; - m.source_line = maybe_line; - m.span_main = col; - } -}; diff --git a/lib/compiler/resinator/preprocess.zig b/lib/compiler/resinator/preprocess.zig index d14812a05d..2a5dfd9f63 100644 --- a/lib/compiler/resinator/preprocess.zig +++ b/lib/compiler/resinator/preprocess.zig @@ -5,7 +5,7 @@ const cli = @import("cli.zig"); const Dependencies = @import("compile.zig").Dependencies; const aro = @import("aro"); -const PreprocessError = error{ ArgError, GeneratedSourceError, PreprocessError, StreamTooLong, OutOfMemory }; +const PreprocessError = error{ ArgError, GeneratedSourceError, PreprocessError, FileTooBig, OutOfMemory, WriteFailed }; pub fn preprocess( comp: *aro.Compilation, @@ -16,18 +16,18 @@ pub fn preprocess( ) PreprocessError!void { try comp.addDefaultPragmaHandlers(); - var driver: aro.Driver = .{ .comp = comp, .aro_name = "arocc" }; + var driver: aro.Driver = .{ .comp = comp, .diagnostics = comp.diagnostics, .aro_name = "arocc" }; defer driver.deinit(); - var macro_buf: std.Io.Writer.Allocating = .init(comp.gpa); - defer macro_buf.deinit(); + var macro_buf: std.ArrayListUnmanaged(u8) = .empty; + defer macro_buf.deinit(comp.gpa); - var trash: [64]u8 = undefined; - var discarding: std.Io.Writer.Discarding = .init(&trash); - _ = driver.parseArgs(&discarding.writer, ¯o_buf.writer, argv) catch |err| switch (err) { + var discard_buffer: [64]u8 = undefined; + var discarding: std.Io.Writer.Discarding = .init(&discard_buffer); + _ = driver.parseArgs(&discarding.writer, ¯o_buf, argv) catch |err| switch (err) { error.FatalError => return error.ArgError, error.OutOfMemory => |e| return e, - error.WriteFailed => return error.OutOfMemory, + error.WriteFailed => unreachable, }; if (hasAnyErrors(comp)) return error.ArgError; @@ -46,7 +46,10 @@ pub fn preprocess( if (hasAnyErrors(comp)) return error.GeneratedSourceError; comp.generated_buf.items.len = 0; - var pp = try aro.Preprocessor.initDefault(comp); + var pp = aro.Preprocessor.initDefault(comp) catch |err| switch (err) { + error.FatalError => return error.GeneratedSourceError, + error.OutOfMemory => |e| return e, + }; defer pp.deinit(); if (comp.langopts.ms_extensions) { @@ -79,16 +82,7 @@ pub fn preprocess( } fn hasAnyErrors(comp: *aro.Compilation) bool { - // In theory we could just check Diagnostics.errors != 0, but that only - // gets set during rendering of the error messages, see: - // https://github.com/Vexu/arocc/issues/603 - for (comp.diagnostics.list.items) |msg| { - switch (msg.kind) { - .@"fatal error", .@"error" => return true, - else => {}, - } - } - return false; + return comp.diagnostics.errors != 0; } /// `arena` is used for temporary -D argument strings and the INCLUDE environment variable.