authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-04-06 17:19:34-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-08 23:17:36-07:00
log99ec511c4c62d22c88a57395e169948140c5b712
tree3a4e8a85ea89af1a53421956f97d635f3a1fe4c5
parentc28d1fe1733eb150f956b1eb0d01d79496e7378c

stage2: pretty print compilation errors


3 files changed, 87 insertions(+), 20 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) {
src/Compilation.zig+85-18
...@@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator;...@@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator;
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const log = std.log.scoped(.compilation);7const log = std.log.scoped(.compilation);
8const Target = std.Target;8const Target = std.Target;
9const debug = std.debug;
910
10const Value = @import("value.zig").Value;11const Value = @import("value.zig").Value;
11const Type = @import("type.zig").Type;12const Type = @import("type.zig").Type;
...@@ -266,9 +267,30 @@ pub const AllErrors = struct {...@@ -266,9 +267,30 @@ pub const AllErrors = struct {
266 list: []const Message,267 list: []const Message,
267268
268 pub const Message = union(enum) {269 pub const Message = union(enum) {
270 const MessageType = enum {
271 pub fn render(self: @This(), stderr: anytype, ttyconf: std.debug.TTY.Config) !void {
272 switch (self) {
273 .err => {
274 ttyconf.setColor(stderr, .Red);
275 try stderr.writeAll("error:");
276 },
277 .note => {
278 ttyconf.setColor(stderr, .Green);
279 try stderr.writeAll("note:");
280 },
281 }
282 ttyconf.setColor(stderr, .Reset);
283 }
284 err,
285 note
286 };
287
269 src: struct {288 src: struct {
270 msg: []const u8,289 msg: []const u8,
271 src_path: []const u8,290 src_path: union(enum) {
291 path: []const u8,
292 scope: *Module.Scope.File,
293 },
272 line: u32,294 line: u32,
273 column: u32,295 column: u32,
274 byte_offset: u32,296 byte_offset: u32,
...@@ -278,26 +300,70 @@ pub const AllErrors = struct {...@@ -278,26 +300,70 @@ pub const AllErrors = struct {
278 msg: []const u8,300 msg: []const u8,
279 },301 },
280302
281 pub fn renderToStdErr(msg: Message) void {303 pub fn renderToStdErr(msg: Message, mod: ?*Module) !void {
282 return msg.renderToStdErrInner("error");304 return msg.renderToStdErrInner(.err, mod);
283 }305 }
284306
285 fn renderToStdErrInner(msg: Message, kind: []const u8) void {307 fn renderToStdErrInner(msg: Message, kind: MessageType, mod: ?*Module) (std.fs.File.WriteError || @typeInfo(@typeInfo(@TypeOf(Module.Scope.File.getSource)).Fn.return_type.?).ErrorUnion.error_set)!void {
308 const ttyconf = debug.detectTTYConfig();
309 const stderr = std.io.getStdErr().writer();
286 switch (msg) {310 switch (msg) {
287 .src => |src| {311 .src => |src| {
288 std.debug.print("{s}:{d}:{d}: {s}: {s}\n", .{312 switch (src.src_path) {
289 src.src_path,313 .path => |p| {
290 src.line + 1,314 // TODO read the file and do pretty printing for c objects?
291 src.column + 1,315 try stderr.print("{s}:{d}:{d}: ", .{
292 kind,316 p,
293 src.msg,317 src.line + 1,
294 });318 src.column + 1,
319 });
320 try kind.render(stderr, ttyconf);
321 try stderr.print(" {s}\n", .{
322 src.msg,
323 });
324 },
325 .scope => |s| {
326 const module = mod.?;
327 try stderr.print("{s}:{d}:{d}: ", .{
328 s.sub_file_path,
329 src.line + 1,
330 src.column + 1,
331 });
332 try kind.render(stderr, ttyconf);
333 try stderr.print(" {s}\n", .{
334 src.msg,
335 });
336 const fsource = try s.getSource(module);
337 const end_pos = blk: for (fsource[src.byte_offset..]) |c, i| {
338 if (c == '\n')
339 break :blk src.byte_offset + i + 1;
340 if (c == 0)
341 break :blk fsource.len - 1;
342 } else unreachable;
343 const start_pos = blk: {
344 var i = src.byte_offset;
345 var c: u8 = fsource[i];
346 while (i > 0) : ({
347 i -= 1;
348 c = fsource[i];
349 }) {
350 if (c == '\n') break :blk i + 1;
351 }
352 break :blk 0;
353 };
354 try stderr.writeAll(fsource[start_pos..end_pos]);
355 try stderr.writeByteNTimes(' ', src.column);
356 ttyconf.setColor(stderr, .Cyan);
357 try stderr.writeAll("^\n");
358 ttyconf.setColor(stderr, .Reset);
359 },
360 }
295 for (src.notes) |note| {361 for (src.notes) |note| {
296 note.renderToStdErrInner("note");362 try note.renderToStdErrInner(.note, mod);
297 }363 }
298 },364 },
299 .plain => |plain| {365 .plain => |plain| {
300 std.debug.print("{s}: {s}\n", .{ kind, plain.msg });366 debug.print("{s}: {s}\n", .{ kind, plain.msg });
301 },367 },
302 }368 }
303 }369 }
...@@ -319,10 +385,11 @@ pub const AllErrors = struct {...@@ -319,10 +385,11 @@ pub const AllErrors = struct {
319 const source = try module_note.src_loc.fileScope().getSource(module);385 const source = try module_note.src_loc.fileScope().getSource(module);
320 const byte_offset = try module_note.src_loc.byteOffset();386 const byte_offset = try module_note.src_loc.byteOffset();
321 const loc = std.zig.findLineColumn(source, byte_offset);387 const loc = std.zig.findLineColumn(source, byte_offset);
322 const sub_file_path = module_note.src_loc.fileScope().sub_file_path;388 const fscope = module_note.src_loc.fileScope();
323 note.* = .{389 note.* = .{
324 .src = .{390 .src = .{
325 .src_path = try arena.allocator.dupe(u8, sub_file_path),391 // TODO this might be freed, might need to dupe the source
392 .src_path = .{ .scope = fscope },
326 .msg = try arena.allocator.dupe(u8, module_note.msg),393 .msg = try arena.allocator.dupe(u8, module_note.msg),
327 .byte_offset = byte_offset,394 .byte_offset = byte_offset,
328 .line = @intCast(u32, loc.line),395 .line = @intCast(u32, loc.line),
...@@ -333,10 +400,10 @@ pub const AllErrors = struct {...@@ -333,10 +400,10 @@ pub const AllErrors = struct {
333 const source = try module_err_msg.src_loc.fileScope().getSource(module);400 const source = try module_err_msg.src_loc.fileScope().getSource(module);
334 const byte_offset = try module_err_msg.src_loc.byteOffset();401 const byte_offset = try module_err_msg.src_loc.byteOffset();
335 const loc = std.zig.findLineColumn(source, byte_offset);402 const loc = std.zig.findLineColumn(source, byte_offset);
336 const sub_file_path = module_err_msg.src_loc.fileScope().sub_file_path;403 const fscope = module_err_msg.src_loc.fileScope();
337 try errors.append(.{404 try errors.append(.{
338 .src = .{405 .src = .{
339 .src_path = try arena.allocator.dupe(u8, sub_file_path),406 .src_path = .{ .scope = fscope },
340 .msg = try arena.allocator.dupe(u8, module_err_msg.msg),407 .msg = try arena.allocator.dupe(u8, module_err_msg.msg),
341 .byte_offset = byte_offset,408 .byte_offset = byte_offset,
342 .line = @intCast(u32, loc.line),409 .line = @intCast(u32, loc.line),
...@@ -1482,7 +1549,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {...@@ -1482,7 +1549,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
1482 // C error reporting bubbling up.1549 // C error reporting bubbling up.
1483 try errors.append(.{1550 try errors.append(.{
1484 .src = .{1551 .src = .{
1485 .src_path = try arena.allocator.dupe(u8, c_object.src.src_path),1552 .src_path = .{ .path = try arena.allocator.dupe(u8, c_object.src.src_path) },
1486 .msg = try std.fmt.allocPrint(&arena.allocator, "unable to build C object: {s}", .{1553 .msg = try std.fmt.allocPrint(&arena.allocator, "unable to build C object: {s}", .{
1487 err_msg.msg,1554 err_msg.msg,
1488 }),1555 }),
src/main.zig+1-1
...@@ -2107,7 +2107,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi...@@ -2107,7 +2107,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi
21072107
2108 if (errors.list.len != 0) {2108 if (errors.list.len != 0) {
2109 for (errors.list) |full_err_msg| {2109 for (errors.list) |full_err_msg| {
2110 full_err_msg.renderToStdErr();2110 try full_err_msg.renderToStdErr(comp.bin_file.options.module);
2111 }2111 }
2112 const log_text = comp.getCompileLogOutput();2112 const log_text = comp.getCompileLogOutput();
2113 if (log_text.len != 0) {2113 if (log_text.len != 0) {