authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-05 20:38:30-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-05 20:38:30-07:00
logd898945786b527b09ef056099e923e946425e146
tree47db832a254a2278e393b7c10cc92dbd63fc008e
parent409ca8882939418b3d4cbd4be7a18daf1d4833aa

zig fmt: builtin call with trailing comma


4 files changed, 84 insertions(+), 64 deletions(-)

lib/std/zig/ast.zig+16-7
......@@ -234,7 +234,9 @@ pub const Tree = struct {
234234 .StringLiteral,
235235 .GroupedExpression,
236236 .BuiltinCallTwo,
237 .BuiltinCallTwoComma,
237238 .BuiltinCall,
239 .BuiltinCallComma,
238240 .ErrorSetDecl,
239241 .AnyType,
240242 .Comptime,
......@@ -474,6 +476,7 @@ pub const Tree = struct {
474476 .ErrorUnion,
475477 .IfSimple,
476478 .WhileSimple,
479 .FnDecl,
477480 => n = datas[n].rhs,
478481
479482 .FieldAccess,
......@@ -497,9 +500,7 @@ pub const Tree = struct {
497500 .EnumLiteral,
498501 => return main_tokens[n] + end_offset,
499502
500 .Call,
501 .BuiltinCall,
502 => {
503 .Call => {
503504 end_offset += 1; // for the rparen
504505 const params = tree.extraData(datas[n].rhs, Node.SubRange);
505506 if (params.end - params.start == 0) {
......@@ -526,6 +527,7 @@ pub const Tree = struct {
526527 .Block,
527528 .ContainerDecl,
528529 .TaggedUnion,
530 .BuiltinCall,
529531 => {
530532 end_offset += 1; // for the rbrace
531533 if (datas[n].rhs - datas[n].lhs == 0) {
......@@ -533,9 +535,12 @@ pub const Tree = struct {
533535 }
534536 n = tree.extra_data[datas[n].rhs - 1]; // last statement
535537 },
536 .ContainerDeclComma, .TaggedUnionComma => {
538 .ContainerDeclComma,
539 .TaggedUnionComma,
540 .BuiltinCallComma,
541 => {
537542 assert(datas[n].rhs - datas[n].lhs > 0);
538 end_offset += 2; // for the comma + rbrace
543 end_offset += 2; // for the comma + rbrace/rparen
539544 n = tree.extra_data[datas[n].rhs - 1]; // last member
540545 },
541546 .CallOne,
......@@ -565,11 +570,12 @@ pub const Tree = struct {
565570 }
566571 },
567572 .ArrayInitDotTwoComma,
573 .BuiltinCallTwoComma,
568574 .StructInitDotTwoComma,
569575 .ContainerDeclTwoComma,
570576 .TaggedUnionTwoComma,
571577 => {
572 end_offset += 2; // for the comma + rbrace
578 end_offset += 2; // for the comma + rbrace/rparen
573579 if (datas[n].rhs != 0) {
574580 n = datas[n].rhs;
575581 } else if (datas[n].lhs != 0) {
......@@ -690,7 +696,6 @@ pub const Tree = struct {
690696 .Slice => unreachable, // TODO
691697 .SwitchCaseOne => unreachable, // TODO
692698 .SwitchRange => unreachable, // TODO
693 .FnDecl => unreachable, // TODO
694699 .ArrayType => unreachable, // TODO
695700 .ArrayTypeSentinel => unreachable, // TODO
696701 .PtrTypeAligned => unreachable, // TODO
......@@ -1836,8 +1841,12 @@ pub const Node = struct {
18361841 GroupedExpression,
18371842 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
18381843 BuiltinCallTwo,
1844 /// Same as BuiltinCallTwo but there is known to be a trailing comma before the rparen.
1845 BuiltinCallTwoComma,
18391846 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
18401847 BuiltinCall,
1848 /// Same as BuiltinCall but there is known to be a trailing comma before the rparen.
1849 BuiltinCallComma,
18411850 /// `error{a, b}`.
18421851 /// lhs and rhs both unused.
18431852 ErrorSetDecl,
lib/std/zig/parse.zig+24-14
......@@ -3676,7 +3676,6 @@ const Parser = struct {
36763676
36773677 /// FnCallArguments <- LPAREN ExprList RPAREN
36783678 /// ExprList <- (Expr COMMA)* Expr?
3679 /// TODO detect when we can emit BuiltinCallTwo instead of BuiltinCall.
36803679 fn parseBuiltinCall(p: *Parser) !Node.Index {
36813680 const builtin_token = p.assertToken(.Builtin);
36823681 _ = (try p.expectTokenRecoverable(.LParen)) orelse {
......@@ -3708,7 +3707,7 @@ const Parser = struct {
37083707 .Comma => {
37093708 if (p.eatToken(.RParen)) |_| {
37103709 return p.addNode(.{
3711 .tag = .BuiltinCallTwo,
3710 .tag = .BuiltinCallTwoComma,
37123711 .main_token = builtin_token,
37133712 .data = .{
37143713 .lhs = param_one,
......@@ -3739,7 +3738,7 @@ const Parser = struct {
37393738 .Comma => {
37403739 if (p.eatToken(.RParen)) |_| {
37413740 return p.addNode(.{
3742 .tag = .BuiltinCallTwo,
3741 .tag = .BuiltinCallTwoComma,
37433742 .main_token = builtin_token,
37443743 .data = .{
37453744 .lhs = param_one,
......@@ -3776,10 +3775,30 @@ const Parser = struct {
37763775 try list.append(param);
37773776 switch (p.token_tags[p.nextToken()]) {
37783777 .Comma => {
3779 if (p.eatToken(.RParen)) |_| break;
3778 if (p.eatToken(.RParen)) |_| {
3779 const params = try p.listToSpan(list.items);
3780 return p.addNode(.{
3781 .tag = .BuiltinCallComma,
3782 .main_token = builtin_token,
3783 .data = .{
3784 .lhs = params.start,
3785 .rhs = params.end,
3786 },
3787 });
3788 }
37803789 continue;
37813790 },
3782 .RParen => break,
3791 .RParen => {
3792 const params = try p.listToSpan(list.items);
3793 return p.addNode(.{
3794 .tag = .BuiltinCall,
3795 .main_token = builtin_token,
3796 .data = .{
3797 .lhs = params.start,
3798 .rhs = params.end,
3799 },
3800 });
3801 },
37833802 else => {
37843803 // This is likely just a missing comma;
37853804 // give an error but continue parsing this list.
......@@ -3790,15 +3809,6 @@ const Parser = struct {
37903809 },
37913810 }
37923811 }
3793 const params = try p.listToSpan(list.items);
3794 return p.addNode(.{
3795 .tag = .BuiltinCall,
3796 .main_token = builtin_token,
3797 .data = .{
3798 .lhs = params.start,
3799 .rhs = params.end,
3800 },
3801 });
38023812 }
38033813
38043814 // string literal or multiline string literal
lib/std/zig/parser_test.zig+29-34
......@@ -263,38 +263,38 @@ test "zig fmt: trailing comma in fn parameter list" {
263263 );
264264}
265265
266//test "zig fmt: comptime struct field" {
267// try testCanonical(
268// \\const Foo = struct {
269// \\ a: i32,
270// \\ comptime b: i32 = 1234,
271// \\};
272// \\
273// );
274//}
275//
266test "zig fmt: comptime struct field" {
267 try testCanonical(
268 \\const Foo = struct {
269 \\ a: i32,
270 \\ comptime b: i32 = 1234,
271 \\};
272 \\
273 );
274}
275
276276//test "zig fmt: c pointer type" {
277277// try testCanonical(
278278// \\pub extern fn repro() [*c]const u8;
279279// \\
280280// );
281281//}
282//
283//test "zig fmt: builtin call with trailing comma" {
284// try testCanonical(
285// \\pub fn main() void {
286// \\ @breakpoint();
287// \\ _ = @boolToInt(a);
288// \\ _ = @call(
289// \\ a,
290// \\ b,
291// \\ c,
292// \\ );
293// \\}
294// \\
295// );
296//}
297//
282
283test "zig fmt: builtin call with trailing comma" {
284 try testCanonical(
285 \\pub fn main() void {
286 \\ @breakpoint();
287 \\ _ = @boolToInt(a);
288 \\ _ = @call(
289 \\ a,
290 \\ b,
291 \\ c,
292 \\ );
293 \\}
294 \\
295 );
296}
297
298298//test "zig fmt: asm expression with comptime content" {
299299// try testCanonical(
300300// \\comptime {
......@@ -3988,14 +3988,9 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
39883988 return error.ParseError;
39893989 }
39903990
3991 var buffer = std.ArrayList(u8).init(allocator);
3992 errdefer buffer.deinit();
3993
3994 const writer = buffer.writer();
3995 try std.zig.render(allocator, writer, tree);
3996 const result = buffer.toOwnedSlice();
3997 anything_changed.* = !mem.eql(u8, result, source);
3998 return result;
3991 const formatted = try std.zig.render(allocator, tree);
3992 anything_changed.* = !mem.eql(u8, formatted, source);
3993 return formatted;
39993994}
40003995fn testTransform(source: []const u8, expected_source: []const u8) !void {
40013996 const needed_alloc_count = x: {
lib/std/zig/render.zig+15-9
......@@ -22,13 +22,19 @@ pub const Error = error{
2222const Writer = std.ArrayList(u8).Writer;
2323const Ais = std.io.AutoIndentingStream(Writer);
2424
25/// Returns whether anything changed.
26/// `gpa` is used for allocating extra stack memory if needed, because
27/// this function utilizes recursion.
28pub fn render(gpa: *mem.Allocator, writer: Writer, tree: ast.Tree) Error!void {
29 assert(tree.errors.len == 0); // cannot render an invalid tree
30 var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, writer);
31 return renderRoot(&auto_indenting_stream, tree);
25/// `gpa` is used both for allocating the resulting formatted source code, but also
26/// for allocating extra stack memory if needed, because this function utilizes recursion.
27/// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
28/// Caller owns the returned slice of bytes, allocated with `gpa`.
29pub fn render(gpa: *mem.Allocator, tree: ast.Tree) Error![]u8 {
30 assert(tree.errors.len == 0); // Cannot render an invalid tree.
31
32 var buffer = std.ArrayList(u8).init(gpa);
33 defer buffer.deinit();
34
35 var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, buffer.writer());
36 try renderRoot(&auto_indenting_stream, tree);
37 return buffer.toOwnedSlice();
3238}
3339
3440/// Assumes there are no tokens in between start and end.
......@@ -770,7 +776,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
770776 // }
771777 //},
772778
773 .BuiltinCallTwo => {
779 .BuiltinCallTwo, .BuiltinCallTwoComma => {
774780 if (datas[node].lhs == 0) {
775781 const params = [_]ast.Node.Index{};
776782 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
......@@ -782,7 +788,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
782788 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
783789 }
784790 },
785 .BuiltinCall => {
791 .BuiltinCall, .BuiltinCallComma => {
786792 const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
787793 return renderBuiltinCall(ais, tree, main_tokens[node], params, space);
788794 },