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(
16141614 return renderParamList(r, builtin_token + 1, params, space);
16151615}
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
16171638fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void {
16181639 const tree = r.tree;
16191640 const ais = r.ais;
......@@ -1674,8 +1695,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi
16741695
16751696 // The params list is a sparse set that does *not* include anytype or ... parameters.
16761697
1677 const trailing_comma = tree.tokenTag(rparen - 1) == .comma;
1678 if (!trailing_comma and !hasComment(tree, lparen, rparen)) {
1698 if (isOneLineFnProto(tree, fn_proto, lparen, rparen)) {
16791699 // Render all on one line, no trailing comma.
16801700 try renderToken(r, lparen, .none); // (
16811701
......@@ -1684,10 +1704,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi
16841704 while (true) {
16851705 last_param_token += 1;
16861706 switch (tree.tokenTag(last_param_token)) {
1687 .doc_comment => {
1688 try renderToken(r, last_param_token, .newline);
1689 continue;
1690 },
1707 .doc_comment => unreachable,
16911708 .ellipsis3 => {
16921709 try renderToken(r, last_param_token, .none); // ...
16931710 break;
lib/std/zig/parser_test.zig+41
......@@ -6382,6 +6382,47 @@ test "zig fmt: whitespace with multiline strings" {
63826382 );
63836383}
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
63856426test "recovery: top level" {
63866427 try testError(
63876428 \\test "" {inline}