Commit 928790364a

Veikka Tuominen <git@vexu.eu>
2021-02-22 16:39:41
zig fmt: correct Node.firstToken for .fn_decl, add error for missing container
1 parent 69d5a10
Changed files (4)
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,
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();
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(
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"
         }
     }