lowerAstErrors
Function parameters
Parameters
- astgen:*AstGen
Functions in this namespace
Functions
Source
Implementation
fn lowerAstErrors(astgen: *AstGen) error{OutOfMemory}!void {
const gpa = astgen.gpa;
const tree = astgen.tree;
assert(tree.errors.len > 0);
var msg: std.io.Writer.Allocating = .init(gpa);
defer msg.deinit();
const msg_w = &msg.writer;
var notes: std.ArrayListUnmanaged(u32) = .empty;
defer notes.deinit(gpa);
const token_starts = tree.tokens.items(.start);
const token_tags = tree.tokens.items(.tag);
const parse_err = tree.errors[0];
const tok = parse_err.token + @intFromBool(parse_err.token_is_prev);
const tok_start = token_starts[tok];
const start_char = tree.source[tok_start];
if (token_tags[tok] == .invalid and
(start_char == '\"' or start_char == '\'' or start_char == '/' or mem.startsWith(u8, tree.source[tok_start..], "\\\\")))
{
const tok_len: u32 = @intCast(tree.tokenSlice(tok).len);
const tok_end = tok_start + tok_len;
const bad_off = blk: {
var idx = tok_start;
while (idx < tok_end) : (idx += 1) {
switch (tree.source[idx]) {
0x00...0x09, 0x0b...0x1f, 0x7f => break,
else => {},
}
}
break :blk idx - tok_start;
};
const ast_err: Ast.Error = .{
.tag = Ast.Error.Tag.invalid_byte,
.token = tok,
.extra = .{ .offset = bad_off },
};
msg.clearRetainingCapacity();
tree.renderError(ast_err, msg_w) catch return error.OutOfMemory;
return try astgen.appendErrorTokNotesOff(tok, bad_off, "{s}", .{msg.written()}, notes.items);
}
var cur_err = tree.errors[0];
for (tree.errors[1..]) |err| {
if (err.is_note) {
tree.renderError(err, msg_w) catch return error.OutOfMemory;
try notes.append(gpa, try astgen.errNoteTok(err.token, "{s}", .{msg.written()}));
} else {
// Flush error
const extra_offset = tree.errorOffset(cur_err);
tree.renderError(cur_err, msg_w) catch return error.OutOfMemory;
try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.written()}, notes.items);
notes.clearRetainingCapacity();
cur_err = err;
// TODO: `Parse` currently does not have good error recovery mechanisms, so the remaining errors could be bogus.
// As such, we'll ignore all remaining errors for now. We should improve `Parse` so that we can report all the errors.
return;
}
msg.clearRetainingCapacity();
}
// Flush error
const extra_offset = tree.errorOffset(cur_err);
tree.renderError(cur_err, msg_w) catch return error.OutOfMemory;
try astgen.appendErrorTokNotesOff(cur_err.token, extra_offset, "{s}", .{msg.written()}, notes.items);
}