authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2024-03-08 11:44:18-08:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2024-03-11 05:06:17-07:00
logdc4b05894da63889d895482ef01e77ef0bf6e88c
treef55c18a70ecf2f23440468f057fbe1ffc4b6d805
parent7c05330287b453a0095bc179c7541ab6ea53d146

ErrorBundle: Add support for reference traces in addOtherSourceLocation

Also adds a test for addBundleAsRoots, which uses addOtherSourceLocation.

1 files changed, 117 insertions(+), 1 deletions(-)

lib/std/zig/ErrorBundle.zig+117-1
......@@ -567,6 +567,28 @@ pub const Wip = struct {
567567 if (index == .none) return .none;
568568 const other_sl = other.getSourceLocation(index);
569569
570 var ref_traces: std.ArrayListUnmanaged(ReferenceTrace) = .{};
571 defer ref_traces.deinit(wip.gpa);
572
573 if (other_sl.reference_trace_len > 0) {
574 var ref_index = other.extraData(SourceLocation, @intFromEnum(index)).end;
575 for (0..other_sl.reference_trace_len) |_| {
576 const other_ref_trace_ed = other.extraData(ReferenceTrace, ref_index);
577 const other_ref_trace = other_ref_trace_ed.data;
578 ref_index = other_ref_trace_ed.end;
579
580 const ref_trace: ReferenceTrace = if (other_ref_trace.src_loc == .none) .{
581 // sentinel ReferenceTrace does not store a string index in decl_name
582 .decl_name = other_ref_trace.decl_name,
583 .src_loc = .none,
584 } else .{
585 .decl_name = try wip.addString(other.nullTerminatedString(other_ref_trace.decl_name)),
586 .src_loc = try wip.addOtherSourceLocation(other, other_ref_trace.src_loc),
587 };
588 try ref_traces.append(wip.gpa, ref_trace);
589 }
590 }
591
570592 const src_loc = try wip.addSourceLocation(.{
571593 .src_path = try wip.addString(other.nullTerminatedString(other_sl.src_path)),
572594 .line = other_sl.line,
......@@ -581,7 +603,9 @@ pub const Wip = struct {
581603 .reference_trace_len = other_sl.reference_trace_len,
582604 });
583605
584 // TODO: also add the reference trace
606 for (ref_traces.items) |ref_trace| {
607 try wip.addReferenceTrace(ref_trace);
608 }
585609
586610 return src_loc;
587611 }
......@@ -615,3 +639,95 @@ pub const Wip = struct {
615639 }
616640 }
617641};
642
643test "addBundleAsRoots" {
644 var bundle = bundle: {
645 var wip: ErrorBundle.Wip = undefined;
646 try wip.init(std.testing.allocator);
647 errdefer wip.deinit();
648
649 var ref_traces: [3]ReferenceTrace = undefined;
650 for (&ref_traces, 0..) |*ref_trace, i| {
651 if (i == ref_traces.len - 1) {
652 // sentinel reference trace
653 ref_trace.* = .{
654 .decl_name = 3, // signifies 3 hidden references
655 .src_loc = .none,
656 };
657 } else {
658 ref_trace.* = .{
659 .decl_name = try wip.addString("foo"),
660 .src_loc = try wip.addSourceLocation(.{
661 .src_path = try wip.addString("foo"),
662 .line = 1,
663 .column = 2,
664 .span_start = 3,
665 .span_main = 4,
666 .span_end = 5,
667 .source_line = 0,
668 }),
669 };
670 }
671 }
672
673 const src_loc = try wip.addSourceLocation(.{
674 .src_path = try wip.addString("foo"),
675 .line = 1,
676 .column = 2,
677 .span_start = 3,
678 .span_main = 4,
679 .span_end = 5,
680 .source_line = try wip.addString("some source code"),
681 .reference_trace_len = ref_traces.len,
682 });
683 for (&ref_traces) |ref_trace| {
684 try wip.addReferenceTrace(ref_trace);
685 }
686
687 try wip.addRootErrorMessage(ErrorMessage{
688 .msg = try wip.addString("hello world"),
689 .src_loc = src_loc,
690 .notes_len = 1,
691 });
692 const i = try wip.reserveNotes(1);
693 const note_index = @intFromEnum(wip.addErrorMessageAssumeCapacity(.{
694 .msg = try wip.addString("this is a note"),
695 .src_loc = try wip.addSourceLocation(.{
696 .src_path = try wip.addString("bar"),
697 .line = 1,
698 .column = 2,
699 .span_start = 3,
700 .span_main = 4,
701 .span_end = 5,
702 .source_line = try wip.addString("another line of source"),
703 }),
704 }));
705 wip.extra.items[i] = note_index;
706
707 break :bundle try wip.toOwnedBundle("");
708 };
709 defer bundle.deinit(std.testing.allocator);
710
711 const ttyconf: std.io.tty.Config = .no_color;
712
713 var bundle_buf = std.ArrayList(u8).init(std.testing.allocator);
714 defer bundle_buf.deinit();
715 try bundle.renderToWriter(.{ .ttyconf = ttyconf }, bundle_buf.writer());
716
717 var copy = copy: {
718 var wip: ErrorBundle.Wip = undefined;
719 try wip.init(std.testing.allocator);
720 errdefer wip.deinit();
721
722 try wip.addBundleAsRoots(bundle);
723
724 break :copy try wip.toOwnedBundle("");
725 };
726 defer copy.deinit(std.testing.allocator);
727
728 var copy_buf = std.ArrayList(u8).init(std.testing.allocator);
729 defer copy_buf.deinit();
730 try copy.renderToWriter(.{ .ttyconf = ttyconf }, copy_buf.writer());
731
732 try std.testing.expectEqualStrings(bundle_buf.items, copy_buf.items);
733}