DoxigAlpha

renderError

Function parameters

Parameters

#
w:*Writer

Index into `tokens`, or null.

Types

#
OptionalTokenIndex
Index into `tokens`, or null.
TokenOffset
A relative token index.
OptionalTokenOffset
A relative token index, or null.
full
Fully assembled AST node information.
ExtraIndex
Index into `extra_data`.

Functions in this namespace

Functions

#
parse
Result should be freed with tree.deinit() when there are
renderAlloc
`gpa` is used for allocating the resulting formatted source code.
errorOffset
Returns an extra offset for column and byte offset of errors that
legacyAsm
To be deleted after 0.15.0 is tagged

Source

Implementation

#
pub fn renderError(tree: Ast, parse_error: Error, w: *Writer) Writer.Error!void {
    switch (parse_error.tag) {
        .asterisk_after_ptr_deref => {
            // Note that the token will point at the `.*` but ideally the source
            // location would point to the `*` after the `.*`.
            return w.writeAll("'.*' cannot be followed by '*'; are you missing a space?");
        },
        .chained_comparison_operators => {
            return w.writeAll("comparison operators cannot be chained");
        },
        .decl_between_fields => {
            return w.writeAll("declarations are not allowed between container fields");
        },
        .expected_block => {
            return w.print("expected block, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_block_or_assignment => {
            return w.print("expected block or assignment, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_block_or_expr => {
            return w.print("expected block or expression, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_block_or_field => {
            return w.print("expected block or field, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_container_members => {
            return w.print("expected test, comptime, var decl, or container field, found '{s}'", .{
                tree.tokenTag(parse_error.token).symbol(),
            });
        },
        .expected_expr => {
            return w.print("expected expression, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_expr_or_assignment => {
            return w.print("expected expression or assignment, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_expr_or_var_decl => {
            return w.print("expected expression or var decl, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_fn => {
            return w.print("expected function, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_inlinable => {
            return w.print("expected 'while' or 'for', found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_labelable => {
            return w.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_param_list => {
            return w.print("expected parameter list, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_prefix_expr => {
            return w.print("expected prefix expression, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_primary_type_expr => {
            return w.print("expected primary type expression, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_pub_item => {
            return w.writeAll("expected function or variable declaration after pub");
        },
        .expected_return_type => {
            return w.print("expected return type expression, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_semi_or_else => {
            return w.writeAll("expected ';' or 'else' after statement");
        },
        .expected_semi_or_lbrace => {
            return w.writeAll("expected ';' or block after function prototype");
        },
        .expected_statement => {
            return w.print("expected statement, found '{s}'", .{
                tree.tokenTag(parse_error.token).symbol(),
            });
        },
        .expected_suffix_op => {
            return w.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_type_expr => {
            return w.print("expected type expression, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_var_decl => {
            return w.print("expected variable declaration, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_var_decl_or_fn => {
            return w.print("expected variable declaration or function, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_loop_payload => {
            return w.print("expected loop payload, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .expected_container => {
            return w.print("expected a struct, enum or union, found '{s}'", .{
                tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(),
            });
        },
        .extern_fn_body => {
            return w.writeAll("extern functions have no body");
        },
        .extra_addrspace_qualifier => {
            return w.writeAll("extra addrspace qualifier");
        },
        .extra_align_qualifier => {
            return w.writeAll("extra align qualifier");
        },
        .extra_allowzero_qualifier => {
            return w.writeAll("extra allowzero qualifier");
        },
        .extra_const_qualifier => {
            return w.writeAll("extra const qualifier");
        },
        .extra_volatile_qualifier => {
            return w.writeAll("extra volatile qualifier");
        },
        .ptr_mod_on_array_child_type => {
            return w.print("pointer modifier '{s}' not allowed on array child type", .{
                tree.tokenTag(parse_error.token).symbol(),
            });
        },
        .invalid_bit_range => {
            return w.writeAll("bit range not allowed on slices and arrays");
        },
        .same_line_doc_comment => {
            return w.writeAll("same line documentation comment");
        },
        .unattached_doc_comment => {
            return w.writeAll("unattached documentation comment");
        },
        .test_doc_comment => {
            return w.writeAll("documentation comments cannot be attached to tests");
        },
        .comptime_doc_comment => {
            return w.writeAll("documentation comments cannot be attached to comptime blocks");
        },
        .varargs_nonfinal => {
            return w.writeAll("function prototype has parameter after varargs");
        },
        .expected_continue_expr => {
            return w.writeAll("expected ':' before while continue expression");
        },

        .expected_semi_after_decl => {
            return w.writeAll("expected ';' after declaration");
        },
        .expected_semi_after_stmt => {
            return w.writeAll("expected ';' after statement");
        },
        .expected_comma_after_field => {
            return w.writeAll("expected ',' after field");
        },
        .expected_comma_after_arg => {
            return w.writeAll("expected ',' after argument");
        },
        .expected_comma_after_param => {
            return w.writeAll("expected ',' after parameter");
        },
        .expected_comma_after_initializer => {
            return w.writeAll("expected ',' after initializer");
        },
        .expected_comma_after_switch_prong => {
            return w.writeAll("expected ',' after switch prong");
        },
        .expected_comma_after_for_operand => {
            return w.writeAll("expected ',' after for operand");
        },
        .expected_comma_after_capture => {
            return w.writeAll("expected ',' after for capture");
        },
        .expected_initializer => {
            return w.writeAll("expected field initializer");
        },
        .mismatched_binary_op_whitespace => {
            return w.print("binary operator '{s}' has whitespace on one side, but not the other", .{tree.tokenTag(parse_error.token).lexeme().?});
        },
        .invalid_ampersand_ampersand => {
            return w.writeAll("ambiguous use of '&&'; use 'and' for logical AND, or change whitespace to ' & &' for bitwise AND");
        },
        .c_style_container => {
            return w.print("'{s} {s}' is invalid", .{
                parse_error.extra.expected_tag.symbol(), tree.tokenSlice(parse_error.token),
            });
        },
        .zig_style_container => {
            return w.print("to declare a container do 'const {s} = {s}'", .{
                tree.tokenSlice(parse_error.token), parse_error.extra.expected_tag.symbol(),
            });
        },
        .previous_field => {
            return w.writeAll("field before declarations here");
        },
        .next_field => {
            return w.writeAll("field after declarations here");
        },
        .expected_var_const => {
            return w.writeAll("expected 'var' or 'const' before variable declaration");
        },
        .wrong_equal_var_decl => {
            return w.writeAll("variable initialized with '==' instead of '='");
        },
        .var_const_decl => {
            return w.writeAll("use 'var' or 'const' to declare variable");
        },
        .extra_for_capture => {
            return w.writeAll("extra capture in for loop");
        },
        .for_input_not_captured => {
            return w.writeAll("for input is not captured");
        },

        .invalid_byte => {
            const tok_slice = tree.source[tree.tokens.items(.start)[parse_error.token]..];
            return w.print("{s} contains invalid byte: '{f}'", .{
                switch (tok_slice[0]) {
                    '\'' => "character literal",
                    '"', '\\' => "string literal",
                    '/' => "comment",
                    else => unreachable,
                },
                std.zig.fmtChar(tok_slice[parse_error.extra.offset]),
            });
        },

        .expected_token => {
            const found_tag = tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev));
            const expected_symbol = parse_error.extra.expected_tag.symbol();
            switch (found_tag) {
                .invalid => return w.print("expected '{s}', found invalid bytes", .{
                    expected_symbol,
                }),
                else => return w.print("expected '{s}', found '{s}'", .{
                    expected_symbol, found_tag.symbol(),
                }),
            }
        },
    }
}