diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 72846b333c..7b0380dfaf 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -258,6 +258,11 @@ pub const Tree = struct { token_tags[parse_error.token].symbol(), }); }, + .expected_container => { + return stream.print("expected a struct, enum or union, found '{s}'", .{ + token_tags[parse_error.token].symbol(), + }); + }, .extra_align_qualifier => { return stream.writeAll("extra align qualifier"); }, @@ -441,10 +446,27 @@ pub const Tree = struct { .call, .call_comma, .switch_range, - .fn_decl, .error_union, => n = datas[n].lhs, + .fn_decl => { + var i = main_tokens[n]; // fn token + while (i > 0) { + i -= 1; + switch (token_tags[i]) { + .keyword_extern, + .keyword_export, + .keyword_pub, + .keyword_threadlocal, + .string_literal, + => continue, + + else => return i + 1 - end_offset, + } + } + return i - end_offset; + }, + .async_call_one, .async_call_one_comma, .async_call, @@ -2338,6 +2360,7 @@ pub const Error = struct { expected_var_decl, expected_var_decl_or_fn, expected_loop_payload, + expected_container, extra_align_qualifier, extra_allowzero_qualifier, extra_const_qualifier, diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index fd142b8765..f5672bedf9 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -3627,7 +3627,10 @@ const Parser = struct { break :blk null_node; } }, - else => unreachable, + else => { + p.tok_i -= 1; + return p.fail(.expected_container); + }, }; _ = try p.expectToken(.l_brace); const members = try p.parseContainerMembers(); diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 9748c07557..eecc4f769a 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -2399,20 +2399,20 @@ test "zig fmt: comments before test decl" { ); } -//test "zig fmt: preserve spacing" { -// try testCanonical( -// \\const std = @import("std"); -// \\ -// \\pub fn main() !void { -// \\ var stdout_file = std.io.getStdOut; -// \\ var stdout_file = std.io.getStdOut; -// \\ -// \\ var stdout_file = std.io.getStdOut; -// \\ var stdout_file = std.io.getStdOut; -// \\} -// \\ -// ); -//} +test "zig fmt: preserve spacing" { + try testCanonical( + \\const std = @import("std"); + \\ + \\pub fn main() !void { + \\ var stdout_file = std.io.getStdOut; + \\ var stdout_file = std.io.getStdOut; + \\ + \\ var stdout_file = std.io.getStdOut; + \\ var stdout_file = std.io.getStdOut; + \\} + \\ + ); +} //test "zig fmt: return types" { // try testCanonical( @@ -2431,27 +2431,27 @@ test "zig fmt: imports" { ); } -//test "zig fmt: global declarations" { -// try testCanonical( -// \\const a = b; -// \\pub const a = b; -// \\var a = b; -// \\pub var a = b; -// \\const a: i32 = b; -// \\pub const a: i32 = b; -// \\var a: i32 = b; -// \\pub var a: i32 = b; -// \\extern const a: i32 = b; -// \\pub extern const a: i32 = b; -// \\extern var a: i32 = b; -// \\pub extern var a: i32 = b; -// \\extern "a" const a: i32 = b; -// \\pub extern "a" const a: i32 = b; -// \\extern "a" var a: i32 = b; -// \\pub extern "a" var a: i32 = b; -// \\ -// ); -//} +test "zig fmt: global declarations" { + try testCanonical( + \\const a = b; + \\pub const a = b; + \\var a = b; + \\pub var a = b; + \\const a: i32 = b; + \\pub const a: i32 = b; + \\var a: i32 = b; + \\pub var a: i32 = b; + \\extern const a: i32 = b; + \\pub extern const a: i32 = b; + \\extern var a: i32 = b; + \\pub extern var a: i32 = b; + \\extern "a" const a: i32 = b; + \\pub extern "a" const a: i32 = b; + \\extern "a" var a: i32 = b; + \\pub extern "a" var a: i32 = b; + \\ + ); +} test "zig fmt: extern declaration" { try testCanonical( @@ -2680,23 +2680,23 @@ test "zig fmt: functions" { ); } -//test "zig fmt: multiline string" { -// try testCanonical( -// \\test "" { -// \\ const s1 = -// \\ \\one -// \\ \\two) -// \\ \\three -// \\ ; -// \\ const s3 = // hi -// \\ \\one -// \\ \\two) -// \\ \\three -// \\ ; -// \\} -// \\ -// ); -//} +test "zig fmt: multiline string" { + try testCanonical( + \\test "" { + \\ const s1 = + \\ \\one + \\ \\two) + \\ \\three + \\ ; + \\ const s3 = // hi + \\ \\one + \\ \\two) + \\ \\three + \\ ; + \\} + \\ + ); +} test "zig fmt: values" { try testCanonical( @@ -3578,15 +3578,14 @@ test "zig fmt: comment after empty comment" { // ); //} -//test "zig fmt: extern without container keyword returns error" { -// try testError( -// \\const container = extern {}; -// \\ -// , &[_]Error{ -// .expected_expr, -// .expected_var_decl_or_fn, -// }); -//} +test "zig fmt: extern without container keyword returns error" { + try testError( + \\const container = extern {}; + \\ + , &[_]Error{ + .expected_container, + }); +} test "zig fmt: same line doc comment returns error" { try testError( @@ -3706,16 +3705,16 @@ test "zig fmt: C var args" { // ); //} -//test "zig fmt: Don't add extra newline after if" { -// try testCanonical( -// \\pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void { -// \\ if (cwd().symLink(existing_path, new_path, .{})) { -// \\ return; -// \\ } -// \\} -// \\ -// ); -//} +test "zig fmt: Don't add extra newline after if" { + try testCanonical( + \\pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: []const u8) !void { + \\ if (cwd().symLink(existing_path, new_path, .{})) { + \\ return; + \\ } + \\} + \\ + ); +} //test "zig fmt: comments in ternary ifs" { // try testCanonical( diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index cbed4ac14d..83ff56febe 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -873,7 +873,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!vo try renderToken(ais, tree, extern_export_token, Space.space); // extern if (var_decl.lib_name) |lib_name| { - try renderExpression(ais, tree, lib_name, Space.space); // "lib" + try renderToken(ais, tree, lib_name, Space.space); // "lib" } }