Commit dee7804a81

LemonBoy <thatlemon@gmail.com>
2020-01-31 15:47:48
fmt: Fix logic to find the argument list closing )
Closes #4341
1 parent a62b4f2
Changed files (2)
lib/std/zig/parser_test.zig
@@ -1,3 +1,41 @@
+test "zig fmt: trailing comma in fn parameter list" {
+    try testCanonical(
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) i32 {}
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) align(8) i32 {}
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) linksection(".text") i32 {}
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) callconv(.C) i32 {}
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) align(8) linksection(".text") i32 {}
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) align(8) callconv(.C) i32 {}
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) align(8) linksection(".text") callconv(.C) i32 {}
+        \\pub fn f(
+        \\    a: i32,
+        \\    b: i32,
+        \\) linksection(".text") callconv(.C) i32 {}
+        \\
+    );
+}
+
 // TODO: Remove condition after deprecating 'typeOf'. See https://github.com/ziglang/zig/issues/1348
 test "zig fmt: change @typeOf to @TypeOf" {
     try testTransform(
lib/std/zig/render.zig
@@ -1344,11 +1344,22 @@ fn renderExpression(
                 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
                 break :blk tree.nextToken(fn_proto.fn_token);
             };
-
-            const rparen = tree.prevToken(switch (fn_proto.return_type) {
-                ast.Node.FnProto.ReturnType.Explicit => |node| node.firstToken(),
-                ast.Node.FnProto.ReturnType.InferErrorSet => |node| tree.prevToken(node.firstToken()),
+            assert(tree.tokens.at(lparen).id == .LParen);
+
+            const rparen = tree.prevToken(
+            // the first token for the annotation expressions is the left
+            // parenthesis, hence the need for two prevToken
+            if (fn_proto.align_expr) |align_expr|
+                tree.prevToken(tree.prevToken(align_expr.firstToken()))
+            else if (fn_proto.section_expr) |section_expr|
+                tree.prevToken(tree.prevToken(section_expr.firstToken()))
+            else if (fn_proto.callconv_expr) |callconv_expr|
+                tree.prevToken(tree.prevToken(callconv_expr.firstToken()))
+            else switch (fn_proto.return_type) {
+                .Explicit => |node| node.firstToken(),
+                .InferErrorSet => |node| tree.prevToken(node.firstToken()),
             });
+            assert(tree.tokens.at(rparen).id == .RParen);
 
             const src_params_trailing_comma = blk: {
                 const maybe_comma = tree.tokens.at(rparen - 1).id;