renderErrorMessageToWriter
Function parameters
Parameters
- w:*Writer
- kind:[]const u8
- color:std.io.tty.Color
- indent:usize
Type definitions in this namespace
Types
- ErrorMessageList
- There will be a MessageIndex for each len at start.
- SourceLocation
- Trailing:
- ErrorMessage
- Trailing:
Functions in this namespace
Functions
- nullTerminatedString
- Given an index into `string_bytes` returns the null-terminated string found there.
Special encoding when there are no errors.
Values
- empty
- Special encoding when there are no errors.
Source
Implementation
fn renderErrorMessageToWriter(
eb: ErrorBundle,
options: RenderOptions,
err_msg_index: MessageIndex,
w: *Writer,
kind: []const u8,
color: std.io.tty.Color,
indent: usize,
) (Writer.Error || std.posix.UnexpectedError)!void {
const ttyconf = options.ttyconf;
const err_msg = eb.getErrorMessage(err_msg_index);
if (err_msg.src_loc != .none) {
const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));
var prefix: std.io.Writer.Discarding = .init(&.{});
try w.splatByteAll(' ', indent);
prefix.count += indent;
try ttyconf.setColor(w, .bold);
try w.print("{s}:{d}:{d}: ", .{
eb.nullTerminatedString(src.data.src_path),
src.data.line + 1,
src.data.column + 1,
});
try prefix.writer.print("{s}:{d}:{d}: ", .{
eb.nullTerminatedString(src.data.src_path),
src.data.line + 1,
src.data.column + 1,
});
try ttyconf.setColor(w, color);
try w.writeAll(kind);
prefix.count += kind.len;
try w.writeAll(": ");
prefix.count += 2;
// This is the length of the part before the error message:
// e.g. "file.zig:4:5: error: "
const prefix_len: usize = @intCast(prefix.count);
try ttyconf.setColor(w, .reset);
try ttyconf.setColor(w, .bold);
if (err_msg.count == 1) {
try writeMsg(eb, err_msg, w, prefix_len);
try w.writeByte('\n');
} else {
try writeMsg(eb, err_msg, w, prefix_len);
try ttyconf.setColor(w, .dim);
try w.print(" ({d} times)\n", .{err_msg.count});
}
try ttyconf.setColor(w, .reset);
if (src.data.source_line != 0 and options.include_source_line) {
const line = eb.nullTerminatedString(src.data.source_line);
for (line) |b| switch (b) {
'\t' => try w.writeByte(' '),
else => try w.writeByte(b),
};
try w.writeByte('\n');
// TODO basic unicode code point monospace width
const before_caret = src.data.span_main - src.data.span_start;
// -1 since span.main includes the caret
const after_caret = src.data.span_end -| src.data.span_main -| 1;
try w.splatByteAll(' ', src.data.column - before_caret);
try ttyconf.setColor(w, .green);
try w.splatByteAll('~', before_caret);
try w.writeByte('^');
try w.splatByteAll('~', after_caret);
try w.writeByte('\n');
try ttyconf.setColor(w, .reset);
}
for (eb.getNotes(err_msg_index)) |note| {
try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent);
}
if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
try ttyconf.setColor(w, .reset);
try ttyconf.setColor(w, .dim);
try w.print("referenced by:\n", .{});
var ref_index = src.end;
for (0..src.data.reference_trace_len) |_| {
const ref_trace = eb.extraData(ReferenceTrace, ref_index);
ref_index = ref_trace.end;
if (ref_trace.data.src_loc != .none) {
const ref_src = eb.getSourceLocation(ref_trace.data.src_loc);
try w.print(" {s}: {s}:{d}:{d}\n", .{
eb.nullTerminatedString(ref_trace.data.decl_name),
eb.nullTerminatedString(ref_src.src_path),
ref_src.line + 1,
ref_src.column + 1,
});
} else if (ref_trace.data.decl_name != 0) {
const count = ref_trace.data.decl_name;
try w.print(
" {d} reference(s) hidden; use '-freference-trace={d}' to see all references\n",
.{ count, count + src.data.reference_trace_len - 1 },
);
} else {
try w.print(
" remaining reference traces hidden; use '-freference-trace' to see all reference traces\n",
.{},
);
}
}
try ttyconf.setColor(w, .reset);
}
} else {
try ttyconf.setColor(w, color);
try w.splatByteAll(' ', indent);
try w.writeAll(kind);
try w.writeAll(": ");
try ttyconf.setColor(w, .reset);
const msg = eb.nullTerminatedString(err_msg.msg);
if (err_msg.count == 1) {
try w.print("{s}\n", .{msg});
} else {
try w.print("{s}", .{msg});
try ttyconf.setColor(w, .dim);
try w.print(" ({d} times)\n", .{err_msg.count});
}
try ttyconf.setColor(w, .reset);
for (eb.getNotes(err_msg_index)) |note| {
try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent + 4);
}
}
}