authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-28 21:18:41-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-28 21:18:41-04:00
log354ab1c5c8ec62c485fbc297817a0e70ab625a71
treea6f959c08e1ff0263f5ad0e150ecc9bf1348eb1f
parent530da363521ca7c3b22e6451874cef24d49683cc

zig fmt: render fn decl with trailing comma 1 line per param


2 files changed, 95 insertions(+), 78 deletions(-)

std/zig/parser_test.zig+14-1
...@@ -1,3 +1,15 @@...@@ -1,3 +1,15 @@
1test "zig fmt: fn decl with trailing comma" {
2 try testTransform(
3 \\fn foo(a: i32, b: i32,) void {}
4 ,
5 \\fn foo(
6 \\ a: i32,
7 \\ b: i32,
8 \\) void {}
9 \\
10 );
11}
12
1test "zig fmt: enum decl with no trailing comma" {13test "zig fmt: enum decl with no trailing comma" {
2 try testTransform(14 try testTransform(
3 \\const StrLitKind = enum {Normal, C};15 \\const StrLitKind = enum {Normal, C};
...@@ -247,7 +259,8 @@ test "zig fmt: switch cases trailing comma" {...@@ -247,7 +259,8 @@ test "zig fmt: switch cases trailing comma" {
247 \\ switch (x) {259 \\ switch (x) {
248 \\ 1, 2, 3 => {},260 \\ 1, 2, 3 => {},
249 \\ 4,261 \\ 4,
250 \\ 5, => {},262 \\ 5,
263 \\ => {},
251 \\ 6...8 => {},264 \\ 6...8 => {},
252 \\ else => {},265 \\ else => {},
253 \\ }266 \\ }
std/zig/render.zig+81-77
...@@ -102,7 +102,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i...@@ -102,7 +102,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
102 }102 }
103 try renderToken(tree, stream, field.name_token, indent, Space.None); // name103 try renderToken(tree, stream, field.name_token, indent, Space.None); // name
104 try renderToken(tree, stream, tree.nextToken(field.name_token), indent, Space.Space); // :104 try renderToken(tree, stream, tree.nextToken(field.name_token), indent, Space.Space); // :
105 try renderTrailingComma(allocator, stream, tree, indent, field.type_expr, Space.Newline); // type,105 try renderExpression(allocator, stream, tree, indent, field.type_expr, Space.Comma); // type,
106 },106 },
107107
108 ast.Node.Id.UnionTag => {108 ast.Node.Id.UnionTag => {
...@@ -111,7 +111,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i...@@ -111,7 +111,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
111 try renderDocComments(tree, stream, tag, indent);111 try renderDocComments(tree, stream, tag, indent);
112112
113 if (tag.type_expr == null and tag.value_expr == null) {113 if (tag.type_expr == null and tag.value_expr == null) {
114 return renderTokenAndTrailingComma(tree, stream, tag.name_token, indent, Space.Newline); // name,114 return renderToken(tree, stream, tag.name_token, indent, Space.Comma); // name,
115 }115 }
116116
117 if (tag.type_expr == null) {117 if (tag.type_expr == null) {
...@@ -124,7 +124,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i...@@ -124,7 +124,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
124 try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, Space.Space); // :124 try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, Space.Space); // :
125125
126 if (tag.value_expr == null) {126 if (tag.value_expr == null) {
127 return renderTrailingComma(allocator, stream, tree, indent, type_expr, Space.Newline); // type,127 return renderExpression(allocator, stream, tree, indent, type_expr, Space.Comma); // type,
128 } else {128 } else {
129 try renderExpression(allocator, stream, tree, indent, type_expr, Space.Space); // type129 try renderExpression(allocator, stream, tree, indent, type_expr, Space.Space); // type
130 }130 }
...@@ -132,7 +132,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i...@@ -132,7 +132,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
132132
133 const value_expr = ??tag.value_expr;133 const value_expr = ??tag.value_expr;
134 try renderToken(tree, stream, tree.prevToken(value_expr.firstToken()), indent, Space.Space); // =134 try renderToken(tree, stream, tree.prevToken(value_expr.firstToken()), indent, Space.Space); // =
135 try renderTrailingComma(allocator, stream, tree, indent, value_expr, Space.Newline); // value,135 try renderExpression(allocator, stream, tree, indent, value_expr, Space.Comma); // value,
136 },136 },
137137
138 ast.Node.Id.EnumTag => {138 ast.Node.Id.EnumTag => {
...@@ -144,9 +144,9 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i...@@ -144,9 +144,9 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
144 try renderToken(tree, stream, tag.name_token, indent, Space.Space); // name144 try renderToken(tree, stream, tag.name_token, indent, Space.Space); // name
145145
146 try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, Space.Space); // =146 try renderToken(tree, stream, tree.nextToken(tag.name_token), indent, Space.Space); // =
147 try renderTrailingComma(allocator, stream, tree, indent, value, Space.Newline);147 try renderExpression(allocator, stream, tree, indent, value, Space.Comma);
148 } else {148 } else {
149 try renderTokenAndTrailingComma(tree, stream, tag.name_token, indent, Space.Newline); // name149 try renderToken(tree, stream, tag.name_token, indent, Space.Comma); // name
150 }150 }
151 },151 },
152152
...@@ -413,7 +413,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -413,7 +413,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
413 try renderToken(tree, stream, comma, new_indent, Space.Newline); // ,413 try renderToken(tree, stream, comma, new_indent, Space.Newline); // ,
414 try renderExtraNewline(tree, stream, next_node.*);414 try renderExtraNewline(tree, stream, next_node.*);
415 } else {415 } else {
416 try renderTrailingComma(allocator, stream, tree, param_node_new_indent, param_node.*, Space.Newline);416 try renderExpression(allocator, stream, tree, param_node_new_indent, param_node.*, Space.Comma);
417 try stream.writeByteNTimes(' ', indent);417 try stream.writeByteNTimes(' ', indent);
418 try renderToken(tree, stream, suffix_op.rtoken, indent, space);418 try renderToken(tree, stream, suffix_op.rtoken, indent, space);
419 return;419 return;
...@@ -540,7 +540,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -540,7 +540,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
540540
541 try renderExtraNewline(tree, stream, next_field_init.*);541 try renderExtraNewline(tree, stream, next_field_init.*);
542 } else {542 } else {
543 try renderTrailingComma(allocator, stream, tree, new_indent, field_init.*, Space.Newline);543 try renderExpression(allocator, stream, tree, new_indent, field_init.*, Space.Comma);
544 }544 }
545 }545 }
546546
...@@ -625,7 +625,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -625,7 +625,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
625 try renderExtraNewline(tree, stream, next_expr.*);625 try renderExtraNewline(tree, stream, next_expr.*);
626 try stream.writeByteNTimes(' ', new_indent);626 try stream.writeByteNTimes(' ', new_indent);
627 } else {627 } else {
628 try renderTrailingComma(allocator, stream, tree, new_indent, expr.*, Space.Newline); // ,628 try renderExpression(allocator, stream, tree, new_indent, expr.*, Space.Comma); // ,
629 }629 }
630 }630 }
631 try stream.writeByteNTimes(' ', indent);631 try stream.writeByteNTimes(' ', indent);
...@@ -892,7 +892,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -892,7 +892,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
892892
893 try renderExtraNewline(tree, stream, next_node.*);893 try renderExtraNewline(tree, stream, next_node.*);
894 } else {894 } else {
895 try renderTrailingComma(allocator, stream, tree, new_indent, node.*, Space.Newline);895 try renderExpression(allocator, stream, tree, new_indent, node.*, Space.Comma);
896 }896 }
897 }897 }
898898
...@@ -976,29 +976,55 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -976,29 +976,55 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
976 try renderExpression(allocator, stream, tree, indent, &async_attr.base, Space.Space);976 try renderExpression(allocator, stream, tree, indent, &async_attr.base, Space.Space);
977 }977 }
978978
979 if (fn_proto.name_token) |name_token| blk: {979 const lparen = if (fn_proto.name_token) |name_token| blk: {
980 try renderToken(tree, stream, fn_proto.fn_token, indent, Space.Space); // fn980 try renderToken(tree, stream, fn_proto.fn_token, indent, Space.Space); // fn
981 try renderToken(tree, stream, name_token, indent, Space.None); // name981 try renderToken(tree, stream, name_token, indent, Space.None); // name
982 try renderToken(tree, stream, tree.nextToken(name_token), indent, Space.None); // (982 break :blk tree.nextToken(name_token);
983 } else blk: {983 } else blk: {
984 try renderToken(tree, stream, fn_proto.fn_token, indent, Space.None); // fn984 try renderToken(tree, stream, fn_proto.fn_token, indent, Space.None); // fn
985 try renderToken(tree, stream, tree.nextToken(fn_proto.fn_token), indent, Space.None); // (985 break :blk tree.nextToken(fn_proto.fn_token);
986 }986 };
987
988 var it = fn_proto.params.iterator(0);
989 while (it.next()) |param_decl_node| {
990 try renderParamDecl(allocator, stream, tree, indent, param_decl_node.*);
991
992 if (it.peek() != null) {
993 const comma = tree.nextToken(param_decl_node.*.lastToken());
994 try renderToken(tree, stream, comma, indent, Space.Space); // ,
995 }
996 }
997987
998 const rparen = tree.prevToken(switch (fn_proto.return_type) {988 const rparen = tree.prevToken(switch (fn_proto.return_type) {
999 ast.Node.FnProto.ReturnType.Explicit => |node| node.firstToken(),989 ast.Node.FnProto.ReturnType.Explicit => |node| node.firstToken(),
1000 ast.Node.FnProto.ReturnType.InferErrorSet => |node| tree.prevToken(node.firstToken()),990 ast.Node.FnProto.ReturnType.InferErrorSet => |node| tree.prevToken(node.firstToken()),
1001 });991 });
992
993 const src_params_trailing_comma = blk: {
994 const maybe_comma = tree.prevToken(rparen);
995 break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
996 };
997 const src_params_same_line = blk: {
998 const loc = tree.tokenLocation(tree.tokens.at(lparen).end, rparen);
999 break :blk loc.line == 0;
1000 };
1001
1002 if (!src_params_trailing_comma and src_params_same_line) {
1003 try renderToken(tree, stream, lparen, indent, Space.None); // (
1004
1005 // render all on one line, no trailing comma
1006 var it = fn_proto.params.iterator(0);
1007 while (it.next()) |param_decl_node| {
1008 try renderParamDecl(allocator, stream, tree, indent, param_decl_node.*, Space.None);
1009
1010 if (it.peek() != null) {
1011 const comma = tree.nextToken(param_decl_node.*.lastToken());
1012 try renderToken(tree, stream, comma, indent, Space.Space); // ,
1013 }
1014 }
1015 } else {
1016 // one param per line
1017 const new_indent = indent + indent_delta;
1018 try renderToken(tree, stream, lparen, new_indent, Space.Newline); // (
1019
1020 var it = fn_proto.params.iterator(0);
1021 while (it.next()) |param_decl_node| {
1022 try stream.writeByteNTimes(' ', new_indent);
1023 try renderParamDecl(allocator, stream, tree, indent, param_decl_node.*, Space.Comma);
1024 }
1025 try stream.writeByteNTimes(' ', indent);
1026 }
1027
1002 try renderToken(tree, stream, rparen, indent, Space.Space); // )1028 try renderToken(tree, stream, rparen, indent, Space.Space); // )
10031029
1004 if (fn_proto.align_expr) |align_expr| {1030 if (fn_proto.align_expr) |align_expr| {
...@@ -1064,7 +1090,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -1064,7 +1090,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
1064 var it = switch_node.cases.iterator(0);1090 var it = switch_node.cases.iterator(0);
1065 while (it.next()) |node| {1091 while (it.next()) |node| {
1066 try stream.writeByteNTimes(' ', new_indent);1092 try stream.writeByteNTimes(' ', new_indent);
1067 try renderExpression(allocator, stream, tree, new_indent, node.*, Space.Newline);1093 try renderExpression(allocator, stream, tree, new_indent, node.*, Space.Comma);
10681094
1069 if (it.peek()) |next_node| {1095 if (it.peek()) |next_node| {
1070 try renderExtraNewline(tree, stream, next_node.*);1096 try renderExtraNewline(tree, stream, next_node.*);
...@@ -1110,7 +1136,8 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -1110,7 +1136,8 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
1110 try renderExtraNewline(tree, stream, next_node.*);1136 try renderExtraNewline(tree, stream, next_node.*);
1111 try stream.writeByteNTimes(' ', indent);1137 try stream.writeByteNTimes(' ', indent);
1112 } else {1138 } else {
1113 try renderTrailingComma(allocator, stream, tree, indent, node.*, Space.Space);1139 try renderExpression(allocator, stream, tree, indent, node.*, Space.Comma);
1140 try stream.writeByteNTimes(' ', indent);
1114 break;1141 break;
1115 }1142 }
1116 }1143 }
...@@ -1122,7 +1149,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind...@@ -1122,7 +1149,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
1122 try renderExpression(allocator, stream, tree, indent, payload, Space.Space);1149 try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
1123 }1150 }
11241151
1125 try renderTrailingComma(allocator, stream, tree, indent, switch_case.expr, space);1152 try renderExpression(allocator, stream, tree, indent, switch_case.expr, space);
1126 },1153 },
1127 ast.Node.Id.SwitchElse => {1154 ast.Node.Id.SwitchElse => {
1128 const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);1155 const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);
...@@ -1543,7 +1570,7 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent...@@ -1543,7 +1570,7 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent
1543 try renderToken(tree, stream, var_decl.semicolon_token, indent, Space.Newline);1570 try renderToken(tree, stream, var_decl.semicolon_token, indent, Space.Newline);
1544}1571}
15451572
1546fn renderParamDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {1573fn renderParamDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node, space: Space) (@typeOf(stream).Child.Error || Error)!void {
1547 const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);1574 const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);
15481575
1549 if (param_decl.comptime_token) |comptime_token| {1576 if (param_decl.comptime_token) |comptime_token| {
...@@ -1557,9 +1584,9 @@ fn renderParamDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde...@@ -1557,9 +1584,9 @@ fn renderParamDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde
1557 try renderToken(tree, stream, tree.nextToken(name_token), indent, Space.Space); // :1584 try renderToken(tree, stream, tree.nextToken(name_token), indent, Space.Space); // :
1558 }1585 }
1559 if (param_decl.var_args_token) |var_args_token| {1586 if (param_decl.var_args_token) |var_args_token| {
1560 try renderToken(tree, stream, var_args_token, indent, Space.None);1587 try renderToken(tree, stream, var_args_token, indent, space);
1561 } else {1588 } else {
1562 try renderExpression(allocator, stream, tree, indent, param_decl.type_node, Space.None);1589 try renderExpression(allocator, stream, tree, indent, param_decl.type_node, space);
1563 }1590 }
1564}1591}
15651592
...@@ -1586,6 +1613,7 @@ fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde...@@ -1586,6 +1613,7 @@ fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde
1586const Space = enum {1613const Space = enum {
1587 None,1614 None,
1588 Newline,1615 Newline,
1616 Comma,
1589 Space,1617 Space,
1590 NoNewline,1618 NoNewline,
1591 NoIndent,1619 NoIndent,
...@@ -1596,9 +1624,27 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent...@@ -1596,9 +1624,27 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
1596 var token = tree.tokens.at(token_index);1624 var token = tree.tokens.at(token_index);
1597 try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(token), " "));1625 try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(token), " "));
15981626
1599 if (space == Space.NoComment) return;
1600
1601 var next_token = tree.tokens.at(token_index + 1);1627 var next_token = tree.tokens.at(token_index + 1);
1628
1629 switch (space) {
1630 Space.NoComment => return,
1631 Space.Comma => switch (next_token.id) {
1632 Token.Id.Comma => return renderToken(tree, stream, token_index + 1, indent, Space.Newline),
1633 Token.Id.LineComment => {
1634 try stream.write(", ");
1635 return renderToken(tree, stream, token_index + 1, indent, Space.Newline);
1636 },
1637 else => {
1638 if (tree.tokens.at(token_index + 2).id == Token.Id.MultilineStringLiteralLine) {
1639 return stream.write(",");
1640 } else {
1641 return stream.write(",\n");
1642 }
1643 },
1644 },
1645 else => {},
1646 }
1647
1602 if (next_token.id != Token.Id.LineComment) {1648 if (next_token.id != Token.Id.LineComment) {
1603 switch (space) {1649 switch (space) {
1604 Space.None, Space.NoNewline, Space.NoIndent => return,1650 Space.None, Space.NoNewline, Space.NoIndent => return,
...@@ -1610,7 +1656,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent...@@ -1610,7 +1656,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
1610 }1656 }
1611 },1657 },
1612 Space.Space => return stream.writeByte(' '),1658 Space.Space => return stream.writeByte(' '),
1613 Space.NoComment => unreachable,1659 Space.NoComment, Space.Comma => unreachable,
1614 }1660 }
1615 }1661 }
16161662
...@@ -1648,7 +1694,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent...@@ -1648,7 +1694,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
1648 }1694 }
1649 },1695 },
1650 Space.NoNewline => {},1696 Space.NoNewline => {},
1651 Space.NoComment => unreachable,1697 Space.NoComment, Space.Comma => unreachable,
1652 }1698 }
1653 return;1699 return;
1654 }1700 }
...@@ -1685,7 +1731,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent...@@ -1685,7 +1731,7 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
1685 try stream.writeByteNTimes(' ', next_line_indent);1731 try stream.writeByteNTimes(' ', next_line_indent);
1686 },1732 },
1687 Space.NoNewline => {},1733 Space.NoNewline => {},
1688 Space.NoComment => unreachable,1734 Space.NoComment, Space.Comma => unreachable,
1689 }1735 }
1690 return;1736 return;
1691 }1737 }
...@@ -1701,45 +1747,3 @@ fn renderDocComments(tree: &ast.Tree, stream: var, node: var, indent: usize) (@t...@@ -1701,45 +1747,3 @@ fn renderDocComments(tree: &ast.Tree, stream: var, node: var, indent: usize) (@t
1701 try stream.writeByteNTimes(' ', indent);1747 try stream.writeByteNTimes(' ', indent);
1702 }1748 }
1703}1749}
1704
1705fn renderTrailingComma(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node,
1706 space: Space) (@typeOf(stream).Child.Error || Error)!void
1707{
1708 const end_token = base.lastToken() + 1;
1709 switch (tree.tokens.at(end_token).id) {
1710 Token.Id.Comma => {
1711 try renderExpression(allocator, stream, tree, indent, base, Space.None);
1712 try renderToken(tree, stream, end_token, indent, space); // ,
1713 },
1714 Token.Id.LineComment => {
1715 try renderExpression(allocator, stream, tree, indent, base, Space.NoComment);
1716 try stream.write(", ");
1717 try renderToken(tree, stream, end_token, indent, space);
1718 },
1719 else => {
1720 try renderExpression(allocator, stream, tree, indent, base, Space.None);
1721 try stream.write(",\n");
1722 assert(space == Space.Newline);
1723 },
1724 }
1725}
1726
1727fn renderTokenAndTrailingComma(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, space: Space) (@typeOf(stream).Child.Error || Error)!void {
1728 const end_token = token_index + 1;
1729 switch (tree.tokens.at(end_token).id) {
1730 Token.Id.Comma => {
1731 try renderToken(tree, stream, token_index, indent, Space.None);
1732 try renderToken(tree, stream, end_token, indent, space); // ,
1733 },
1734 Token.Id.LineComment => {
1735 try renderToken(tree, stream, token_index, indent, Space.NoComment);
1736 try stream.write(", ");
1737 try renderToken(tree, stream, end_token, indent, space);
1738 },
1739 else => {
1740 try renderToken(tree, stream, token_index, indent, Space.None);
1741 try stream.write(",\n");
1742 assert(space == Space.Newline);
1743 },
1744 }
1745}