authorgravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-03-31 16:38:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-31 21:09:56-04:00
log0563e8e1d4181a2707a1898941ccf59d974bc835
treefadccfcc0542927df8b7cd4084255c449e13df28
parentaa794eb621d328f8e96e3458602b926d610598ec

Always write a multiline struct literal if a field expr is multiline


2 files changed, 102 insertions(+), 11 deletions(-)

std/zig/parser_test.zig+44
...@@ -393,6 +393,50 @@ test "zig fmt: struct literal no trailing comma" {...@@ -393,6 +393,50 @@ test "zig fmt: struct literal no trailing comma" {
393 );393 );
394}394}
395395
396test "zig fmt: struct literal containing a multiline expression" {
397 try testTransform(
398 \\const a = A{ .x = if (f1()) 10 else 20 };
399 \\const a = A{ .x = if (f1()) 10 else 20, };
400 \\const a = A{ .x = if (f1())
401 \\ 10 else 20 };
402 \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 };
403 \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100, };
404 \\const a = A{ .x = if (f1())
405 \\ 10 else 20};
406 \\const a = A{ .x = switch(g) {0 => "ok", else => "no"} };
407 \\
408 ,
409 \\const a = A{ .x = if (f1()) 10 else 20 };
410 \\const a = A{
411 \\ .x = if (f1()) 10 else 20,
412 \\};
413 \\const a = A{
414 \\ .x = if (f1())
415 \\ 10
416 \\ else
417 \\ 20,
418 \\};
419 \\const a = A{ .x = if (f1()) 10 else 20, .y = f2() + 100 };
420 \\const a = A{
421 \\ .x = if (f1()) 10 else 20,
422 \\ .y = f2() + 100,
423 \\};
424 \\const a = A{
425 \\ .x = if (f1())
426 \\ 10
427 \\ else
428 \\ 20,
429 \\};
430 \\const a = A{
431 \\ .x = switch (g) {
432 \\ 0 => "ok",
433 \\ else => "no",
434 \\ },
435 \\};
436 \\
437 );
438}
439
396test "zig fmt: array literal with hint" {440test "zig fmt: array literal with hint" {
397 try testTransform(441 try testTransform(
398 \\const a = []u8{442 \\const a = []u8{
std/zig/render.zig+58-11
...@@ -596,6 +596,28 @@ fn renderExpression(...@@ -596,6 +596,28 @@ fn renderExpression(
596 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);596 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
597 }597 }
598598
599 const src_has_trailing_comma = blk: {
600 const maybe_comma = tree.prevToken(suffix_op.rtoken);
601 break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
602 };
603
604 const src_same_line = blk: {
605 const loc = tree.tokenLocation(tree.tokens.at(lbrace).end, suffix_op.rtoken);
606 break :blk loc.line == 0;
607 };
608
609 const expr_outputs_one_line = blk: {
610 // render field expressions until a LF is found
611 var it = field_inits.iterator(0);
612 while (it.next()) |field_init| {
613 var find_stream = FindByteOutStream.init('\n');
614 var dummy_col: usize = 0;
615 try renderExpression(allocator, &find_stream.stream, tree, 0, &dummy_col, field_init.*, Space.None);
616 if (find_stream.byte_found) break :blk false;
617 }
618 break :blk true;
619 };
620
599 if (field_inits.len == 1) blk: {621 if (field_inits.len == 1) blk: {
600 const field_init = field_inits.at(0).*.cast(ast.Node.FieldInitializer).?;622 const field_init = field_inits.at(0).*.cast(ast.Node.FieldInitializer).?;
601623
...@@ -605,23 +627,18 @@ fn renderExpression(...@@ -605,23 +627,18 @@ fn renderExpression(
605 }627 }
606 }628 }
607629
630 // if the expression outputs to multiline, make this struct multiline
631 if (!expr_outputs_one_line or src_has_trailing_comma) {
632 break :blk;
633 }
634
608 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);635 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
609 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);636 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
610 try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);637 try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
611 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);638 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
612 }639 }
613640
614 const src_has_trailing_comma = blk: {641 if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) {
615 const maybe_comma = tree.prevToken(suffix_op.rtoken);
616 break :blk tree.tokens.at(maybe_comma).id == Token.Id.Comma;
617 };
618
619 const src_same_line = blk: {
620 const loc = tree.tokenLocation(tree.tokens.at(lbrace).end, suffix_op.rtoken);
621 break :blk loc.line == 0;
622 };
623
624 if (!src_has_trailing_comma and src_same_line) {
625 // render all on one line, no trailing comma642 // render all on one line, no trailing comma
626 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);643 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
627 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);644 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
...@@ -2092,3 +2109,33 @@ fn nodeCausesSliceOpSpace(base: *ast.Node) bool {...@@ -2092,3 +2109,33 @@ fn nodeCausesSliceOpSpace(base: *ast.Node) bool {
2092 else => true,2109 else => true,
2093 };2110 };
2094}2111}
2112
2113// An OutStream that returns whether the given character has been written to it.
2114// The contents are not written to anything.
2115const FindByteOutStream = struct {
2116 const Self = FindByteOutStream;
2117 pub const Error = error{};
2118 pub const Stream = std.io.OutStream(Error);
2119
2120 pub stream: Stream,
2121 pub byte_found: bool,
2122 byte: u8,
2123
2124 pub fn init(byte: u8) Self {
2125 return Self{
2126 .stream = Stream{ .writeFn = writeFn },
2127 .byte = byte,
2128 .byte_found = false,
2129 };
2130 }
2131
2132 fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
2133 const self = @fieldParentPtr(Self, "stream", out_stream);
2134 if (self.byte_found) return;
2135 self.byte_found = blk: {
2136 for (bytes) |b|
2137 if (b == self.byte) break :blk true;
2138 break :blk false;
2139 };
2140 }
2141};