resinator: Update for latest aro

This commit is contained in:
Ryan Liptak 2025-07-18 20:17:39 -07:00 committed by Andrew Kelley
parent 01d993b230
commit e8e8d7e5c8
2 changed files with 51 additions and 112 deletions

View File

@ -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;
}
};

View File

@ -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, &macro_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, &macro_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.