Commit d898945786
Changed files (4)
lib
lib/std/zig/ast.zig
@@ -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,
lib/std/zig/parse.zig
@@ -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
lib/std/zig/parser_test.zig
@@ -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: {
lib/std/zig/render.zig
@@ -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], ¶ms, 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], ¶ms, space);
}
},
- .BuiltinCall => {
+ .BuiltinCall, .BuiltinCallComma => {
const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
return renderBuiltinCall(ais, tree, main_tokens[node], params, space);
},