zig/lib/compiler/util.zig

82 lines
2.7 KiB
Zig

//! Utilities shared between compiler sub-commands
const std = @import("std");
const aro = @import("aro");
const ErrorBundle = std.zig.ErrorBundle;
pub fn aroDiagnosticsToErrorBundle(
d: *const aro.Diagnostics,
gpa: std.mem.Allocator,
fail_msg: ?[]const u8,
) !ErrorBundle {
@branchHint(.cold);
var bundle: ErrorBundle.Wip = undefined;
try bundle.init(gpa);
errdefer bundle.deinit();
if (fail_msg) |msg| {
try bundle.addRootErrorMessage(.{
.msg = try bundle.addString(msg),
});
}
var cur_err: ?ErrorBundle.ErrorMessage = null;
var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty;
defer cur_notes.deinit(gpa);
for (d.output.to_list.messages.items) |msg| {
switch (msg.kind) {
.off, .warning => {
if (cur_err) |err| {
try bundle.addRootErrorMessageWithNotes(err, cur_notes.items);
// Clear the current error so that notes don't bleed into unassociated errors
cur_err = null;
}
continue;
},
.note => if (cur_err == null) continue,
.@"fatal error", .@"error" => {},
}
const src_loc = 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;
};
switch (msg.kind) {
.@"fatal error", .@"error" => {
if (cur_err) |err| {
try bundle.addRootErrorMessageWithNotes(err, cur_notes.items);
}
cur_err = .{
.msg = try bundle.addString(msg.text),
.src_loc = src_loc,
};
cur_notes.clearRetainingCapacity();
},
.note => {
cur_err.?.notes_len += 1;
try cur_notes.append(gpa, .{
.msg = try bundle.addString(msg.text),
.src_loc = src_loc,
});
},
.off, .warning => unreachable,
}
}
if (cur_err) |err| {
try bundle.addRootErrorMessageWithNotes(err, cur_notes.items);
}
return try bundle.toOwnedBundle("");
}