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 {...@@ -234,7 +234,9 @@ pub const Tree = struct {
234 .StringLiteral,234 .StringLiteral,
235 .GroupedExpression,235 .GroupedExpression,
236 .BuiltinCallTwo,236 .BuiltinCallTwo,
237 .BuiltinCallTwoComma,
237 .BuiltinCall,238 .BuiltinCall,
239 .BuiltinCallComma,
238 .ErrorSetDecl,240 .ErrorSetDecl,
239 .AnyType,241 .AnyType,
240 .Comptime,242 .Comptime,
...@@ -474,6 +476,7 @@ pub const Tree = struct {...@@ -474,6 +476,7 @@ pub const Tree = struct {
474 .ErrorUnion,476 .ErrorUnion,
475 .IfSimple,477 .IfSimple,
476 .WhileSimple,478 .WhileSimple,
479 .FnDecl,
477 => n = datas[n].rhs,480 => n = datas[n].rhs,
478481
479 .FieldAccess,482 .FieldAccess,
...@@ -497,9 +500,7 @@ pub const Tree = struct {...@@ -497,9 +500,7 @@ pub const Tree = struct {
497 .EnumLiteral,500 .EnumLiteral,
498 => return main_tokens[n] + end_offset,501 => return main_tokens[n] + end_offset,
499502
500 .Call,503 .Call => {
501 .BuiltinCall,
502 => {
503 end_offset += 1; // for the rparen504 end_offset += 1; // for the rparen
504 const params = tree.extraData(datas[n].rhs, Node.SubRange);505 const params = tree.extraData(datas[n].rhs, Node.SubRange);
505 if (params.end - params.start == 0) {506 if (params.end - params.start == 0) {
...@@ -526,6 +527,7 @@ pub const Tree = struct {...@@ -526,6 +527,7 @@ pub const Tree = struct {
526 .Block,527 .Block,
527 .ContainerDecl,528 .ContainerDecl,
528 .TaggedUnion,529 .TaggedUnion,
530 .BuiltinCall,
529 => {531 => {
530 end_offset += 1; // for the rbrace532 end_offset += 1; // for the rbrace
531 if (datas[n].rhs - datas[n].lhs == 0) {533 if (datas[n].rhs - datas[n].lhs == 0) {
...@@ -533,9 +535,12 @@ pub const Tree = struct {...@@ -533,9 +535,12 @@ pub const Tree = struct {
533 }535 }
534 n = tree.extra_data[datas[n].rhs - 1]; // last statement536 n = tree.extra_data[datas[n].rhs - 1]; // last statement
535 },537 },
536 .ContainerDeclComma, .TaggedUnionComma => {538 .ContainerDeclComma,
539 .TaggedUnionComma,
540 .BuiltinCallComma,
541 => {
537 assert(datas[n].rhs - datas[n].lhs > 0);542 assert(datas[n].rhs - datas[n].lhs > 0);
538 end_offset += 2; // for the comma + rbrace543 end_offset += 2; // for the comma + rbrace/rparen
539 n = tree.extra_data[datas[n].rhs - 1]; // last member544 n = tree.extra_data[datas[n].rhs - 1]; // last member
540 },545 },
541 .CallOne,546 .CallOne,
...@@ -565,11 +570,12 @@ pub const Tree = struct {...@@ -565,11 +570,12 @@ pub const Tree = struct {
565 }570 }
566 },571 },
567 .ArrayInitDotTwoComma,572 .ArrayInitDotTwoComma,
573 .BuiltinCallTwoComma,
568 .StructInitDotTwoComma,574 .StructInitDotTwoComma,
569 .ContainerDeclTwoComma,575 .ContainerDeclTwoComma,
570 .TaggedUnionTwoComma,576 .TaggedUnionTwoComma,
571 => {577 => {
572 end_offset += 2; // for the comma + rbrace578 end_offset += 2; // for the comma + rbrace/rparen
573 if (datas[n].rhs != 0) {579 if (datas[n].rhs != 0) {
574 n = datas[n].rhs;580 n = datas[n].rhs;
575 } else if (datas[n].lhs != 0) {581 } else if (datas[n].lhs != 0) {
...@@ -690,7 +696,6 @@ pub const Tree = struct {...@@ -690,7 +696,6 @@ pub const Tree = struct {
690 .Slice => unreachable, // TODO696 .Slice => unreachable, // TODO
691 .SwitchCaseOne => unreachable, // TODO697 .SwitchCaseOne => unreachable, // TODO
692 .SwitchRange => unreachable, // TODO698 .SwitchRange => unreachable, // TODO
693 .FnDecl => unreachable, // TODO
694 .ArrayType => unreachable, // TODO699 .ArrayType => unreachable, // TODO
695 .ArrayTypeSentinel => unreachable, // TODO700 .ArrayTypeSentinel => unreachable, // TODO
696 .PtrTypeAligned => unreachable, // TODO701 .PtrTypeAligned => unreachable, // TODO
...@@ -1836,8 +1841,12 @@ pub const Node = struct {...@@ -1836,8 +1841,12 @@ pub const Node = struct {
1836 GroupedExpression,1841 GroupedExpression,
1837 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.1842 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
1838 BuiltinCallTwo,1843 BuiltinCallTwo,
1844 /// Same as BuiltinCallTwo but there is known to be a trailing comma before the rparen.
1845 BuiltinCallTwoComma,
1839 /// `@a(b, c)`. `sub_list[lhs..rhs]`.1846 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
1840 BuiltinCall,1847 BuiltinCall,
1848 /// Same as BuiltinCall but there is known to be a trailing comma before the rparen.
1849 BuiltinCallComma,
1841 /// `error{a, b}`.1850 /// `error{a, b}`.
1842 /// lhs and rhs both unused.1851 /// lhs and rhs both unused.
1843 ErrorSetDecl,1852 ErrorSetDecl,
lib/std/zig/parse.zig+24-14
...@@ -3676,7 +3676,6 @@ const Parser = struct {...@@ -3676,7 +3676,6 @@ const Parser = struct {
36763676
3677 /// FnCallArguments <- LPAREN ExprList RPAREN3677 /// FnCallArguments <- LPAREN ExprList RPAREN
3678 /// ExprList <- (Expr COMMA)* Expr?3678 /// ExprList <- (Expr COMMA)* Expr?
3679 /// TODO detect when we can emit BuiltinCallTwo instead of BuiltinCall.
3680 fn parseBuiltinCall(p: *Parser) !Node.Index {3679 fn parseBuiltinCall(p: *Parser) !Node.Index {
3681 const builtin_token = p.assertToken(.Builtin);3680 const builtin_token = p.assertToken(.Builtin);
3682 _ = (try p.expectTokenRecoverable(.LParen)) orelse {3681 _ = (try p.expectTokenRecoverable(.LParen)) orelse {
...@@ -3708,7 +3707,7 @@ const Parser = struct {...@@ -3708,7 +3707,7 @@ const Parser = struct {
3708 .Comma => {3707 .Comma => {
3709 if (p.eatToken(.RParen)) |_| {3708 if (p.eatToken(.RParen)) |_| {
3710 return p.addNode(.{3709 return p.addNode(.{
3711 .tag = .BuiltinCallTwo,3710 .tag = .BuiltinCallTwoComma,
3712 .main_token = builtin_token,3711 .main_token = builtin_token,
3713 .data = .{3712 .data = .{
3714 .lhs = param_one,3713 .lhs = param_one,
...@@ -3739,7 +3738,7 @@ const Parser = struct {...@@ -3739,7 +3738,7 @@ const Parser = struct {
3739 .Comma => {3738 .Comma => {
3740 if (p.eatToken(.RParen)) |_| {3739 if (p.eatToken(.RParen)) |_| {
3741 return p.addNode(.{3740 return p.addNode(.{
3742 .tag = .BuiltinCallTwo,3741 .tag = .BuiltinCallTwoComma,
3743 .main_token = builtin_token,3742 .main_token = builtin_token,
3744 .data = .{3743 .data = .{
3745 .lhs = param_one,3744 .lhs = param_one,
...@@ -3776,10 +3775,30 @@ const Parser = struct {...@@ -3776,10 +3775,30 @@ const Parser = struct {
3776 try list.append(param);3775 try list.append(param);
3777 switch (p.token_tags[p.nextToken()]) {3776 switch (p.token_tags[p.nextToken()]) {
3778 .Comma => {3777 .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 }
3780 continue;3789 continue;
3781 },3790 },
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 },
3783 else => {3802 else => {
3784 // This is likely just a missing comma;3803 // This is likely just a missing comma;
3785 // give an error but continue parsing this list.3804 // give an error but continue parsing this list.
...@@ -3790,15 +3809,6 @@ const Parser = struct {...@@ -3790,15 +3809,6 @@ const Parser = struct {
3790 },3809 },
3791 }3810 }
3792 }3811 }
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 });
3802 }3812 }
38033813
3804 // string literal or multiline string literal3814 // 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" {...@@ -263,38 +263,38 @@ test "zig fmt: trailing comma in fn parameter list" {
263 );263 );
264}264}
265265
266//test "zig fmt: comptime struct field" {266test "zig fmt: comptime struct field" {
267// try testCanonical(267 try testCanonical(
268// \\const Foo = struct {268 \\const Foo = struct {
269// \\ a: i32,269 \\ a: i32,
270// \\ comptime b: i32 = 1234,270 \\ comptime b: i32 = 1234,
271// \\};271 \\};
272// \\272 \\
273// );273 );
274//}274}
275//275
276//test "zig fmt: c pointer type" {276//test "zig fmt: c pointer type" {
277// try testCanonical(277// try testCanonical(
278// \\pub extern fn repro() [*c]const u8;278// \\pub extern fn repro() [*c]const u8;
279// \\279// \\
280// );280// );
281//}281//}
282//282
283//test "zig fmt: builtin call with trailing comma" {283test "zig fmt: builtin call with trailing comma" {
284// try testCanonical(284 try testCanonical(
285// \\pub fn main() void {285 \\pub fn main() void {
286// \\ @breakpoint();286 \\ @breakpoint();
287// \\ _ = @boolToInt(a);287 \\ _ = @boolToInt(a);
288// \\ _ = @call(288 \\ _ = @call(
289// \\ a,289 \\ a,
290// \\ b,290 \\ b,
291// \\ c,291 \\ c,
292// \\ );292 \\ );
293// \\}293 \\}
294// \\294 \\
295// );295 );
296//}296}
297//297
298//test "zig fmt: asm expression with comptime content" {298//test "zig fmt: asm expression with comptime content" {
299// try testCanonical(299// try testCanonical(
300// \\comptime {300// \\comptime {
...@@ -3988,14 +3988,9 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b...@@ -3988,14 +3988,9 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
3988 return error.ParseError;3988 return error.ParseError;
3989 }3989 }
39903990
3991 var buffer = std.ArrayList(u8).init(allocator);3991 const formatted = try std.zig.render(allocator, tree);
3992 errdefer buffer.deinit();3992 anything_changed.* = !mem.eql(u8, formatted, source);
39933993 return formatted;
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;
3999}3994}
4000fn testTransform(source: []const u8, expected_source: []const u8) !void {3995fn testTransform(source: []const u8, expected_source: []const u8) !void {
4001 const needed_alloc_count = x: {3996 const needed_alloc_count = x: {
lib/std/zig/render.zig+15-9
...@@ -22,13 +22,19 @@ pub const Error = error{...@@ -22,13 +22,19 @@ pub const Error = error{
22const Writer = std.ArrayList(u8).Writer;22const Writer = std.ArrayList(u8).Writer;
23const Ais = std.io.AutoIndentingStream(Writer);23const Ais = std.io.AutoIndentingStream(Writer);
2424
25/// Returns whether anything changed.25/// `gpa` is used both for allocating the resulting formatted source code, but also
26/// `gpa` is used for allocating extra stack memory if needed, because26/// for allocating extra stack memory if needed, because this function utilizes recursion.
27/// this function utilizes recursion.27/// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
28pub fn render(gpa: *mem.Allocator, writer: Writer, tree: ast.Tree) Error!void {28/// Caller owns the returned slice of bytes, allocated with `gpa`.
29 assert(tree.errors.len == 0); // cannot render an invalid tree29pub fn render(gpa: *mem.Allocator, tree: ast.Tree) Error![]u8 {
30 var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, writer);30 assert(tree.errors.len == 0); // Cannot render an invalid tree.
31 return renderRoot(&auto_indenting_stream, 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();
32}38}
3339
34/// Assumes there are no tokens in between start and end.40/// 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...@@ -770,7 +776,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
770 // }776 // }
771 //},777 //},
772778
773 .BuiltinCallTwo => {779 .BuiltinCallTwo, .BuiltinCallTwoComma => {
774 if (datas[node].lhs == 0) {780 if (datas[node].lhs == 0) {
775 const params = [_]ast.Node.Index{};781 const params = [_]ast.Node.Index{};
776 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);782 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...@@ -782,7 +788,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
782 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);788 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
783 }789 }
784 },790 },
785 .BuiltinCall => {791 .BuiltinCall, .BuiltinCallComma => {
786 const params = tree.extra_data[datas[node].lhs..datas[node].rhs];792 const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
787 return renderBuiltinCall(ais, tree, main_tokens[node], params, space);793 return renderBuiltinCall(ais, tree, main_tokens[node], params, space);
788 },794 },