zig fmt: implement error set decls

This commit is contained in:
Isaac Freund 2021-02-07 22:16:23 +01:00 committed by Andrew Kelley
parent bb7b5ee2ac
commit 1d71b19c0d
4 changed files with 84 additions and 7 deletions

View File

@ -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.

View File

@ -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
},
});
},

View File

@ -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{

View File

@ -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);