| ... | ... | @@ -567,6 +567,28 @@ pub const Wip = struct { |
| 567 | 567 | if (index == .none) return .none; |
| 568 | 568 | const other_sl = other.getSourceLocation(index); |
| 569 | 569 | |
| 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 | |
| 570 | 592 | const src_loc = try wip.addSourceLocation(.{ |
| 571 | 593 | .src_path = try wip.addString(other.nullTerminatedString(other_sl.src_path)), |
| 572 | 594 | .line = other_sl.line, |
| ... | ... | @@ -581,7 +603,9 @@ pub const Wip = struct { |
| 581 | 603 | .reference_trace_len = other_sl.reference_trace_len, |
| 582 | 604 | }); |
| 583 | 605 | |
| 584 | | // TODO: also add the reference trace |
| 606 | for (ref_traces.items) |ref_trace| { |
| 607 | try wip.addReferenceTrace(ref_trace); |
| 608 | } |
| 585 | 609 | |
| 586 | 610 | return src_loc; |
| 587 | 611 | } |
| ... | ... | @@ -615,3 +639,95 @@ pub const Wip = struct { |
| 615 | 639 | } |
| 616 | 640 | } |
| 617 | 641 | }; |
| 642 | |
| 643 | test "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 | } |