DoxigAlpha

addZirErrorMessages

Function parameters

Parameters

#
eb:*ErrorBundle.Wip
zir:std.zig.Zir
tree:std.zig.Ast
source:[:0]const u8
src_path:[]const u8

Type definitions in this namespace

Types

#
ErrorMessageList
There will be a MessageIndex for each len at start.
SourceLocation
Trailing:
ErrorMessage
Trailing:

Functions in this namespace

Functions

#
nullTerminatedString
Given an index into `string_bytes` returns the null-terminated string found there.

Special encoding when there are no errors.

Values

#
empty
Special encoding when there are no errors.

Source

Implementation

#
pub fn addZirErrorMessages(
    eb: *ErrorBundle.Wip,
    zir: std.zig.Zir,
    tree: std.zig.Ast,
    source: [:0]const u8,
    src_path: []const u8,
) !void {
    const Zir = std.zig.Zir;
    const payload_index = zir.extra[@intFromEnum(Zir.ExtraIndex.compile_errors)];
    assert(payload_index != 0);

    const header = zir.extraData(Zir.Inst.CompileErrors, payload_index);
    const items_len = header.data.items_len;
    var extra_index = header.end;
    for (0..items_len) |_| {
        const item = zir.extraData(Zir.Inst.CompileErrors.Item, extra_index);
        extra_index = item.end;
        const err_span = blk: {
            if (item.data.node.unwrap()) |node| {
                break :blk tree.nodeToSpan(node);
            } else if (item.data.token.unwrap()) |token| {
                const start = tree.tokenStart(token) + item.data.byte_offset;
                const end = start + @as(u32, @intCast(tree.tokenSlice(token).len)) - item.data.byte_offset;
                break :blk std.zig.Ast.Span{ .start = start, .end = end, .main = start };
            } else unreachable;
        };
        const err_loc = std.zig.findLineColumn(source, err_span.main);

        {
            const msg = zir.nullTerminatedString(item.data.msg);
            try eb.addRootErrorMessage(.{
                .msg = try eb.addString(msg),
                .src_loc = try eb.addSourceLocation(.{
                    .src_path = try eb.addString(src_path),
                    .span_start = err_span.start,
                    .span_main = err_span.main,
                    .span_end = err_span.end,
                    .line = @intCast(err_loc.line),
                    .column = @intCast(err_loc.column),
                    .source_line = try eb.addString(err_loc.source_line),
                }),
                .notes_len = item.data.notesLen(zir),
            });
        }

        if (item.data.notes != 0) {
            const notes_start = try eb.reserveNotes(item.data.notesLen(zir));
            const block = zir.extraData(Zir.Inst.Block, item.data.notes);
            const body = zir.extra[block.end..][0..block.data.body_len];
            for (notes_start.., body) |note_i, body_elem| {
                const note_item = zir.extraData(Zir.Inst.CompileErrors.Item, body_elem);
                const msg = zir.nullTerminatedString(note_item.data.msg);
                const span = blk: {
                    if (note_item.data.node.unwrap()) |node| {
                        break :blk tree.nodeToSpan(node);
                    } else if (note_item.data.token.unwrap()) |token| {
                        const start = tree.tokenStart(token) + note_item.data.byte_offset;
                        const end = start + @as(u32, @intCast(tree.tokenSlice(token).len)) - item.data.byte_offset;
                        break :blk std.zig.Ast.Span{ .start = start, .end = end, .main = start };
                    } else unreachable;
                };
                const loc = std.zig.findLineColumn(source, span.main);

                // This line can cause `wip.extra.items` to be resized.
                const note_index = @intFromEnum(try eb.addErrorMessage(.{
                    .msg = try eb.addString(msg),
                    .src_loc = try eb.addSourceLocation(.{
                        .src_path = try eb.addString(src_path),
                        .span_start = span.start,
                        .span_main = span.main,
                        .span_end = span.end,
                        .line = @intCast(loc.line),
                        .column = @intCast(loc.column),
                        .source_line = if (loc.eql(err_loc))
                            0
                        else
                            try eb.addString(loc.source_line),
                    }),
                    .notes_len = 0, // TODO rework this function to be recursive
                }));
                eb.extra.items[note_i] = note_index;
            }
        }
    }
}