Function renderError [src]

Prototype

pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void

Parameters

tree: Astparse_error: Error

Source

pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !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 stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?"); }, .chained_comparison_operators => { return stream.writeAll("comparison operators cannot be chained"); }, .decl_between_fields => { return stream.writeAll("declarations are not allowed between container fields"); }, .expected_block => { return stream.print("expected block, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_block_or_assignment => { return stream.print("expected block or assignment, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_block_or_expr => { return stream.print("expected block or expression, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_block_or_field => { return stream.print("expected block or field, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_container_members => { return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{ tree.tokenTag(parse_error.token).symbol(), }); }, .expected_expr => { return stream.print("expected expression, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_expr_or_assignment => { return stream.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 stream.print("expected expression or var decl, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_fn => { return stream.print("expected function, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_inlinable => { return stream.print("expected 'while' or 'for', found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_labelable => { return stream.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_param_list => { return stream.print("expected parameter list, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_prefix_expr => { return stream.print("expected prefix expression, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_primary_type_expr => { return stream.print("expected primary type expression, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_pub_item => { return stream.writeAll("expected function or variable declaration after pub"); }, .expected_return_type => { return stream.print("expected return type expression, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_semi_or_else => { return stream.writeAll("expected ';' or 'else' after statement"); }, .expected_semi_or_lbrace => { return stream.writeAll("expected ';' or block after function prototype"); }, .expected_statement => { return stream.print("expected statement, found '{s}'", .{ tree.tokenTag(parse_error.token).symbol(), }); }, .expected_suffix_op => { return stream.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 stream.print("expected type expression, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_var_decl => { return stream.print("expected variable declaration, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_var_decl_or_fn => { return stream.print("expected variable declaration or function, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_loop_payload => { return stream.print("expected loop payload, found '{s}'", .{ tree.tokenTag(parse_error.token + @intFromBool(parse_error.token_is_prev)).symbol(), }); }, .expected_container => { return stream.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 stream.writeAll("extern functions have no body"); }, .extra_addrspace_qualifier => { return stream.writeAll("extra addrspace qualifier"); }, .extra_align_qualifier => { return stream.writeAll("extra align qualifier"); }, .extra_allowzero_qualifier => { return stream.writeAll("extra allowzero qualifier"); }, .extra_const_qualifier => { return stream.writeAll("extra const qualifier"); }, .extra_volatile_qualifier => { return stream.writeAll("extra volatile qualifier"); }, .ptr_mod_on_array_child_type => { return stream.print("pointer modifier '{s}' not allowed on array child type", .{ tree.tokenTag(parse_error.token).symbol(), }); }, .invalid_bit_range => { return stream.writeAll("bit range not allowed on slices and arrays"); }, .same_line_doc_comment => { return stream.writeAll("same line documentation comment"); }, .unattached_doc_comment => { return stream.writeAll("unattached documentation comment"); }, .test_doc_comment => { return stream.writeAll("documentation comments cannot be attached to tests"); }, .comptime_doc_comment => { return stream.writeAll("documentation comments cannot be attached to comptime blocks"); }, .varargs_nonfinal => { return stream.writeAll("function prototype has parameter after varargs"); }, .expected_continue_expr => { return stream.writeAll("expected ':' before while continue expression"); }, .expected_semi_after_decl => { return stream.writeAll("expected ';' after declaration"); }, .expected_semi_after_stmt => { return stream.writeAll("expected ';' after statement"); }, .expected_comma_after_field => { return stream.writeAll("expected ',' after field"); }, .expected_comma_after_arg => { return stream.writeAll("expected ',' after argument"); }, .expected_comma_after_param => { return stream.writeAll("expected ',' after parameter"); }, .expected_comma_after_initializer => { return stream.writeAll("expected ',' after initializer"); }, .expected_comma_after_switch_prong => { return stream.writeAll("expected ',' after switch prong"); }, .expected_comma_after_for_operand => { return stream.writeAll("expected ',' after for operand"); }, .expected_comma_after_capture => { return stream.writeAll("expected ',' after for capture"); }, .expected_initializer => { return stream.writeAll("expected field initializer"); }, .mismatched_binary_op_whitespace => { return stream.print("binary operator `{s}` has whitespace on one side, but not the other.", .{tree.tokenTag(parse_error.token).lexeme().?}); }, .invalid_ampersand_ampersand => { return stream.writeAll("ambiguous use of '&&'; use 'and' for logical AND, or change whitespace to ' & &' for bitwise AND"); }, .c_style_container => { return stream.print("'{s} {s}' is invalid", .{ parse_error.extra.expected_tag.symbol(), tree.tokenSlice(parse_error.token), }); }, .zig_style_container => { return stream.print("to declare a container do 'const {s} = {s}'", .{ tree.tokenSlice(parse_error.token), parse_error.extra.expected_tag.symbol(), }); }, .previous_field => { return stream.writeAll("field before declarations here"); }, .next_field => { return stream.writeAll("field after declarations here"); }, .expected_var_const => { return stream.writeAll("expected 'var' or 'const' before variable declaration"); }, .wrong_equal_var_decl => { return stream.writeAll("variable initialized with '==' instead of '='"); }, .var_const_decl => { return stream.writeAll("use 'var' or 'const' to declare variable"); }, .extra_for_capture => { return stream.writeAll("extra capture in for loop"); }, .for_input_not_captured => { return stream.writeAll("for input is not captured"); }, .invalid_byte => { const tok_slice = tree.source[tree.tokens.items(.start)[parse_error.token]..]; return stream.print("{s} contains invalid byte: '{'}'", .{ switch (tok_slice[0]) { '\'' => "character literal", '"', '\\' => "string literal", '/' => "comment", else => unreachable, }, std.zig.fmtEscapes(tok_slice[parse_error.extra.offset..][0..1]), }); }, .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 stream.print("expected '{s}', found invalid bytes", .{ expected_symbol, }), else => return stream.print("expected '{s}', found '{s}'", .{ expected_symbol, found_tag.symbol(), }), } }, } }