authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-10 15:19:30+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-10 11:53:53-08:00
loga524e57090f3e3412292dbe6b3e4fe4fb7bad1ea
treebee166a7f12e3859152cf046ba5d636e01ca1f59
parent80b719d967d7241182e237b42ade1cd88494c8e8

zig fmt: support bodyless function decls

extern function declarations do not have a body, so allow setting the rhs for FnDecl to 0 to indicate this is the case.

4 files changed, 52 insertions(+), 14 deletions(-)

lib/std/zig/ast.zig+12-4
......@@ -521,7 +521,8 @@ pub const Tree = struct {
521521 .IfSimple,
522522 .WhileSimple,
523523 .ForSimple,
524 .FnDecl,
524 .FnProtoSimple,
525 .FnProtoMulti,
525526 .PtrTypeAligned,
526527 .PtrTypeSentinel,
527528 .PtrType,
......@@ -538,8 +539,6 @@ pub const Tree = struct {
538539 .AsmSimple,
539540 .AsmOutput,
540541 .AsmInput,
541 .FnProtoSimple,
542 .FnProtoMulti,
543542 .ErrorValue,
544543 => return datas[n].rhs + end_offset,
545544
......@@ -804,6 +803,13 @@ pub const Tree = struct {
804803 return main_tokens[n] + end_offset;
805804 }
806805 },
806 .FnDecl => {
807 if (datas[n].rhs != 0) {
808 n = datas[n].rhs;
809 } else {
810 n = datas[n].lhs;
811 }
812 },
807813 .FnProtoOne => {
808814 const extra = tree.extraData(datas[n].lhs, Node.FnProtoOne);
809815 // linksection, callconv, align can appear in any order, so we
......@@ -2520,7 +2526,9 @@ pub const Node = struct {
25202526 /// `fn(a: b, c: d) rhs linksection(e) callconv(f)`. `FnProto[lhs]`.
25212527 /// anytype and ... parameters are omitted from the AST tree.
25222528 FnProto,
2523 /// lhs is the FnProto, rhs is the function body block.
2529 /// lhs is the FnProto.
2530 /// rhs is the function body block if non-zero.
2531 /// if rhs is zero, the funtion decl has no body (e.g. an extern function)
25242532 FnDecl,
25252533 /// `anyframe->rhs`. main_token is `anyframe`. `lhs` is arrow token index.
25262534 AnyFrameType,
lib/std/zig/parse.zig+8-1
......@@ -516,7 +516,14 @@ const Parser = struct {
516516 .Semicolon => {
517517 const semicolon_token = p.nextToken();
518518 try p.parseAppendedDocComment(semicolon_token);
519 return fn_proto;
519 return p.addNode(.{
520 .tag = .FnDecl,
521 .main_token = p.nodes.items(.main_token)[fn_proto],
522 .data = .{
523 .lhs = fn_proto,
524 .rhs = 0,
525 },
526 });
520527 },
521528 .LBrace => {
522529 const body_block = try p.parseBlock();
lib/std/zig/parser_test.zig+23-7
......@@ -298,12 +298,12 @@ test "zig fmt: grouped expressions (parentheses)" {
298298 );
299299}
300300
301//test "zig fmt: c pointer type" {
302// try testCanonical(
303// \\pub extern fn repro() [*c]const u8;
304// \\
305// );
306//}
301test "zig fmt: c pointer type" {
302 try testCanonical(
303 \\pub extern fn repro() [*c]const u8;
304 \\
305 );
306}
307307
308308test "zig fmt: builtin call with trailing comma" {
309309 try testCanonical(
......@@ -2339,7 +2339,23 @@ test "zig fmt: alignment" {
23392339// \\
23402340// );
23412341//}
2342//
2342
2343test "zig fmt: function attributes" {
2344 try testCanonical(
2345 \\export fn foo() void {}
2346 \\pub export fn foo() void {}
2347 \\extern fn foo() void;
2348 \\pub extern fn foo() void;
2349 \\extern "c" fn foo() void;
2350 \\pub extern "c" fn foo() void;
2351 \\inline fn foo() void {}
2352 \\pub inline fn foo() void {}
2353 \\noinline fn foo() void {}
2354 \\pub noinline fn foo() void {}
2355 \\
2356 );
2357}
2358
23432359//test "zig fmt: pointer attributes" {
23442360// try testCanonical(
23452361// \\extern fn f1(s: *align(*u8) u8) c_int;
lib/std/zig/render.zig+9-2
......@@ -121,6 +121,8 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
121121 .Keyword_export,
122122 .Keyword_pub,
123123 .StringLiteral,
124 .Keyword_inline,
125 .Keyword_noinline,
124126 => continue,
125127
126128 else => {
......@@ -132,8 +134,13 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
132134 while (i < fn_token) : (i += 1) {
133135 try renderToken(ais, tree, i, .Space);
134136 }
135 try renderExpression(ais, tree, fn_proto, .Space);
136 return renderExpression(ais, tree, datas[decl].rhs, space);
137 if (datas[decl].rhs != 0) {
138 try renderExpression(ais, tree, fn_proto, .Space);
139 return renderExpression(ais, tree, datas[decl].rhs, space);
140 } else {
141 try renderExpression(ais, tree, fn_proto, .None);
142 return renderToken(ais, tree, tree.lastToken(fn_proto) + 1, space); // semicolon
143 }
137144 },
138145 .FnProtoSimple,
139146 .FnProtoMulti,