Commit d869133a9f
Changed files (4)
lib
lib/std/zig/ast.zig
@@ -213,6 +213,7 @@ pub const Tree = struct {
.Await,
.OptionalType,
.Switch,
+ .SwitchComma,
.IfSimple,
.If,
.Suspend,
@@ -313,7 +314,6 @@ pub const Tree = struct {
.StructInit,
.CallOne,
.Call,
- .SwitchCaseOne,
.SwitchRange,
.FnDecl,
.ErrorUnion,
@@ -406,7 +406,19 @@ pub const Tree = struct {
};
},
- .SwitchCaseMulti => unreachable, // TODO
+ .SwitchCaseOne => {
+ if (datas[n].lhs == 0) {
+ return main_tokens[n] - 1; // else token
+ } else {
+ n = datas[n].lhs;
+ }
+ },
+ .SwitchCase => {
+ const extra = tree.extraData(datas[n].lhs, Node.SubRange);
+ assert(extra.end - extra.start > 0);
+ n = extra.start;
+ },
+
.WhileSimple => unreachable, // TODO
.WhileCont => unreachable, // TODO
.While => unreachable, // TODO
@@ -494,6 +506,8 @@ pub const Tree = struct {
.PtrTypeSentinel,
.PtrType,
.PtrTypeBitRange,
+ .SwitchCaseOne,
+ .SwitchCase,
=> n = datas[n].rhs,
.FieldAccess,
@@ -532,6 +546,16 @@ pub const Tree = struct {
}
n = tree.extra_data[params.end - 1]; // last parameter
},
+ .Switch => {
+ const cases = tree.extraData(datas[n].rhs, Node.SubRange);
+ if (cases.end - cases.start == 0) {
+ end_offset += 3; // rparen, lbrace, rbrace
+ n = datas[n].lhs; // condition expression
+ } else {
+ end_offset += 1; // for the rbrace
+ n = tree.extra_data[cases.end - 1]; // last case
+ }
+ },
.ContainerDeclArg => {
const members = tree.extraData(datas[n].rhs, Node.SubRange);
if (members.end - members.start == 0) {
@@ -542,7 +566,9 @@ pub const Tree = struct {
n = tree.extra_data[members.end - 1]; // last parameter
}
},
- .ContainerDeclArgComma => {
+ .ContainerDeclArgComma,
+ .SwitchComma,
+ => {
const members = tree.extraData(datas[n].rhs, Node.SubRange);
assert(members.end - members.start > 0);
end_offset += 2; // for the comma + rbrace
@@ -737,16 +763,13 @@ pub const Tree = struct {
.TaggedUnionEnumTag => unreachable, // TODO
.TaggedUnionEnumTagComma => unreachable, // TODO
- .Switch => unreachable, // TODO
.If => unreachable, // TODO
.Continue => unreachable, // TODO
.AsmSimple => unreachable, // TODO
.Asm => unreachable, // TODO
- .SwitchCaseOne => unreachable, // TODO
.SwitchRange => unreachable, // TODO
.ArrayType => unreachable, // TODO
.ArrayTypeSentinel => unreachable, // TODO
- .SwitchCaseMulti => unreachable, // TODO
.WhileCont => unreachable, // TODO
.While => unreachable, // TODO
.ForSimple => unreachable, // TODO
@@ -1202,7 +1225,8 @@ pub const Tree = struct {
}
pub fn containerDeclArg(tree: Tree, node: Node.Index) Full.ContainerDecl {
- assert(tree.nodes.items(.tag)[node] == .ContainerDeclArg);
+ assert(tree.nodes.items(.tag)[node] == .ContainerDeclArg or
+ tree.nodes.items(.tag)[node] == .ContainerDeclArgComma);
const data = tree.nodes.items(.data)[node];
const members_range = tree.extraData(data.rhs, Node.SubRange);
return tree.fullContainerDecl(.{
@@ -1214,7 +1238,8 @@ pub const Tree = struct {
}
pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl {
- assert(tree.nodes.items(.tag)[node] == .TaggedUnionTwo);
+ assert(tree.nodes.items(.tag)[node] == .TaggedUnionTwo or
+ tree.nodes.items(.tag)[node] == .TaggedUnionTwoComma);
const data = tree.nodes.items(.data)[node];
buffer.* = .{ data.lhs, data.rhs };
const members = if (data.rhs != 0)
@@ -1233,7 +1258,8 @@ pub const Tree = struct {
}
pub fn taggedUnion(tree: Tree, node: Node.Index) Full.ContainerDecl {
- assert(tree.nodes.items(.tag)[node] == .TaggedUnion);
+ assert(tree.nodes.items(.tag)[node] == .TaggedUnion or
+ tree.nodes.items(.tag)[node] == .TaggedUnionComma);
const data = tree.nodes.items(.data)[node];
const main_token = tree.nodes.items(.main_token)[node];
return tree.fullContainerDecl(.{
@@ -1245,7 +1271,8 @@ pub const Tree = struct {
}
pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) Full.ContainerDecl {
- assert(tree.nodes.items(.tag)[node] == .TaggedUnionEnumTag);
+ assert(tree.nodes.items(.tag)[node] == .TaggedUnionEnumTag or
+ tree.nodes.items(.tag)[node] == .TaggedUnionEnumTagComma);
const data = tree.nodes.items(.data)[node];
const members_range = tree.extraData(data.rhs, Node.SubRange);
const main_token = tree.nodes.items(.main_token)[node];
@@ -1257,6 +1284,25 @@ pub const Tree = struct {
});
}
+ pub fn switchCaseOne(tree: Tree, node: Node.Index) Full.SwitchCase {
+ const data = &tree.nodes.items(.data)[node];
+ return tree.fullSwitchCase(.{
+ .values = if (data.lhs == 0) &.{} else @ptrCast([*]Node.Index, &data.lhs)[0..1],
+ .arrow_token = tree.nodes.items(.main_token)[node],
+ .target_expr = data.rhs,
+ });
+ }
+
+ pub fn switchCase(tree: Tree, node: Node.Index) Full.SwitchCase {
+ const data = tree.nodes.items(.data)[node];
+ const extra = tree.extraData(data.lhs, Node.SubRange);
+ return tree.fullSwitchCase(.{
+ .values = tree.extra_data[extra.start..extra.end],
+ .arrow_token = tree.nodes.items(.main_token)[node],
+ .target_expr = data.rhs,
+ });
+ }
+
fn fullVarDecl(tree: Tree, info: Full.VarDecl.Ast) Full.VarDecl {
const token_tags = tree.tokens.items(.tag);
var result: Full.VarDecl = .{
@@ -1407,6 +1453,18 @@ pub const Tree = struct {
}
return result;
}
+
+ fn fullSwitchCase(tree: Tree, info: Full.SwitchCase.Ast) Full.SwitchCase {
+ const token_tags = tree.tokens.items(.tag);
+ var result: Full.SwitchCase = .{
+ .ast = info,
+ .payload_token = null,
+ };
+ if (token_tags[info.arrow_token + 1] == .Pipe) {
+ result.payload_token = info.arrow_token + 2;
+ }
+ return result;
+ }
};
/// Fully assembled AST node information.
@@ -1552,6 +1610,20 @@ pub const Full = struct {
arg: Node.Index,
};
};
+
+ pub const SwitchCase = struct {
+ /// Points to the first token after the `|`. Will either be an identifier or
+ /// a `*` (with an identifier immediately after it).
+ payload_token: ?TokenIndex,
+ ast: Ast,
+
+ pub const Ast = struct {
+ /// If empty, this is an else case
+ values: []const Node.Index,
+ arrow_token: TokenIndex,
+ target_expr: Node.Index,
+ };
+ };
};
pub const Error = union(enum) {
@@ -1996,13 +2068,16 @@ pub const Node = struct {
/// `lhs(a, b, c)`. `sub_range_list[rhs]`.
/// main_token is the `(`.
Call,
- /// `switch(lhs) {}`. `sub_range_list[rhs]`.
+ /// `switch(lhs) {}`. `SubRange[rhs]`.
Switch,
+ /// Same as Switch except there is known to be a trailing comma
+ /// before the final rbrace
+ SwitchComma,
/// `lhs => rhs`. If lhs is omitted it means `else`.
/// main_token is the `=>`
SwitchCaseOne,
- /// `a, b, c => rhs`. `sub_range_list[lhs]`.
- SwitchCaseMulti,
+ /// `a, b, c => rhs`. `SubRange[lhs]`.
+ SwitchCase,
/// `lhs...rhs`.
SwitchRange,
/// `while (lhs) rhs`.
lib/std/zig/parse.zig
@@ -2887,10 +2887,11 @@ const Parser = struct {
_ = try p.expectToken(.RParen);
_ = try p.expectToken(.LBrace);
const cases = try p.parseSwitchProngList();
+ const trailing_comma = p.token_tags[p.tok_i - 1] == .Comma;
_ = try p.expectToken(.RBrace);
return p.addNode(.{
- .tag = .Switch,
+ .tag = if (trailing_comma) .SwitchComma else .Switch,
.main_token = switch_token,
.data = .{
.lhs = expr_node,
@@ -3208,7 +3209,7 @@ const Parser = struct {
const arrow_token = try p.expectToken(.EqualAngleBracketRight);
_ = try p.parsePtrPayload();
return p.addNode(.{
- .tag = .SwitchCaseMulti,
+ .tag = .SwitchCase,
.main_token = arrow_token,
.data = .{
.lhs = try p.addExtra(Node.SubRange{
lib/std/zig/parser_test.zig
@@ -1671,32 +1671,32 @@ test "zig fmt: block in slice expression" {
// \\
// );
//}
-//
-//test "zig fmt: switch cases trailing comma" {
-// try testTransform(
-// \\fn switch_cases(x: i32) void {
-// \\ switch (x) {
-// \\ 1,2,3 => {},
-// \\ 4,5, => {},
-// \\ 6... 8, => {},
-// \\ else => {},
-// \\ }
-// \\}
-// ,
-// \\fn switch_cases(x: i32) void {
-// \\ switch (x) {
-// \\ 1, 2, 3 => {},
-// \\ 4,
-// \\ 5,
-// \\ => {},
-// \\ 6...8 => {},
-// \\ else => {},
-// \\ }
-// \\}
-// \\
-// );
-//}
-//
+
+test "zig fmt: switch cases trailing comma" {
+ try testTransform(
+ \\test "switch cases trailing comma"{
+ \\ switch (x) {
+ \\ 1,2,3 => {},
+ \\ 4,5, => {},
+ \\ 6... 8, => {},
+ \\ else => {},
+ \\ }
+ \\}
+ ,
+ \\test "switch cases trailing comma" {
+ \\ switch (x) {
+ \\ 1, 2, 3 => {},
+ \\ 4,
+ \\ 5,
+ \\ => {},
+ \\ 6...8 => {},
+ \\ else => {},
+ \\ }
+ \\}
+ \\
+ );
+}
+
//test "zig fmt: slice align" {
// try testCanonical(
// \\const A = struct {
@@ -1996,16 +1996,16 @@ test "zig fmt: ptr deref operator and unwrap optional operator" {
// \\
// );
//}
-//
-//test "zig fmt: switch with empty body" {
-// try testCanonical(
-// \\test "" {
-// \\ foo() catch |err| switch (err) {};
-// \\}
-// \\
-// );
-//}
-//
+
+test "zig fmt: switch with empty body" {
+ try testCanonical(
+ \\test "" {
+ \\ foo() catch |err| switch (err) {};
+ \\}
+ \\
+ );
+}
+
//test "zig fmt: line comments in struct initializer" {
// try testCanonical(
// \\fn foo() void {
@@ -2725,42 +2725,42 @@ test "zig fmt: blocks" {
);
}
-//test "zig fmt: switch" {
-// try testCanonical(
-// \\test "switch" {
-// \\ switch (0) {
-// \\ 0 => {},
-// \\ 1 => unreachable,
-// \\ 2, 3 => {},
-// \\ 4...7 => {},
-// \\ 1 + 4 * 3 + 22 => {},
-// \\ else => {
-// \\ const a = 1;
-// \\ const b = a;
-// \\ },
-// \\ }
-// \\
-// \\ const res = switch (0) {
-// \\ 0 => 0,
-// \\ 1 => 2,
-// \\ 1 => a = 4,
-// \\ else => 4,
-// \\ };
-// \\
-// \\ const Union = union(enum) {
-// \\ Int: i64,
-// \\ Float: f64,
-// \\ };
-// \\
-// \\ switch (u) {
-// \\ Union.Int => |int| {},
-// \\ Union.Float => |*float| unreachable,
-// \\ }
-// \\}
-// \\
-// );
-//}
-//
+test "zig fmt: switch" {
+ try testCanonical(
+ \\test "switch" {
+ \\ switch (0) {
+ \\ 0 => {},
+ \\ 1 => unreachable,
+ \\ 2, 3 => {},
+ \\ 4...7 => {},
+ \\ 1 + 4 * 3 + 22 => {},
+ \\ else => {
+ \\ const a = 1;
+ \\ const b = a;
+ \\ },
+ \\ }
+ \\
+ \\ const res = switch (0) {
+ \\ 0 => 0,
+ \\ 1 => 2,
+ \\ 1 => a = 4,
+ \\ else => 4,
+ \\ };
+ \\
+ \\ const Union = union(enum) {
+ \\ Int: i64,
+ \\ Float: f64,
+ \\ };
+ \\
+ \\ switch (u) {
+ \\ Union.Int => |int| {},
+ \\ Union.Float => |*float| unreachable,
+ \\ }
+ \\}
+ \\
+ );
+}
+
//test "zig fmt: while" {
// try testCanonical(
// \\test "while" {
lib/std/zig/render.zig
@@ -207,19 +207,18 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
=> {
const statements = [2]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
if (datas[node].lhs == 0) {
- return renderBlock(ais, tree, main_tokens[node], statements[0..0], space);
+ return renderBlock(ais, tree, node, statements[0..0], space);
} else if (datas[node].rhs == 0) {
- return renderBlock(ais, tree, main_tokens[node], statements[0..1], space);
+ return renderBlock(ais, tree, node, statements[0..1], space);
} else {
- return renderBlock(ais, tree, main_tokens[node], statements[0..2], space);
+ return renderBlock(ais, tree, node, statements[0..2], space);
}
},
.Block,
.BlockSemicolon,
=> {
- const lbrace = main_tokens[node];
const statements = tree.extra_data[datas[node].lhs..datas[node].rhs];
- return renderBlock(ais, tree, main_tokens[node], statements, space);
+ return renderBlock(ais, tree, node, statements, space);
},
.ErrDefer => {
@@ -615,81 +614,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
try renderToken(ais, tree, rbrace, space);
}
},
- //.ErrorSetDecl => {
- // const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base);
-
- // const lbrace = tree.nextToken(err_set_decl.error_token);
-
- // if (err_set_decl.decls_len == 0) {
- // try renderToken(ais, tree, err_set_decl.error_token, Space.None);
- // try renderToken(ais, tree, lbrace, Space.None);
- // return renderToken(ais, tree, err_set_decl.rbrace_token, space);
- // }
-
- // if (err_set_decl.decls_len == 1) blk: {
- // const node = err_set_decl.decls()[0];
-
- // // if there are any doc comments or same line comments
- // // don't try to put it all on one line
- // if (node.cast(ast.Node.ErrorTag)) |tag| {
- // if (tag.doc_comments != null) break :blk;
- // } else {
- // break :blk;
- // }
-
- // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error
- // try renderToken(ais, tree, lbrace, Space.None); // lbrace
- // try renderExpression(ais, tree, node, Space.None);
- // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace
- // }
-
- // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error
-
- // const src_has_trailing_comma = blk: {
- // const maybe_comma = tree.prevToken(err_set_decl.rbrace_token);
- // break :blk tree.token_tags[maybe_comma] == .Comma;
- // };
-
- // if (src_has_trailing_comma) {
- // {
- // ais.pushIndent();
- // defer ais.popIndent();
-
- // try renderToken(ais, tree, lbrace, Space.Newline); // lbrace
- // const decls = err_set_decl.decls();
- // for (decls) |node, i| {
- // if (i + 1 < decls.len) {
- // try renderExpression(ais, tree, node, Space.None);
- // try renderToken(ais, tree, tree.nextToken(node.lastToken()), Space.Newline); // ,
-
- // try renderExtraNewline(ais, tree, decls[i + 1]);
- // } else {
- // try renderExpression(ais, tree, node, Space.Comma);
- // }
- // }
- // }
-
- // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace
- // } else {
- // try renderToken(ais, tree, lbrace, Space.Space); // lbrace
-
- // const decls = err_set_decl.decls();
- // for (decls) |node, i| {
- // if (i + 1 < decls.len) {
- // try renderExpression(ais, tree, node, Space.None);
-
- // const comma_token = tree.nextToken(node.lastToken());
- // assert(tree.token_tags[comma_token] == .Comma);
- // try renderToken(ais, tree, comma_token, Space.Space); // ,
- // try renderExtraNewline(ais, tree, decls[i + 1]);
- // } else {
- // try renderExpression(ais, tree, node, Space.Space);
- // }
- // }
-
- // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace
- // }
- //},
.BuiltinCallTwo, .BuiltinCallTwoComma => {
if (datas[node].lhs == 0) {
@@ -732,92 +656,38 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
// }
//},
- .Switch => unreachable, // TODO
- //.Switch => {
- // const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base);
-
- // try renderToken(ais, tree, switch_node.switch_token, Space.Space); // switch
- // try renderToken(ais, tree, tree.nextToken(switch_node.switch_token), Space.None); // (
-
- // const rparen = tree.nextToken(switch_node.expr.lastToken());
- // const lbrace = tree.nextToken(rparen);
-
- // if (switch_node.cases_len == 0) {
- // try renderExpression(ais, tree, switch_node.expr, Space.None);
- // try renderToken(ais, tree, rparen, Space.Space); // )
- // try renderToken(ais, tree, lbrace, Space.None); // lbrace
- // return renderToken(ais, tree, switch_node.rbrace, space); // rbrace
- // }
-
- // try renderExpression(ais, tree, switch_node.expr, Space.None);
- // try renderToken(ais, tree, rparen, Space.Space); // )
-
- // {
- // ais.pushIndentNextLine();
- // defer ais.popIndent();
- // try renderToken(ais, tree, lbrace, Space.Newline); // lbrace
-
- // const cases = switch_node.cases();
- // for (cases) |node, i| {
- // try renderExpression(ais, tree, node, Space.Comma);
-
- // if (i + 1 < cases.len) {
- // try renderExtraNewline(ais, tree, cases[i + 1]);
- // }
- // }
- // }
-
- // return renderToken(ais, tree, switch_node.rbrace, space); // rbrace
- //},
-
- .SwitchCaseOne => unreachable, // TODO
- .SwitchCaseMulti => unreachable, // TODO
- //.SwitchCase => {
- // const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);
-
- // assert(switch_case.items_len != 0);
- // const src_has_trailing_comma = blk: {
- // const last_node = switch_case.items()[switch_case.items_len - 1];
- // const maybe_comma = tree.nextToken(last_node.lastToken());
- // break :blk tree.token_tags[maybe_comma] == .Comma;
- // };
-
- // if (switch_case.items_len == 1 or !src_has_trailing_comma) {
- // const items = switch_case.items();
- // for (items) |node, i| {
- // if (i + 1 < items.len) {
- // try renderExpression(ais, tree, node, Space.None);
-
- // const comma_token = tree.nextToken(node.lastToken());
- // try renderToken(ais, tree, comma_token, Space.Space); // ,
- // try renderExtraNewline(ais, tree, items[i + 1]);
- // } else {
- // try renderExpression(ais, tree, node, Space.Space);
- // }
- // }
- // } else {
- // const items = switch_case.items();
- // for (items) |node, i| {
- // if (i + 1 < items.len) {
- // try renderExpression(ais, tree, node, Space.None);
-
- // const comma_token = tree.nextToken(node.lastToken());
- // try renderToken(ais, tree, comma_token, Space.Newline); // ,
- // try renderExtraNewline(ais, tree, items[i + 1]);
- // } else {
- // try renderExpression(ais, tree, node, Space.Comma);
- // }
- // }
- // }
-
- // try renderToken(ais, tree, switch_case.arrow_token, Space.Space); // =>
-
- // if (switch_case.payload) |payload| {
- // try renderExpression(ais, tree, payload, Space.Space);
- // }
+ .Switch,
+ .SwitchComma,
+ => {
+ const switch_token = main_tokens[node];
+ const condition = datas[node].lhs;
+ const extra = tree.extraData(datas[node].rhs, ast.Node.SubRange);
+ const cases = tree.extra_data[extra.start..extra.end];
+ const rparen = tree.lastToken(condition) + 1;
+
+ try renderToken(ais, tree, switch_token, .Space); // switch keyword
+ try renderToken(ais, tree, switch_token + 1, .None); // lparen
+ try renderExpression(ais, tree, condition, .None); // condtion expression
+ try renderToken(ais, tree, rparen, .Space); // rparen
+
+ if (cases.len == 0) {
+ try renderToken(ais, tree, rparen + 1, .None); // lbrace
+ try renderToken(ais, tree, rparen + 2, space); // rbrace
+ } else {
+ try renderToken(ais, tree, rparen + 1, .Newline); // lbrace
+ ais.pushIndent();
+ try renderExpression(ais, tree, cases[0], .Comma);
+ for (cases[1..]) |case| {
+ try renderExtraNewline(ais, tree, case);
+ try renderExpression(ais, tree, case, .Comma);
+ }
+ ais.popIndent();
+ try renderToken(ais, tree, tree.lastToken(node), space); // rbrace
+ }
+ },
- // return renderExpression(ais, tree, switch_case.expr, space);
- //},
+ .SwitchCaseOne => try renderSwitchCase(ais, tree, tree.switchCaseOne(node), space),
+ .SwitchCase => try renderSwitchCase(ais, tree, tree.switchCase(node), space),
.WhileSimple => unreachable, // TODO
.WhileCont => unreachable, // TODO
@@ -1745,16 +1615,64 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.Full.FnProto, space: S
return renderExpression(ais, tree, fn_proto.ast.return_type, space);
}
+fn renderSwitchCase(
+ ais: *Ais,
+ tree: ast.Tree,
+ switch_case: ast.Full.SwitchCase,
+ space: Space,
+) Error!void {
+ const token_tags = tree.tokens.items(.tag);
+ const trailing_comma = token_tags[switch_case.ast.arrow_token - 1] == .Comma;
+
+ // Render everything before the arrow
+ if (switch_case.ast.values.len == 0) {
+ try renderToken(ais, tree, switch_case.ast.arrow_token - 1, .Space); // else keyword
+ } else if (switch_case.ast.values.len == 1) {
+ // render on one line and drop the trailing comma if any
+ try renderExpression(ais, tree, switch_case.ast.values[0], .Space);
+ } else if (trailing_comma) {
+ // Render each value on a new line
+ try renderExpression(ais, tree, switch_case.ast.values[0], .Comma);
+ for (switch_case.ast.values[1..]) |value_expr| {
+ try renderExtraNewline(ais, tree, value_expr);
+ try renderExpression(ais, tree, value_expr, .Comma);
+ }
+ } else {
+ // Render on one line
+ for (switch_case.ast.values) |value_expr| {
+ try renderExpression(ais, tree, value_expr, .CommaSpace);
+ }
+ }
+
+ // Render the arrow and everything after it
+ try renderToken(ais, tree, switch_case.ast.arrow_token, .Space);
+
+ if (switch_case.payload_token) |payload_token| {
+ try renderToken(ais, tree, payload_token - 1, .None); // pipe
+ if (token_tags[payload_token] == .Asterisk) {
+ try renderToken(ais, tree, payload_token, .None); // asterisk
+ try renderToken(ais, tree, payload_token + 1, .None); // identifier
+ try renderToken(ais, tree, payload_token + 2, .Space); // pipe
+ } else {
+ try renderToken(ais, tree, payload_token, .None); // identifier
+ try renderToken(ais, tree, payload_token + 1, .Space); // pipe
+ }
+ }
+
+ try renderExpression(ais, tree, switch_case.ast.target_expr, space);
+}
+
fn renderBlock(
ais: *Ais,
tree: ast.Tree,
- lbrace: ast.TokenIndex,
+ block_node: ast.Node.Index,
statements: []const ast.Node.Index,
space: Space,
) Error!void {
const token_tags = tree.tokens.items(.tag);
const node_tags = tree.nodes.items(.tag);
const nodes_data = tree.nodes.items(.data);
+ const lbrace = tree.nodes.items(.main_token)[block_node];
if (token_tags[lbrace - 1] == .Colon and
token_tags[lbrace - 2] == .Identifier)
@@ -1783,15 +1701,8 @@ fn renderBlock(
}
}
ais.popIndent();
- // The rbrace could be +1 or +2 from the last token of the last
- // statement in the block because lastToken() does not count semicolons.
- const maybe_rbrace = tree.lastToken(statements[statements.len - 1]) + 1;
- if (token_tags[maybe_rbrace] == .RBrace) {
- return renderToken(ais, tree, maybe_rbrace, space);
- } else {
- assert(token_tags[maybe_rbrace + 1] == .RBrace);
- return renderToken(ais, tree, maybe_rbrace + 1, space);
- }
+
+ try renderToken(ais, tree, tree.lastToken(block_node), space); // rbrace
}
// TODO: handle comments between fields