authorgravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2025-07-28 16:39:20-04:00
committergravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2026-03-12 17:23:19-04:00
logb0db0ef4e197eb44faa0e343874dfc8f810324ca
tree8e9ac84ae394989e10d5f184e614bda5ef741284
parent472992ae4553d8057e81c75026923df18e30a9a8

zig fmt: fix doc comments on fn paramaters without comma


2 files changed, 64 insertions(+), 6 deletions(-)

lib/std/zig/Ast/Render.zig+23-6
...@@ -1614,6 +1614,27 @@ fn renderBuiltinCall(...@@ -1614,6 +1614,27 @@ fn renderBuiltinCall(
1614 return renderParamList(r, builtin_token + 1, params, space);1614 return renderParamList(r, builtin_token + 1, params, space);
1615}1615}
16161616
1617fn isOneLineFnProto(
1618 tree: Ast,
1619 fn_proto: Ast.full.FnProto,
1620 lparen: Ast.TokenIndex,
1621 rparen: Ast.TokenIndex,
1622) bool {
1623 const trailing_comma = tree.tokenTag(rparen - 1) == .comma;
1624 if (trailing_comma or hasComment(tree, lparen, rparen))
1625 return false;
1626
1627 // Check that there are no doc comments
1628 var after_last_param = lparen + 1;
1629 for (fn_proto.ast.params) |expr| {
1630 // Looking before each param is insufficient since anytype is not included in `params`
1631 if (hasDocComment(tree, after_last_param, tree.firstToken(expr)))
1632 return false;
1633 after_last_param = tree.lastToken(expr) + 1;
1634 }
1635 return !hasDocComment(tree, after_last_param, rparen);
1636}
1637
1617fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void {1638fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void {
1618 const tree = r.tree;1639 const tree = r.tree;
1619 const ais = r.ais;1640 const ais = r.ais;
...@@ -1674,8 +1695,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi...@@ -1674,8 +1695,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi
16741695
1675 // The params list is a sparse set that does *not* include anytype or ... parameters.1696 // The params list is a sparse set that does *not* include anytype or ... parameters.
16761697
1677 const trailing_comma = tree.tokenTag(rparen - 1) == .comma;1698 if (isOneLineFnProto(tree, fn_proto, lparen, rparen)) {
1678 if (!trailing_comma and !hasComment(tree, lparen, rparen)) {
1679 // Render all on one line, no trailing comma.1699 // Render all on one line, no trailing comma.
1680 try renderToken(r, lparen, .none); // (1700 try renderToken(r, lparen, .none); // (
16811701
...@@ -1684,10 +1704,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi...@@ -1684,10 +1704,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi
1684 while (true) {1704 while (true) {
1685 last_param_token += 1;1705 last_param_token += 1;
1686 switch (tree.tokenTag(last_param_token)) {1706 switch (tree.tokenTag(last_param_token)) {
1687 .doc_comment => {1707 .doc_comment => unreachable,
1688 try renderToken(r, last_param_token, .newline);
1689 continue;
1690 },
1691 .ellipsis3 => {1708 .ellipsis3 => {
1692 try renderToken(r, last_param_token, .none); // ...1709 try renderToken(r, last_param_token, .none); // ...
1693 break;1710 break;
lib/std/zig/parser_test.zig+41
...@@ -6382,6 +6382,47 @@ test "zig fmt: whitespace with multiline strings" {...@@ -6382,6 +6382,47 @@ test "zig fmt: whitespace with multiline strings" {
6382 );6382 );
6383}6383}
63846384
6385test "zig fmt: doc comments on fn parameters" {
6386 try testTransform(
6387 \\extern fn foo(
6388 \\ /// Bitmap
6389 \\ active: u64
6390 \\) void;
6391 \\extern fn bar(
6392 \\ bits: u6,
6393 \\ /// Bitmap
6394 \\ active: u64
6395 \\) void;
6396 \\extern fn baz(
6397 \\ /// Bitmap
6398 \\ active: anytype
6399 \\) void;
6400 \\
6401 ,
6402 \\extern fn foo(
6403 \\ /// Bitmap
6404 \\ active: u64,
6405 \\) void;
6406 \\extern fn bar(
6407 \\ bits: u6,
6408 \\ /// Bitmap
6409 \\ active: u64,
6410 \\) void;
6411 \\extern fn baz(
6412 \\ /// Bitmap
6413 \\ active: anytype,
6414 \\) void;
6415 \\
6416 );
6417 try testCanonical(
6418 \\extern fn foo(x: struct {
6419 \\ /// Bitmap
6420 \\ active: u64,
6421 \\}) void;
6422 \\
6423 );
6424}
6425
6385test "recovery: top level" {6426test "recovery: top level" {
6386 try testError(6427 try testError(
6387 \\test "" {inline}6428 \\test "" {inline}