feature. See also
. The project being documented here (as the example) is the Zig library itself.
main.diagnosticsToErrorBundle
fn diagnosticsToErrorBundle(
gpa: Allocator,
source: []const u8,
diagnostics: *Diagnostics,
mappings: SourceMappings,
) !ErrorBundle
File
Code
fn diagnosticsToErrorBundle(
gpa: Allocator,
source: []const u8,
diagnostics: *Diagnostics,
mappings: SourceMappings,
) !ErrorBundle {
@branchHint(.cold);
var bundle: ErrorBundle.Wip = undefined;
try bundle.init(gpa);
errdefer bundle.deinit();
var msg_buf: std.Io.Writer.Allocating = .init(gpa);
defer msg_buf.deinit();
var cur_err: ?ErrorBundle.ErrorMessage = null;
var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty;
defer cur_notes.deinit(gpa);
for (diagnostics.errors.items) |err_details| {
switch (err_details.type) {
.hint => continue,
.warning => {
cur_err = null;
continue;
},
.note => if (cur_err == null) continue,
.err => {},
}
const corresponding_span = mappings.getCorrespondingSpan(err_details.token.line_number).?;
const err_line = corresponding_span.start_line;
const err_filename = mappings.files.get(corresponding_span.filename_offset);
const source_line_start = err_details.token.getLineStartForErrorDisplay(source);
// and add one to get a 1-based column
const column = err_details.token.calculateColumn(source, 1, source_line_start) + 1;
msg_buf.clearRetainingCapacity();
try err_details.render(&msg_buf.writer, source, diagnostics.strings.items);
const src_loc = src_loc: {
var src_loc: ErrorBundle.SourceLocation = .{
.src_path = try bundle.addString(err_filename),
.line = @intCast(err_line - 1),
.column = @intCast(column - 1),
.span_start = 0,
.span_main = 0,
.span_end = 0,
};
if (err_details.print_source_line) {
const source_line = err_details.token.getLineForErrorDisplay(source, source_line_start);
const visual_info = err_details.visualTokenInfo(source_line_start, source_line_start + source_line.len, source);
src_loc.span_start = @intCast(visual_info.point_offset - visual_info.before_len);
src_loc.span_main = @intCast(visual_info.point_offset);
src_loc.span_end = @intCast(visual_info.point_offset + 1 + visual_info.after_len);
src_loc.source_line = try bundle.addString(source_line);
}
break :src_loc try bundle.addSourceLocation(src_loc);
};
switch (err_details.type) {
.err => {
if (cur_err) |err| {
try bundle.addRootErrorMessageWithNotes(err, cur_notes.items);
}
cur_err = .{
.msg = try bundle.addString(msg_buf.written()),
.src_loc = src_loc,
};
cur_notes.clearRetainingCapacity();
},
.note => {
cur_err.?.notes_len += 1;
try cur_notes.append(gpa, .{
.msg = try bundle.addString(msg_buf.written()),
.src_loc = src_loc,
});
},
.warning, .hint => unreachable,
}
}
if (cur_err) |err| {
try bundle.addRootErrorMessageWithNotes(err, cur_notes.items);
}
return try bundle.toOwnedBundle("");
}