Merge pretty printing compile errors branch

This commit is contained in:
Andrew Kelley 2021-04-09 00:20:26 -07:00
commit cc525bc002
4 changed files with 61 additions and 13 deletions

View File

@ -462,7 +462,7 @@ pub const TTY = struct {
// TODO give this a payload of file handle
windows_api,
fn setColor(conf: Config, out_stream: anytype, color: Color) void {
pub fn setColor(conf: Config, out_stream: anytype, color: Color) void {
nosuspend switch (conf) {
.no_color => return,
.escape_codes => switch (color) {

View File

@ -31,21 +31,38 @@ pub fn hashSrc(src: []const u8) SrcHash {
return out;
}
pub fn findLineColumn(source: []const u8, byte_offset: usize) struct { line: usize, column: usize } {
pub const Loc = struct {
line: usize,
column: usize,
/// Does not include the trailing newline.
source_line: []const u8,
};
pub fn findLineColumn(source: []const u8, byte_offset: usize) Loc {
var line: usize = 0;
var column: usize = 0;
for (source[0..byte_offset]) |byte| {
switch (byte) {
var line_start: usize = 0;
var i: usize = 0;
while (i < byte_offset) : (i += 1) {
switch (source[i]) {
'\n' => {
line += 1;
column = 0;
line_start = i + 1;
},
else => {
column += 1;
},
}
}
return .{ .line = line, .column = column };
while (i < source.len and source[i] != '\n') {
i += 1;
}
return .{
.line = line,
.column = column,
.source_line = source[line_start..i],
};
}
pub fn lineDelta(source: []const u8, start: usize, end: usize) isize {

View File

@ -272,28 +272,52 @@ pub const AllErrors = struct {
line: u32,
column: u32,
byte_offset: u32,
/// Does not include the trailing newline.
source_line: ?[]const u8,
notes: []Message = &.{},
},
plain: struct {
msg: []const u8,
},
pub fn renderToStdErr(msg: Message) void {
return msg.renderToStdErrInner("error");
pub fn renderToStdErr(msg: Message, ttyconf: std.debug.TTY.Config) void {
const stderr_mutex = std.debug.getStderrMutex();
const held = std.debug.getStderrMutex().acquire();
defer held.release();
const stderr = std.io.getStdErr();
return msg.renderToStdErrInner(ttyconf, stderr, "error", .Red) catch return;
}
fn renderToStdErrInner(msg: Message, kind: []const u8) void {
fn renderToStdErrInner(
msg: Message,
ttyconf: std.debug.TTY.Config,
stderr_file: std.fs.File,
kind: []const u8,
color: std.debug.TTY.Color,
) anyerror!void {
const stderr = stderr_file.writer();
switch (msg) {
.src => |src| {
std.debug.print("{s}:{d}:{d}: {s}: {s}\n", .{
try stderr.print("{s}:{d}:{d}: ", .{
src.src_path,
src.line + 1,
src.column + 1,
kind,
src.msg,
});
ttyconf.setColor(stderr, color);
try stderr.writeAll(kind);
ttyconf.setColor(stderr, .Bold);
try stderr.print(" {s}\n", .{src.msg});
ttyconf.setColor(stderr, .Reset);
if (src.source_line) |line| {
try stderr.writeAll(line);
try stderr.writeByte('\n');
try stderr.writeByteNTimes(' ', src.column);
ttyconf.setColor(stderr, .Green);
try stderr.writeAll("^\n");
ttyconf.setColor(stderr, .Reset);
}
for (src.notes) |note| {
note.renderToStdErrInner("note");
try note.renderToStdErrInner(ttyconf, stderr_file, "note", .Cyan);
}
},
.plain => |plain| {
@ -327,6 +351,7 @@ pub const AllErrors = struct {
.byte_offset = byte_offset,
.line = @intCast(u32, loc.line),
.column = @intCast(u32, loc.column),
.source_line = try arena.allocator.dupe(u8, loc.source_line),
},
};
}
@ -342,6 +367,7 @@ pub const AllErrors = struct {
.line = @intCast(u32, loc.line),
.column = @intCast(u32, loc.column),
.notes = notes,
.source_line = try arena.allocator.dupe(u8, loc.source_line),
},
});
}
@ -1489,6 +1515,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
.byte_offset = 0,
.line = err_msg.line,
.column = err_msg.column,
.source_line = null, // TODO
},
});
}

View File

@ -2106,8 +2106,12 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi
defer errors.deinit(comp.gpa);
if (errors.list.len != 0) {
const ttyconf: std.debug.TTY.Config = switch (comp.color) {
.auto, .on => std.debug.detectTTYConfig(),
.off => .no_color,
};
for (errors.list) |full_err_msg| {
full_err_msg.renderToStdErr();
full_err_msg.renderToStdErr(ttyconf);
}
const log_text = comp.getCompileLogOutput();
if (log_text.len != 0) {