mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Always write a multiline struct literal if a field expr is multiline
This commit is contained in:
parent
aa794eb621
commit
0563e8e1d4
@ -393,6 +393,50 @@ test "zig fmt: struct literal no trailing comma" {
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: struct literal containing a multiline expression" {
|
||||
try testTransform(
|
||||
\\const a = A{ .x = if (f1()) 10 else 20 };
|
||||
\\const a = A{ .x = if (f1()) 10 else 20, };
|
||||
\\const a = A{ .x = if (f1())
|
||||
\\ 10 else 20 };
|
||||
\\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 };
|
||||
\\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100, };
|
||||
\\const a = A{ .x = if (f1())
|
||||
\\ 10 else 20};
|
||||
\\const a = A{ .x = switch(g) {0 => "ok", else => "no"} };
|
||||
\\
|
||||
,
|
||||
\\const a = A{ .x = if (f1()) 10 else 20 };
|
||||
\\const a = A{
|
||||
\\ .x = if (f1()) 10 else 20,
|
||||
\\};
|
||||
\\const a = A{
|
||||
\\ .x = if (f1())
|
||||
\\ 10
|
||||
\\ else
|
||||
\\ 20,
|
||||
\\};
|
||||
\\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 };
|
||||
\\const a = A{
|
||||
\\ .x = if (f1()) 10 else 20,
|
||||
\\ .y = f2() + 100,
|
||||
\\};
|
||||
\\const a = A{
|
||||
\\ .x = if (f1())
|
||||
\\ 10
|
||||
\\ else
|
||||
\\ 20,
|
||||
\\};
|
||||
\\const a = A{
|
||||
\\ .x = switch (g) {
|
||||
\\ 0 => "ok",
|
||||
\\ else => "no",
|
||||
\\ },
|
||||
\\};
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: array literal with hint" {
|
||||
try testTransform(
|
||||
\\const a = []u8{
|
||||
|
||||
@ -596,21 +596,6 @@ fn renderExpression(
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
|
||||
}
|
||||
|
||||
if (field_inits.len == 1) blk: {
|
||||
const field_init = field_inits.at(0).*.cast(ast.Node.FieldInitializer).?;
|
||||
|
||||
if (field_init.expr.cast(ast.Node.SuffixOp)) |nested_suffix_op| {
|
||||
if (nested_suffix_op.op == ast.Node.SuffixOp.Op.StructInitializer) {
|
||||
break :blk;
|
||||
}
|
||||
}
|
||||
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
|
||||
}
|
||||
|
||||
const src_has_trailing_comma = blk: {
|
||||
const maybe_comma = tree.prevToken(suffix_op.rtoken);
|
||||
break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
|
||||
@ -621,7 +606,39 @@ fn renderExpression(
|
||||
break :blk loc.line == 0;
|
||||
};
|
||||
|
||||
if (!src_has_trailing_comma and src_same_line) {
|
||||
const expr_outputs_one_line = blk: {
|
||||
// render field expressions until a LF is found
|
||||
var it = field_inits.iterator(0);
|
||||
while (it.next()) |field_init| {
|
||||
var find_stream = FindByteOutStream.init('\n');
|
||||
var dummy_col: usize = 0;
|
||||
try renderExpression(allocator, &find_stream.stream, tree, 0, &dummy_col, field_init.*, Space.None);
|
||||
if (find_stream.byte_found) break :blk false;
|
||||
}
|
||||
break :blk true;
|
||||
};
|
||||
|
||||
if (field_inits.len == 1) blk: {
|
||||
const field_init = field_inits.at(0).*.cast(ast.Node.FieldInitializer).?;
|
||||
|
||||
if (field_init.expr.cast(ast.Node.SuffixOp)) |nested_suffix_op| {
|
||||
if (nested_suffix_op.op == ast.Node.SuffixOp.Op.StructInitializer) {
|
||||
break :blk;
|
||||
}
|
||||
}
|
||||
|
||||
// if the expression outputs to multiline, make this struct multiline
|
||||
if (!expr_outputs_one_line or src_has_trailing_comma) {
|
||||
break :blk;
|
||||
}
|
||||
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
|
||||
return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
|
||||
}
|
||||
|
||||
if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) {
|
||||
// render all on one line, no trailing comma
|
||||
try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
|
||||
try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
|
||||
@ -2092,3 +2109,33 @@ fn nodeCausesSliceOpSpace(base: *ast.Node) bool {
|
||||
else => true,
|
||||
};
|
||||
}
|
||||
|
||||
// An OutStream that returns whether the given character has been written to it.
|
||||
// The contents are not written to anything.
|
||||
const FindByteOutStream = struct {
|
||||
const Self = FindByteOutStream;
|
||||
pub const Error = error{};
|
||||
pub const Stream = std.io.OutStream(Error);
|
||||
|
||||
pub stream: Stream,
|
||||
pub byte_found: bool,
|
||||
byte: u8,
|
||||
|
||||
pub fn init(byte: u8) Self {
|
||||
return Self{
|
||||
.stream = Stream{ .writeFn = writeFn },
|
||||
.byte = byte,
|
||||
.byte_found = false,
|
||||
};
|
||||
}
|
||||
|
||||
fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
|
||||
const self = @fieldParentPtr(Self, "stream", out_stream);
|
||||
if (self.byte_found) return;
|
||||
self.byte_found = blk: {
|
||||
for (bytes) |b|
|
||||
if (b == self.byte) break :blk true;
|
||||
break :blk false;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user