| ... | @@ -5,8 +5,8 @@ | ... | @@ -5,8 +5,8 @@ |
| 5 | //! | 5 | //! |
| 6 | //! Across the compiler, `Report.Builder`s' `.err` and `.warn` methods | 6 | //! Across the compiler, `Report.Builder`s' `.err` and `.warn` methods |
| 7 | //! can add messages by ID. | 7 | //! can add messages by ID. |
| 8 | errors: []Item, | 8 | errors: []Item(Err), |
| 9 | warnings: []Item, | 9 | warnings: []Item(Warn), |
| 10 | string_bytes: []u8, | 10 | string_bytes: []u8, |
| 11 | | 11 | |
| 12 | pub const empty: Report = .{ | 12 | pub const empty: Report = .{ |
| ... | @@ -18,23 +18,20 @@ pub const empty: Report = .{ | ... | @@ -18,23 +18,20 @@ pub const empty: Report = .{ |
| 18 | pub var debug_show_report_trace: if (builtin.mode == .Debug) bool else void = | 18 | pub var debug_show_report_trace: if (builtin.mode == .Debug) bool else void = |
| 19 | if (builtin.mode == .Debug) false; | 19 | if (builtin.mode == .Debug) false; |
| 20 | | 20 | |
| 21 | pub const Item = struct { | 21 | pub fn Item(T: type) type { |
| 22 | /// What is this diagnostic | 22 | return struct { |
| 23 | data: union { @"error": Err, warn: Warn }, | 23 | data: T, |
| 24 | | 24 | debug_stack_trace: DebugStoredTrace = .empty, |
| 25 | debug_stack_trace: DebugStoredTrace = .empty, | 25 | }; |
| 26 | | 26 | } |
| 27 | /// Type is never stored, inferred from which list it is in. | | |
| 28 | pub const Type = enum { @"error", warn }; | | |
| 29 | }; | | |
| 30 | | 27 | |
| 31 | pub const Err = union(enum) { | 28 | pub const Err = union(enum) { |
| 32 | pub const FieldEnum = core.FieldEnum(Err); | 29 | pub const FieldEnum = core.FieldEnum(Err); |
| 33 | | 30 | |
| 34 | /// Constructs a `Report` with just a single error. | 31 | /// Constructs a `Report` with just a single error. |
| 35 | pub fn toReport(err: Err, alloc: Allocator, trace: DebugStoredTrace) !Report { | 32 | pub fn toReport(err: Err, alloc: Allocator, trace: DebugStoredTrace) !Report { |
| 36 | const errors = try alloc.dupe(Item, &.{.{ | 33 | const errors = try alloc.dupe(Item(Err), &.{.{ |
| 37 | .data = .{ .@"error" = err }, | 34 | .data = err, |
| 38 | .debug_stack_trace = trace, | 35 | .debug_stack_trace = trace, |
| 39 | }}); | 36 | }}); |
| 40 | return .{ .errors = errors, .warnings = &.{}, .string_bytes = &.{} }; | 37 | return .{ .errors = errors, .warnings = &.{}, .string_bytes = &.{} }; |
| ... | @@ -641,7 +638,7 @@ pub fn dump(report: Report, ctx: DumpContext, out: core.OutStream) !void { | ... | @@ -641,7 +638,7 @@ pub fn dump(report: Report, ctx: DumpContext, out: core.OutStream) !void { |
| 641 | const ast: *const Ast = switch (ctx) { | 638 | const ast: *const Ast = switch (ctx) { |
| 642 | .comp => |comp_ctx| | 639 | .comp => |comp_ctx| |
| 643 | // Ast cannot be queried if the error is in computing the Ast | 640 | // Ast cannot be queried if the error is in computing the Ast |
| 644 | if (report.errors.len > 0 and report.errors[0].data.@"error" == .ast) fake_ast: { | 641 | if (report.errors.len > 0 and report.errors[0].data == .ast) fake_ast: { |
| 645 | fake_ast_data = .{ | 642 | fake_ast_data = .{ |
| 646 | .utf8_source = (comp_ctx.file.getSource(comp_ctx.comp.gpa) catch { | 643 | .utf8_source = (comp_ctx.file.getSource(comp_ctx.comp.gpa) catch { |
| 647 | @panic("TODO"); | 644 | @panic("TODO"); |
| ... | @@ -695,18 +692,18 @@ pub fn dump(report: Report, ctx: DumpContext, out: core.OutStream) !void { | ... | @@ -695,18 +692,18 @@ pub fn dump(report: Report, ctx: DumpContext, out: core.OutStream) !void { |
| 695 | }; | 692 | }; |
| 696 | | 693 | |
| 697 | for (report.errors) |item| { | 694 | for (report.errors) |item| { |
| 698 | try formatItem(item, .@"error", arena.allocator(), url, msg_ctx, out); | 695 | try formatItem(Err, item, arena.allocator(), url, msg_ctx, out); |
| 699 | _ = arena.reset(.retain_capacity); | 696 | _ = arena.reset(.retain_capacity); |
| 700 | } | 697 | } |
| 701 | for (report.warnings) |item| { | 698 | for (report.warnings) |item| { |
| 702 | try formatItem(item, .warn, arena.allocator(), url, msg_ctx, out); | 699 | try formatItem(Warn, item, arena.allocator(), url, msg_ctx, out); |
| 703 | _ = arena.reset(.retain_capacity); | 700 | _ = arena.reset(.retain_capacity); |
| 704 | } | 701 | } |
| 705 | } | 702 | } |
| 706 | | 703 | |
| 707 | fn formatItem( | 704 | fn formatItem( |
| 708 | item: Item, | 705 | comptime T: type, |
| 709 | item_type: Item.Type, | 706 | item: Item(T), |
| 710 | arena: Allocator, | 707 | arena: Allocator, |
| 711 | url: []const u8, | 708 | url: []const u8, |
| 712 | ctx_init: MsgContext, | 709 | ctx_init: MsgContext, |
| ... | @@ -720,10 +717,8 @@ fn formatItem( | ... | @@ -720,10 +717,8 @@ fn formatItem( |
| 720 | ctx.components = ArrayListUnmanaged(Component).initCapacity(alloc, 16) catch | 717 | ctx.components = ArrayListUnmanaged(Component).initCapacity(alloc, 16) catch |
| 721 | unreachable; // stack-fallback allocator has enough space. | 718 | unreachable; // stack-fallback allocator has enough space. |
| 722 | | 719 | |
| 723 | switch (item_type) { | 720 | switch (item.data) { |
| 724 | inline else => |tag| switch (@field(item.data, @tagName(tag))) { | 721 | inline else => |payload| try payload.build(&ctx), |
| 725 | inline else => |payload| try payload.build(&ctx), | | |
| 726 | }, | | |
| 727 | } | 722 | } |
| 728 | | 723 | |
| 729 | assert(ctx.components.items.len > 0); | 724 | assert(ctx.components.items.len > 0); |
| ... | @@ -744,8 +739,10 @@ fn formatItem( | ... | @@ -744,8 +739,10 @@ fn formatItem( |
| 744 | | 739 | |
| 745 | for (ctx.components.items, 1..) |component, i| { | 740 | for (ctx.components.items, 1..) |component, i| { |
| 746 | const prefix: Prefix = if (i == 1) | 741 | const prefix: Prefix = if (i == 1) |
| 747 | switch (item_type) { | 742 | switch (T) { |
| 748 | inline else => |tag| @field(Prefix, @tagName(tag)), | 743 | Err => .@"error", |
| | 744 | Warn => .warn, |
| | 745 | else => @compileError(unreachable), |
| 749 | } | 746 | } |
| 750 | else | 747 | else |
| 751 | .note; | 748 | .note; |
| ... | @@ -862,8 +859,8 @@ fn formatItem( | ... | @@ -862,8 +859,8 @@ fn formatItem( |
| 862 | | 859 | |
| 863 | pub const Builder = struct { | 860 | pub const Builder = struct { |
| 864 | gpa: Allocator, | 861 | gpa: Allocator, |
| 865 | errors: ArrayListUnmanaged(Item), | 862 | errors: ArrayListUnmanaged(Item(Err)), |
| 866 | warnings: ArrayListUnmanaged(Item), | 863 | warnings: ArrayListUnmanaged(Item(Warn)), |
| 867 | string_bytes: ArrayListUnmanaged(u8), | 864 | string_bytes: ArrayListUnmanaged(u8), |
| 868 | | 865 | |
| 869 | pub fn init(gpa: Allocator) Builder { | 866 | pub fn init(gpa: Allocator) Builder { |
| ... | @@ -890,7 +887,7 @@ pub const Builder = struct { | ... | @@ -890,7 +887,7 @@ pub const Builder = struct { |
| 890 | return_address: usize, | 887 | return_address: usize, |
| 891 | ) !void { | 888 | ) !void { |
| 892 | try b.errors.append(b.gpa, .{ | 889 | try b.errors.append(b.gpa, .{ |
| 893 | .data = .{ .@"error" = @unionInit(Err, @tagName(kind), data) }, | 890 | .data = @unionInit(Err, @tagName(kind), data), |
| 894 | .debug_stack_trace = DebugStoredTrace.capture(return_address), | 891 | .debug_stack_trace = DebugStoredTrace.capture(return_address), |
| 895 | }); | 892 | }); |
| 896 | } | 893 | } |
| ... | @@ -902,7 +899,7 @@ pub const Builder = struct { | ... | @@ -902,7 +899,7 @@ pub const Builder = struct { |
| 902 | return_address: usize, | 899 | return_address: usize, |
| 903 | ) !void { | 900 | ) !void { |
| 904 | try b.warnings.append(b.gpa, .{ | 901 | try b.warnings.append(b.gpa, .{ |
| 905 | .data = .{ .warn = @unionInit(Warn, @tagName(kind), data) }, | 902 | .data = @unionInit(Warn, @tagName(kind), data), |
| 906 | .debug_stack_trace = DebugStoredTrace.capture(return_address), | 903 | .debug_stack_trace = DebugStoredTrace.capture(return_address), |
| 907 | }); | 904 | }); |
| 908 | } | 905 | } |