diff options
| author | jacob gw <jacoblevgw@gmail.com> | 2021-04-06 17:19:34 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-08 23:17:36 -0700 |
| commit | 99ec511c4c62d22c88a57395e169948140c5b712 (patch) | |
| tree | 3a4e8a85ea89af1a53421956f97d635f3a1fe4c5 /src | |
| parent | c28d1fe1733eb150f956b1eb0d01d79496e7378c (diff) | |
| download | zig-99ec511c4c62d22c88a57395e169948140c5b712.tar.gz zig-99ec511c4c62d22c88a57395e169948140c5b712.zip | |
stage2: pretty print compilation errors
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 103 | ||||
| -rw-r--r-- | src/main.zig | 2 |
2 files changed, 86 insertions, 19 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 080d4bddaa..9de8e9296c 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator; const assert = std.debug.assert; const log = std.log.scoped(.compilation); const Target = std.Target; +const debug = std.debug; const Value = @import("value.zig").Value; const Type = @import("type.zig").Type; @@ -266,9 +267,30 @@ pub const AllErrors = struct { list: []const Message, pub const Message = union(enum) { + const MessageType = enum { + pub fn render(self: @This(), stderr: anytype, ttyconf: std.debug.TTY.Config) !void { + switch (self) { + .err => { + ttyconf.setColor(stderr, .Red); + try stderr.writeAll("error:"); + }, + .note => { + ttyconf.setColor(stderr, .Green); + try stderr.writeAll("note:"); + }, + } + ttyconf.setColor(stderr, .Reset); + } + err, + note + }; + src: struct { msg: []const u8, - src_path: []const u8, + src_path: union(enum) { + path: []const u8, + scope: *Module.Scope.File, + }, line: u32, column: u32, byte_offset: u32, @@ -278,26 +300,70 @@ pub const AllErrors = struct { msg: []const u8, }, - pub fn renderToStdErr(msg: Message) void { - return msg.renderToStdErrInner("error"); + pub fn renderToStdErr(msg: Message, mod: ?*Module) !void { + return msg.renderToStdErrInner(.err, mod); } - fn renderToStdErrInner(msg: Message, kind: []const u8) void { + 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 { + const ttyconf = debug.detectTTYConfig(); + const stderr = std.io.getStdErr().writer(); switch (msg) { .src => |src| { - std.debug.print("{s}:{d}:{d}: {s}: {s}\n", .{ - src.src_path, - src.line + 1, - src.column + 1, - kind, - src.msg, - }); + switch (src.src_path) { + .path => |p| { + // TODO read the file and do pretty printing for c objects? + try stderr.print("{s}:{d}:{d}: ", .{ + p, + src.line + 1, + src.column + 1, + }); + try kind.render(stderr, ttyconf); + try stderr.print(" {s}\n", .{ + src.msg, + }); + }, + .scope => |s| { + const module = mod.?; + try stderr.print("{s}:{d}:{d}: ", .{ + s.sub_file_path, + src.line + 1, + src.column + 1, + }); + try kind.render(stderr, ttyconf); + try stderr.print(" {s}\n", .{ + src.msg, + }); + const fsource = try s.getSource(module); + const end_pos = blk: for (fsource[src.byte_offset..]) |c, i| { + if (c == '\n') + break :blk src.byte_offset + i + 1; + if (c == 0) + break :blk fsource.len - 1; + } else unreachable; + const start_pos = blk: { + var i = src.byte_offset; + var c: u8 = fsource[i]; + while (i > 0) : ({ + i -= 1; + c = fsource[i]; + }) { + if (c == '\n') break :blk i + 1; + } + break :blk 0; + }; + try stderr.writeAll(fsource[start_pos..end_pos]); + try stderr.writeByteNTimes(' ', src.column); + ttyconf.setColor(stderr, .Cyan); + try stderr.writeAll("^\n"); + ttyconf.setColor(stderr, .Reset); + }, + } for (src.notes) |note| { - note.renderToStdErrInner("note"); + try note.renderToStdErrInner(.note, mod); } }, .plain => |plain| { - std.debug.print("{s}: {s}\n", .{ kind, plain.msg }); + debug.print("{s}: {s}\n", .{ kind, plain.msg }); }, } } @@ -319,10 +385,11 @@ pub const AllErrors = struct { const source = try module_note.src_loc.fileScope().getSource(module); const byte_offset = try module_note.src_loc.byteOffset(); const loc = std.zig.findLineColumn(source, byte_offset); - const sub_file_path = module_note.src_loc.fileScope().sub_file_path; + const fscope = module_note.src_loc.fileScope(); note.* = .{ .src = .{ - .src_path = try arena.allocator.dupe(u8, sub_file_path), + // TODO this might be freed, might need to dupe the source + .src_path = .{ .scope = fscope }, .msg = try arena.allocator.dupe(u8, module_note.msg), .byte_offset = byte_offset, .line = @intCast(u32, loc.line), @@ -333,10 +400,10 @@ pub const AllErrors = struct { const source = try module_err_msg.src_loc.fileScope().getSource(module); const byte_offset = try module_err_msg.src_loc.byteOffset(); const loc = std.zig.findLineColumn(source, byte_offset); - const sub_file_path = module_err_msg.src_loc.fileScope().sub_file_path; + const fscope = module_err_msg.src_loc.fileScope(); try errors.append(.{ .src = .{ - .src_path = try arena.allocator.dupe(u8, sub_file_path), + .src_path = .{ .scope = fscope }, .msg = try arena.allocator.dupe(u8, module_err_msg.msg), .byte_offset = byte_offset, .line = @intCast(u32, loc.line), @@ -1482,7 +1549,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { // C error reporting bubbling up. try errors.append(.{ .src = .{ - .src_path = try arena.allocator.dupe(u8, c_object.src.src_path), + .src_path = .{ .path = try arena.allocator.dupe(u8, c_object.src.src_path) }, .msg = try std.fmt.allocPrint(&arena.allocator, "unable to build C object: {s}", .{ err_msg.msg, }), diff --git a/src/main.zig b/src/main.zig index 5fb74db61f..032703a460 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2107,7 +2107,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi if (errors.list.len != 0) { for (errors.list) |full_err_msg| { - full_err_msg.renderToStdErr(); + try full_err_msg.renderToStdErr(comp.bin_file.options.module); } const log_text = comp.getCompileLogOutput(); if (log_text.len != 0) { |
