authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-09 00:20:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-09 00:20:26-07:00
logcc525bc002e456cc735f66bc4d2c5267a10b6016
tree473870b356590dc0631e9a809403e180190d23e1
parentc28d1fe1733eb150f956b1eb0d01d79496e7378c
parent9a2de796bd0eb047ca9bd23940004f3b25ab6625

Merge pretty printing compile errors branch


4 files changed, 61 insertions(+), 13 deletions(-)

lib/std/debug.zig+1-1
...@@ -462,7 +462,7 @@ pub const TTY = struct {...@@ -462,7 +462,7 @@ pub const TTY = struct {
462 // TODO give this a payload of file handle462 // TODO give this a payload of file handle
463 windows_api,463 windows_api,
464464
465 fn setColor(conf: Config, out_stream: anytype, color: Color) void {465 pub fn setColor(conf: Config, out_stream: anytype, color: Color) void {
466 nosuspend switch (conf) {466 nosuspend switch (conf) {
467 .no_color => return,467 .no_color => return,
468 .escape_codes => switch (color) {468 .escape_codes => switch (color) {
lib/std/zig.zig+21-4
...@@ -31,21 +31,38 @@ pub fn hashSrc(src: []const u8) SrcHash {...@@ -31,21 +31,38 @@ pub fn hashSrc(src: []const u8) SrcHash {
31 return out;31 return out;
32}32}
3333
34pub fn findLineColumn(source: []const u8, byte_offset: usize) struct { line: usize, column: usize } {34pub const Loc = struct {
35 line: usize,
36 column: usize,
37 /// Does not include the trailing newline.
38 source_line: []const u8,
39};
40
41pub fn findLineColumn(source: []const u8, byte_offset: usize) Loc {
35 var line: usize = 0;42 var line: usize = 0;
36 var column: usize = 0;43 var column: usize = 0;
37 for (source[0..byte_offset]) |byte| {44 var line_start: usize = 0;
38 switch (byte) {45 var i: usize = 0;
46 while (i < byte_offset) : (i += 1) {
47 switch (source[i]) {
39 '\n' => {48 '\n' => {
40 line += 1;49 line += 1;
41 column = 0;50 column = 0;
51 line_start = i + 1;
42 },52 },
43 else => {53 else => {
44 column += 1;54 column += 1;
45 },55 },
46 }56 }
47 }57 }
48 return .{ .line = line, .column = column };58 while (i < source.len and source[i] != '\n') {
59 i += 1;
60 }
61 return .{
62 .line = line,
63 .column = column,
64 .source_line = source[line_start..i],
65 };
49}66}
5067
51pub fn lineDelta(source: []const u8, start: usize, end: usize) isize {68pub fn lineDelta(source: []const u8, start: usize, end: usize) isize {
src/Compilation.zig+34-7
...@@ -272,28 +272,52 @@ pub const AllErrors = struct {...@@ -272,28 +272,52 @@ pub const AllErrors = struct {
272 line: u32,272 line: u32,
273 column: u32,273 column: u32,
274 byte_offset: u32,274 byte_offset: u32,
275 /// Does not include the trailing newline.
276 source_line: ?[]const u8,
275 notes: []Message = &.{},277 notes: []Message = &.{},
276 },278 },
277 plain: struct {279 plain: struct {
278 msg: []const u8,280 msg: []const u8,
279 },281 },
280282
281 pub fn renderToStdErr(msg: Message) void {283 pub fn renderToStdErr(msg: Message, ttyconf: std.debug.TTY.Config) void {
282 return msg.renderToStdErrInner("error");284 const stderr_mutex = std.debug.getStderrMutex();
285 const held = std.debug.getStderrMutex().acquire();
286 defer held.release();
287 const stderr = std.io.getStdErr();
288 return msg.renderToStdErrInner(ttyconf, stderr, "error", .Red) catch return;
283 }289 }
284290
285 fn renderToStdErrInner(msg: Message, kind: []const u8) void {291 fn renderToStdErrInner(
292 msg: Message,
293 ttyconf: std.debug.TTY.Config,
294 stderr_file: std.fs.File,
295 kind: []const u8,
296 color: std.debug.TTY.Color,
297 ) anyerror!void {
298 const stderr = stderr_file.writer();
286 switch (msg) {299 switch (msg) {
287 .src => |src| {300 .src => |src| {
288 std.debug.print("{s}:{d}:{d}: {s}: {s}\n", .{301 try stderr.print("{s}:{d}:{d}: ", .{
289 src.src_path,302 src.src_path,
290 src.line + 1,303 src.line + 1,
291 src.column + 1,304 src.column + 1,
292 kind,
293 src.msg,
294 });305 });
306 ttyconf.setColor(stderr, color);
307 try stderr.writeAll(kind);
308 ttyconf.setColor(stderr, .Bold);
309 try stderr.print(" {s}\n", .{src.msg});
310 ttyconf.setColor(stderr, .Reset);
311 if (src.source_line) |line| {
312 try stderr.writeAll(line);
313 try stderr.writeByte('\n');
314 try stderr.writeByteNTimes(' ', src.column);
315 ttyconf.setColor(stderr, .Green);
316 try stderr.writeAll("^\n");
317 ttyconf.setColor(stderr, .Reset);
318 }
295 for (src.notes) |note| {319 for (src.notes) |note| {
296 note.renderToStdErrInner("note");320 try note.renderToStdErrInner(ttyconf, stderr_file, "note", .Cyan);
297 }321 }
298 },322 },
299 .plain => |plain| {323 .plain => |plain| {
...@@ -327,6 +351,7 @@ pub const AllErrors = struct {...@@ -327,6 +351,7 @@ pub const AllErrors = struct {
327 .byte_offset = byte_offset,351 .byte_offset = byte_offset,
328 .line = @intCast(u32, loc.line),352 .line = @intCast(u32, loc.line),
329 .column = @intCast(u32, loc.column),353 .column = @intCast(u32, loc.column),
354 .source_line = try arena.allocator.dupe(u8, loc.source_line),
330 },355 },
331 };356 };
332 }357 }
...@@ -342,6 +367,7 @@ pub const AllErrors = struct {...@@ -342,6 +367,7 @@ pub const AllErrors = struct {
342 .line = @intCast(u32, loc.line),367 .line = @intCast(u32, loc.line),
343 .column = @intCast(u32, loc.column),368 .column = @intCast(u32, loc.column),
344 .notes = notes,369 .notes = notes,
370 .source_line = try arena.allocator.dupe(u8, loc.source_line),
345 },371 },
346 });372 });
347 }373 }
...@@ -1489,6 +1515,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -1489,6 +1515,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
1489 .byte_offset = 0,1515 .byte_offset = 0,
1490 .line = err_msg.line,1516 .line = err_msg.line,
1491 .column = err_msg.column,1517 .column = err_msg.column,
1518 .source_line = null, // TODO
1492 },1519 },
1493 });1520 });
1494 }1521 }
src/main.zig+5-1
...@@ -2106,8 +2106,12 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi...@@ -2106,8 +2106,12 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi
2106 defer errors.deinit(comp.gpa);2106 defer errors.deinit(comp.gpa);
21072107
2108 if (errors.list.len != 0) {2108 if (errors.list.len != 0) {
2109 const ttyconf: std.debug.TTY.Config = switch (comp.color) {
2110 .auto, .on => std.debug.detectTTYConfig(),
2111 .off => .no_color,
2112 };
2109 for (errors.list) |full_err_msg| {2113 for (errors.list) |full_err_msg| {
2110 full_err_msg.renderToStdErr();2114 full_err_msg.renderToStdErr(ttyconf);
2111 }2115 }
2112 const log_text = comp.getCompileLogOutput();2116 const log_text = comp.getCompileLogOutput();
2113 if (log_text.len != 0) {2117 if (log_text.len != 0) {