renderContainerDecl
Function parameters
Parameters
Type definitions in this namespace
Types
Functions in this namespace
Functions
Error sets in this namespace
Error Sets
Source
Implementation
fn renderContainerDecl(
r: *Render,
container_decl_node: Ast.Node.Index,
container_decl: Ast.full.ContainerDecl,
space: Space,
) Error!void {
const tree = r.tree;
const ais = r.ais;
if (container_decl.layout_token) |layout_token| {
try renderToken(r, layout_token, .space);
}
const container: Container = switch (tree.tokenTag(container_decl.ast.main_token)) {
.keyword_enum => .@"enum",
.keyword_struct => for (container_decl.ast.members) |member| {
if (tree.fullContainerField(member)) |field| if (!field.ast.tuple_like) break .other;
} else .tuple,
else => .other,
};
var lbrace: Ast.TokenIndex = undefined;
if (container_decl.ast.enum_token) |enum_token| {
try renderToken(r, container_decl.ast.main_token, .none); // union
try renderToken(r, enum_token - 1, .none); // lparen
try renderToken(r, enum_token, .none); // enum
if (container_decl.ast.arg.unwrap()) |arg| {
try renderToken(r, enum_token + 1, .none); // lparen
try renderExpression(r, arg, .none);
const rparen = tree.lastToken(arg) + 1;
try renderToken(r, rparen, .none); // rparen
try renderToken(r, rparen + 1, .space); // rparen
lbrace = rparen + 2;
} else {
try renderToken(r, enum_token + 1, .space); // rparen
lbrace = enum_token + 2;
}
} else if (container_decl.ast.arg.unwrap()) |arg| {
try renderToken(r, container_decl.ast.main_token, .none); // union
try renderToken(r, container_decl.ast.main_token + 1, .none); // lparen
try renderExpression(r, arg, .none);
const rparen = tree.lastToken(arg) + 1;
try renderToken(r, rparen, .space); // rparen
lbrace = rparen + 1;
} else {
try renderToken(r, container_decl.ast.main_token, .space); // union
lbrace = container_decl.ast.main_token + 1;
}
const rbrace = tree.lastToken(container_decl_node);
if (container_decl.ast.members.len == 0) {
try ais.pushIndent(.normal);
if (tree.tokenTag(lbrace + 1) == .container_doc_comment) {
try renderToken(r, lbrace, .newline); // lbrace
try renderContainerDocComments(r, lbrace + 1);
} else {
try renderToken(r, lbrace, .none); // lbrace
}
ais.popIndent();
return renderToken(r, rbrace, space); // rbrace
}
const src_has_trailing_comma = tree.tokenTag(rbrace - 1) == .comma;
if (!src_has_trailing_comma) one_line: {
// We print all the members in-line unless one of the following conditions are true:
// 1. The container has comments or multiline strings.
if (hasComment(tree, lbrace, rbrace) or hasMultilineString(tree, lbrace, rbrace)) {
break :one_line;
}
// 2. The container has a container comment.
if (tree.tokenTag(lbrace + 1) == .container_doc_comment) break :one_line;
// 3. A member of the container has a doc comment.
for (tree.tokens.items(.tag)[lbrace + 1 .. rbrace - 1]) |tag| {
if (tag == .doc_comment) break :one_line;
}
// 4. The container has non-field members.
for (container_decl.ast.members) |member| {
if (tree.fullContainerField(member) == null) break :one_line;
}
// Print all the declarations on the same line.
try renderToken(r, lbrace, .space); // lbrace
for (container_decl.ast.members) |member| {
try renderMember(r, container, member, .space);
}
return renderToken(r, rbrace, space); // rbrace
}
// One member per line.
try ais.pushIndent(.normal);
try renderToken(r, lbrace, .newline); // lbrace
if (tree.tokenTag(lbrace + 1) == .container_doc_comment) {
try renderContainerDocComments(r, lbrace + 1);
}
for (container_decl.ast.members, 0..) |member, i| {
if (i != 0) try renderExtraNewline(r, member);
switch (tree.nodeTag(member)) {
// For container fields, ensure a trailing comma is added if necessary.
.container_field_init,
.container_field_align,
.container_field,
=> {
try ais.pushSpace(.comma);
try renderMember(r, container, member, .comma);
ais.popSpace();
},
else => try renderMember(r, container, member, .newline),
}
}
ais.popIndent();
return renderToken(r, rbrace, space); // rbrace
}