| ... | @@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator; | ... | @@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator; |
| 6 | const assert = std.debug.assert; | 6 | const assert = std.debug.assert; |
| 7 | const log = std.log.scoped(.compilation); | 7 | const log = std.log.scoped(.compilation); |
| 8 | const Target = std.Target; | 8 | const Target = std.Target; |
| | 9 | const debug = std.debug; |
| 9 | | 10 | |
| 10 | const Value = @import("value.zig").Value; | 11 | const Value = @import("value.zig").Value; |
| 11 | const Type = @import("type.zig").Type; | 12 | const 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, |
| 267 | | 268 | |
| 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 | }, |
| 280 | | 302 | |
| 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 | } |
| 284 | | 306 | |
| 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 | }), |