| ... | ... | @@ -6,7 +6,6 @@ const Allocator = std.mem.Allocator; |
| 6 | 6 | const assert = std.debug.assert; |
| 7 | 7 | const log = std.log.scoped(.compilation); |
| 8 | 8 | const Target = std.Target; |
| 9 | | const debug = std.debug; |
| 10 | 9 | |
| 11 | 10 | const Value = @import("value.zig").Value; |
| 12 | 11 | const Type = @import("type.zig").Type; |
| ... | ... | @@ -267,103 +266,62 @@ pub const AllErrors = struct { |
| 267 | 266 | list: []const Message, |
| 268 | 267 | |
| 269 | 268 | 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 | | |
| 288 | 269 | src: struct { |
| 289 | 270 | msg: []const u8, |
| 290 | | src_path: union(enum) { |
| 291 | | path: []const u8, |
| 292 | | scope: *Module.Scope.File, |
| 293 | | }, |
| 271 | src_path: []const u8, |
| 294 | 272 | line: u32, |
| 295 | 273 | column: u32, |
| 296 | 274 | byte_offset: u32, |
| 275 | /// Does not include the trailing newline. |
| 276 | source_line: ?[]const u8, |
| 297 | 277 | notes: []Message = &.{}, |
| 298 | 278 | }, |
| 299 | 279 | plain: struct { |
| 300 | 280 | msg: []const u8, |
| 301 | 281 | }, |
| 302 | 282 | |
| 303 | | pub fn renderToStdErr(msg: Message, mod: ?*Module) !void { |
| 304 | | return msg.renderToStdErrInner(.err, mod); |
| 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; |
| 305 | 289 | } |
| 306 | 290 | |
| 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(); |
| 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(); |
| 310 | 299 | switch (msg) { |
| 311 | 300 | .src => |src| { |
| 312 | | switch (src.src_path) { |
| 313 | | .path => |p| { |
| 314 | | // TODO read the file and do pretty printing for c objects? |
| 315 | | try stderr.print("{s}:{d}:{d}: ", .{ |
| 316 | | p, |
| 317 | | src.line + 1, |
| 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 | | }, |
| 301 | try stderr.print("{s}:{d}:{d}: ", .{ |
| 302 | src.src_path, |
| 303 | src.line + 1, |
| 304 | src.column + 1, |
| 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); |
| 360 | 318 | } |
| 361 | 319 | for (src.notes) |note| { |
| 362 | | try note.renderToStdErrInner(.note, mod); |
| 320 | try note.renderToStdErrInner(ttyconf, stderr_file, "note", .Cyan); |
| 363 | 321 | } |
| 364 | 322 | }, |
| 365 | 323 | .plain => |plain| { |
| 366 | | debug.print("{s}: {s}\n", .{ kind, plain.msg }); |
| 324 | std.debug.print("{s}: {s}\n", .{ kind, plain.msg }); |
| 367 | 325 | }, |
| 368 | 326 | } |
| 369 | 327 | } |
| ... | ... | @@ -385,30 +343,31 @@ pub const AllErrors = struct { |
| 385 | 343 | const source = try module_note.src_loc.fileScope().getSource(module); |
| 386 | 344 | const byte_offset = try module_note.src_loc.byteOffset(); |
| 387 | 345 | const loc = std.zig.findLineColumn(source, byte_offset); |
| 388 | | const fscope = module_note.src_loc.fileScope(); |
| 346 | const sub_file_path = module_note.src_loc.fileScope().sub_file_path; |
| 389 | 347 | note.* = .{ |
| 390 | 348 | .src = .{ |
| 391 | | // TODO this might be freed, might need to dupe the source |
| 392 | | .src_path = .{ .scope = fscope }, |
| 349 | .src_path = try arena.allocator.dupe(u8, sub_file_path), |
| 393 | 350 | .msg = try arena.allocator.dupe(u8, module_note.msg), |
| 394 | 351 | .byte_offset = byte_offset, |
| 395 | 352 | .line = @intCast(u32, loc.line), |
| 396 | 353 | .column = @intCast(u32, loc.column), |
| 354 | .source_line = try arena.allocator.dupe(u8, loc.source_line), |
| 397 | 355 | }, |
| 398 | 356 | }; |
| 399 | 357 | } |
| 400 | 358 | const source = try module_err_msg.src_loc.fileScope().getSource(module); |
| 401 | 359 | const byte_offset = try module_err_msg.src_loc.byteOffset(); |
| 402 | 360 | const loc = std.zig.findLineColumn(source, byte_offset); |
| 403 | | const fscope = module_err_msg.src_loc.fileScope(); |
| 361 | const sub_file_path = module_err_msg.src_loc.fileScope().sub_file_path; |
| 404 | 362 | try errors.append(.{ |
| 405 | 363 | .src = .{ |
| 406 | | .src_path = .{ .scope = fscope }, |
| 364 | .src_path = try arena.allocator.dupe(u8, sub_file_path), |
| 407 | 365 | .msg = try arena.allocator.dupe(u8, module_err_msg.msg), |
| 408 | 366 | .byte_offset = byte_offset, |
| 409 | 367 | .line = @intCast(u32, loc.line), |
| 410 | 368 | .column = @intCast(u32, loc.column), |
| 411 | 369 | .notes = notes, |
| 370 | .source_line = try arena.allocator.dupe(u8, loc.source_line), |
| 412 | 371 | }, |
| 413 | 372 | }); |
| 414 | 373 | } |
| ... | ... | @@ -1549,13 +1508,14 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { |
| 1549 | 1508 | // C error reporting bubbling up. |
| 1550 | 1509 | try errors.append(.{ |
| 1551 | 1510 | .src = .{ |
| 1552 | | .src_path = .{ .path = try arena.allocator.dupe(u8, c_object.src.src_path) }, |
| 1511 | .src_path = try arena.allocator.dupe(u8, c_object.src.src_path), |
| 1553 | 1512 | .msg = try std.fmt.allocPrint(&arena.allocator, "unable to build C object: {s}", .{ |
| 1554 | 1513 | err_msg.msg, |
| 1555 | 1514 | }), |
| 1556 | 1515 | .byte_offset = 0, |
| 1557 | 1516 | .line = err_msg.line, |
| 1558 | 1517 | .column = err_msg.column, |
| 1518 | .source_line = null, // TODO |
| 1559 | 1519 | }, |
| 1560 | 1520 | }); |
| 1561 | 1521 | } |