From 1d71b19c0d025aeeede229e714679f4b4fb7880d Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Sun, 7 Feb 2021 22:16:23 +0100 Subject: [PATCH] zig fmt: implement error set decls --- lib/std/zig/ast.zig | 4 +-- lib/std/zig/parse.zig | 6 ++--- lib/std/zig/parser_test.zig | 31 ++++++++++++++++++++++- lib/std/zig/render.zig | 50 ++++++++++++++++++++++++++++++++++++- 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 4ecd82acb4..bebacd0b2d 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -498,6 +498,7 @@ pub const Tree = struct { .UnwrapOptional, .GroupedExpression, .StringLiteral, + .ErrorSetDecl, => return datas[n].rhs + end_offset, .AnyType, @@ -724,7 +725,6 @@ pub const Tree = struct { .Switch => unreachable, // TODO .If => unreachable, // TODO .Continue => unreachable, // TODO - .ErrorSetDecl => unreachable, // TODO .AsmSimple => unreachable, // TODO .Asm => unreachable, // TODO .SwitchCaseOne => unreachable, // TODO @@ -2061,7 +2061,7 @@ pub const Node = struct { /// Same as BuiltinCall but there is known to be a trailing comma before the rparen. BuiltinCallComma, /// `error{a, b}`. - /// lhs and rhs both unused. + /// rhs is the rbrace, lhs is unused. ErrorSetDecl, /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`. /// main_token is `struct`, `union`, `opaque`, `enum` keyword. diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index c6cec8a195..fc4847249a 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -2714,13 +2714,13 @@ const Parser = struct { const error_token = p.tok_i; p.tok_i += 2; - if (p.eatToken(.RBrace)) |_| { + if (p.eatToken(.RBrace)) |rbrace| { return p.addNode(.{ .tag = .ErrorSetDecl, .main_token = error_token, .data = .{ .lhs = undefined, - .rhs = undefined, + .rhs = rbrace, }, }); } @@ -2758,7 +2758,7 @@ const Parser = struct { .main_token = error_token, .data = .{ .lhs = undefined, - .rhs = undefined, + .rhs = p.tok_i - 1, // rbrace }, }); }, diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index d8af653028..dec7b09127 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -2015,7 +2015,36 @@ test "zig fmt: ptr deref operator and unwrap optional operator" { // \\ // ); //} -// + +// TODO: replace this with the next test case when possible +test "zig fmt: error set declaration" { + try testCanonical( + \\const E = error{ + \\ A, + \\ B, + \\ + \\ C, + \\}; + \\const Error = error{ + \\ /// no more memory + \\ OutOfMemory, + \\}; + \\const Error = error{ + \\ /// no more memory + \\ OutOfMemory, + \\ + \\ /// another + \\ Another, + \\ /// and one more + \\ Another, + \\}; + \\const Error = error{OutOfMemory}; + \\const Error = error{}; + \\const Error = error{ OutOfMemory, OutOfTime }; + \\ + ); +} + //test "zig fmt: error set declaration" { // try testCanonical( // \\const E = error{ diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 3d2c6e2f03..cbaf462166 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -563,7 +563,55 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac .TaggedUnionEnumTagComma, => return renderContainerDecl(ais, tree, tree.taggedUnionEnumTag(node), space), - .ErrorSetDecl => unreachable, // TODO + // TODO: handle comments properly + .ErrorSetDecl => { + const error_token = main_tokens[node]; + const lbrace = error_token + 1; + const rbrace = datas[node].rhs; + + try renderToken(ais, tree, error_token, .None); + + if (lbrace + 1 == rbrace) { + // There is nothing between the braces so render condensed: `error{}` + try renderToken(ais, tree, lbrace, .None); + try renderToken(ais, tree, rbrace, space); + } else if (lbrace + 2 == rbrace and token_tags[lbrace + 1] == .Identifier) { + // There is exactly one member and no trailing comma or + // comments, so render without surrounding spaces: `error{Foo}` + try renderToken(ais, tree, lbrace, .None); + try renderToken(ais, tree, lbrace + 1, .None); // identifier + try renderToken(ais, tree, rbrace, space); + } else if (token_tags[rbrace - 1] == .Comma) { + // There is a trailing comma so render each member on a new line. + try renderToken(ais, tree, lbrace, .Newline); + ais.pushIndent(); + var i = lbrace + 1; + while (i < rbrace) : (i += 1) { + try renderExtraNewlineToken(ais, tree, i); + switch (token_tags[i]) { + .DocComment => try renderToken(ais, tree, i, .Newline), + .Identifier => try renderToken(ais, tree, i, .Comma), + .Comma => {}, + else => unreachable, + } + } + ais.popIndent(); + try renderToken(ais, tree, rbrace, space); + } else { + // There is no trailing comma so render everything on one line. + try renderToken(ais, tree, lbrace, .Space); + var i = lbrace + 1; + while (i < rbrace) : (i += 1) { + switch (token_tags[i]) { + .DocComment => unreachable, // TODO + .Identifier => try renderToken(ais, tree, i, .CommaSpace), + .Comma => {}, + else => unreachable, + } + } + try renderToken(ais, tree, rbrace, space); + } + }, //.ErrorSetDecl => { // const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base);