| ... | ... | @@ -272,28 +272,52 @@ pub const AllErrors = struct { |
| 272 | 272 | line: u32, |
| 273 | 273 | column: u32, |
| 274 | 274 | byte_offset: u32, |
| 275 | /// Does not include the trailing newline. |
| 276 | source_line: ?[]const u8, |
| 275 | 277 | notes: []Message = &.{}, |
| 276 | 278 | }, |
| 277 | 279 | plain: struct { |
| 278 | 280 | msg: []const u8, |
| 279 | 281 | }, |
| 280 | 282 | |
| 281 | | pub fn renderToStdErr(msg: Message) void { |
| 282 | | return msg.renderToStdErrInner("error"); |
| 283 | pub fn renderToStdErr(msg: Message, ttyconf: std.debug.TTY.Config) void { |
| 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 | } |
| 284 | 290 | |
| 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 | 299 | switch (msg) { |
| 287 | 300 | .src => |src| { |
| 288 | | std.debug.print("{s}:{d}:{d}: {s}: {s}\n", .{ |
| 301 | try stderr.print("{s}:{d}:{d}: ", .{ |
| 289 | 302 | src.src_path, |
| 290 | 303 | src.line + 1, |
| 291 | 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 | 319 | for (src.notes) |note| { |
| 296 | | note.renderToStdErrInner("note"); |
| 320 | try note.renderToStdErrInner(ttyconf, stderr_file, "note", .Cyan); |
| 297 | 321 | } |
| 298 | 322 | }, |
| 299 | 323 | .plain => |plain| { |
| ... | ... | @@ -327,6 +351,7 @@ pub const AllErrors = struct { |
| 327 | 351 | .byte_offset = byte_offset, |
| 328 | 352 | .line = @intCast(u32, loc.line), |
| 329 | 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 | 367 | .line = @intCast(u32, loc.line), |
| 343 | 368 | .column = @intCast(u32, loc.column), |
| 344 | 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 | 1515 | .byte_offset = 0, |
| 1490 | 1516 | .line = err_msg.line, |
| 1491 | 1517 | .column = err_msg.column, |
| 1518 | .source_line = null, // TODO |
| 1492 | 1519 | }, |
| 1493 | 1520 | }); |
| 1494 | 1521 | } |