zig fmt: builtin call with trailing comma

This commit is contained in:
Andrew Kelley 2021-02-05 20:38:30 -07:00
parent 409ca88829
commit d898945786
4 changed files with 84 additions and 64 deletions

View File

@ -234,7 +234,9 @@ pub const Tree = struct {
.StringLiteral,
.GroupedExpression,
.BuiltinCallTwo,
.BuiltinCallTwoComma,
.BuiltinCall,
.BuiltinCallComma,
.ErrorSetDecl,
.AnyType,
.Comptime,
@ -474,6 +476,7 @@ pub const Tree = struct {
.ErrorUnion,
.IfSimple,
.WhileSimple,
.FnDecl,
=> n = datas[n].rhs,
.FieldAccess,
@ -497,9 +500,7 @@ pub const Tree = struct {
.EnumLiteral,
=> return main_tokens[n] + end_offset,
.Call,
.BuiltinCall,
=> {
.Call => {
end_offset += 1; // for the rparen
const params = tree.extraData(datas[n].rhs, Node.SubRange);
if (params.end - params.start == 0) {
@ -526,6 +527,7 @@ pub const Tree = struct {
.Block,
.ContainerDecl,
.TaggedUnion,
.BuiltinCall,
=> {
end_offset += 1; // for the rbrace
if (datas[n].rhs - datas[n].lhs == 0) {
@ -533,9 +535,12 @@ pub const Tree = struct {
}
n = tree.extra_data[datas[n].rhs - 1]; // last statement
},
.ContainerDeclComma, .TaggedUnionComma => {
.ContainerDeclComma,
.TaggedUnionComma,
.BuiltinCallComma,
=> {
assert(datas[n].rhs - datas[n].lhs > 0);
end_offset += 2; // for the comma + rbrace
end_offset += 2; // for the comma + rbrace/rparen
n = tree.extra_data[datas[n].rhs - 1]; // last member
},
.CallOne,
@ -565,11 +570,12 @@ pub const Tree = struct {
}
},
.ArrayInitDotTwoComma,
.BuiltinCallTwoComma,
.StructInitDotTwoComma,
.ContainerDeclTwoComma,
.TaggedUnionTwoComma,
=> {
end_offset += 2; // for the comma + rbrace
end_offset += 2; // for the comma + rbrace/rparen
if (datas[n].rhs != 0) {
n = datas[n].rhs;
} else if (datas[n].lhs != 0) {
@ -690,7 +696,6 @@ pub const Tree = struct {
.Slice => unreachable, // TODO
.SwitchCaseOne => unreachable, // TODO
.SwitchRange => unreachable, // TODO
.FnDecl => unreachable, // TODO
.ArrayType => unreachable, // TODO
.ArrayTypeSentinel => unreachable, // TODO
.PtrTypeAligned => unreachable, // TODO
@ -1836,8 +1841,12 @@ pub const Node = struct {
GroupedExpression,
/// `@a(lhs, rhs)`. lhs and rhs may be omitted.
BuiltinCallTwo,
/// Same as BuiltinCallTwo but there is known to be a trailing comma before the rparen.
BuiltinCallTwoComma,
/// `@a(b, c)`. `sub_list[lhs..rhs]`.
BuiltinCall,
/// Same as BuiltinCall but there is known to be a trailing comma before the rparen.
BuiltinCallComma,
/// `error{a, b}`.
/// lhs and rhs both unused.
ErrorSetDecl,

View File

@ -3676,7 +3676,6 @@ const Parser = struct {
/// FnCallArguments <- LPAREN ExprList RPAREN
/// ExprList <- (Expr COMMA)* Expr?
/// TODO detect when we can emit BuiltinCallTwo instead of BuiltinCall.
fn parseBuiltinCall(p: *Parser) !Node.Index {
const builtin_token = p.assertToken(.Builtin);
_ = (try p.expectTokenRecoverable(.LParen)) orelse {
@ -3708,7 +3707,7 @@ const Parser = struct {
.Comma => {
if (p.eatToken(.RParen)) |_| {
return p.addNode(.{
.tag = .BuiltinCallTwo,
.tag = .BuiltinCallTwoComma,
.main_token = builtin_token,
.data = .{
.lhs = param_one,
@ -3739,7 +3738,7 @@ const Parser = struct {
.Comma => {
if (p.eatToken(.RParen)) |_| {
return p.addNode(.{
.tag = .BuiltinCallTwo,
.tag = .BuiltinCallTwoComma,
.main_token = builtin_token,
.data = .{
.lhs = param_one,
@ -3776,10 +3775,30 @@ const Parser = struct {
try list.append(param);
switch (p.token_tags[p.nextToken()]) {
.Comma => {
if (p.eatToken(.RParen)) |_| break;
if (p.eatToken(.RParen)) |_| {
const params = try p.listToSpan(list.items);
return p.addNode(.{
.tag = .BuiltinCallComma,
.main_token = builtin_token,
.data = .{
.lhs = params.start,
.rhs = params.end,
},
});
}
continue;
},
.RParen => break,
.RParen => {
const params = try p.listToSpan(list.items);
return p.addNode(.{
.tag = .BuiltinCall,
.main_token = builtin_token,
.data = .{
.lhs = params.start,
.rhs = params.end,
},
});
},
else => {
// This is likely just a missing comma;
// give an error but continue parsing this list.
@ -3790,15 +3809,6 @@ const Parser = struct {
},
}
}
const params = try p.listToSpan(list.items);
return p.addNode(.{
.tag = .BuiltinCall,
.main_token = builtin_token,
.data = .{
.lhs = params.start,
.rhs = params.end,
},
});
}
// string literal or multiline string literal

View File

@ -263,38 +263,38 @@ test "zig fmt: trailing comma in fn parameter list" {
);
}
//test "zig fmt: comptime struct field" {
// try testCanonical(
// \\const Foo = struct {
// \\ a: i32,
// \\ comptime b: i32 = 1234,
// \\};
// \\
// );
//}
//
test "zig fmt: comptime struct field" {
try testCanonical(
\\const Foo = struct {
\\ a: i32,
\\ comptime b: i32 = 1234,
\\};
\\
);
}
//test "zig fmt: c pointer type" {
// try testCanonical(
// \\pub extern fn repro() [*c]const u8;
// \\
// );
//}
//
//test "zig fmt: builtin call with trailing comma" {
// try testCanonical(
// \\pub fn main() void {
// \\ @breakpoint();
// \\ _ = @boolToInt(a);
// \\ _ = @call(
// \\ a,
// \\ b,
// \\ c,
// \\ );
// \\}
// \\
// );
//}
//
test "zig fmt: builtin call with trailing comma" {
try testCanonical(
\\pub fn main() void {
\\ @breakpoint();
\\ _ = @boolToInt(a);
\\ _ = @call(
\\ a,
\\ b,
\\ c,
\\ );
\\}
\\
);
}
//test "zig fmt: asm expression with comptime content" {
// try testCanonical(
// \\comptime {
@ -3988,14 +3988,9 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
return error.ParseError;
}
var buffer = std.ArrayList(u8).init(allocator);
errdefer buffer.deinit();
const writer = buffer.writer();
try std.zig.render(allocator, writer, tree);
const result = buffer.toOwnedSlice();
anything_changed.* = !mem.eql(u8, result, source);
return result;
const formatted = try std.zig.render(allocator, tree);
anything_changed.* = !mem.eql(u8, formatted, source);
return formatted;
}
fn testTransform(source: []const u8, expected_source: []const u8) !void {
const needed_alloc_count = x: {

View File

@ -22,13 +22,19 @@ pub const Error = error{
const Writer = std.ArrayList(u8).Writer;
const Ais = std.io.AutoIndentingStream(Writer);
/// Returns whether anything changed.
/// `gpa` is used for allocating extra stack memory if needed, because
/// this function utilizes recursion.
pub fn render(gpa: *mem.Allocator, writer: Writer, tree: ast.Tree) Error!void {
assert(tree.errors.len == 0); // cannot render an invalid tree
var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, writer);
return renderRoot(&auto_indenting_stream, tree);
/// `gpa` is used both for allocating the resulting formatted source code, but also
/// for allocating extra stack memory if needed, because this function utilizes recursion.
/// Note: that's not actually true yet, see https://github.com/ziglang/zig/issues/1006.
/// Caller owns the returned slice of bytes, allocated with `gpa`.
pub fn render(gpa: *mem.Allocator, tree: ast.Tree) Error![]u8 {
assert(tree.errors.len == 0); // Cannot render an invalid tree.
var buffer = std.ArrayList(u8).init(gpa);
defer buffer.deinit();
var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, buffer.writer());
try renderRoot(&auto_indenting_stream, tree);
return buffer.toOwnedSlice();
}
/// 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
// }
//},
.BuiltinCallTwo => {
.BuiltinCallTwo, .BuiltinCallTwoComma => {
if (datas[node].lhs == 0) {
const params = [_]ast.Node.Index{};
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
return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
}
},
.BuiltinCall => {
.BuiltinCall, .BuiltinCallComma => {
const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
return renderBuiltinCall(ais, tree, main_tokens[node], params, space);
},