Skip to content

Commit

Permalink
zig fmt: simplify and improve consistency of if/for/while handling
Browse files Browse the repository at this point in the history
The main realization here was that getting rid of the early returns
in renderWhile() and rewriting the logic into a mostly unified execution
path took things from ~200 lines to ~100 lines and improved consistency
by deduplicating code.

Also add several test cases and fix a few issues along the way:

Fixes ziglang#6114
Fixes ziglang#8022
  • Loading branch information
ifreund authored and rgreenblatt committed Mar 19, 2021
1 parent 7283fc0 commit f12f2ad
Show file tree
Hide file tree
Showing 2 changed files with 296 additions and 147 deletions.
218 changes: 217 additions & 1 deletion lib/std/zig/parser_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3186,7 +3186,7 @@ test "zig fmt: for" {

test "zig fmt: for if" {
try testCanonical(
\\test "for if" {
\\test {
\\ for (a) |x| if (x) f(x);
\\
\\ for (a) |x| if (x)
Expand All @@ -3209,6 +3209,131 @@ test "zig fmt: for if" {
);
}

test "zig fmt: if for" {
try testCanonical(
\\test {
\\ if (a) for (x) |x| f(x);
\\
\\ if (a) for (x) |x|
\\ f(x);
\\
\\ if (a) for (x) |x| {
\\ f(x);
\\ };
\\
\\ if (a)
\\ for (x) |x|
\\ f(x);
\\
\\ if (a)
\\ for (x) |x| {
\\ f(x);
\\ };
\\}
\\
);
}

test "zig fmt: while if" {
try testCanonical(
\\test {
\\ while (a) if (x) f(x);
\\
\\ while (a) if (x)
\\ f(x);
\\
\\ while (a) if (x) {
\\ f(x);
\\ };
\\
\\ while (a)
\\ if (x)
\\ f(x);
\\
\\ while (a)
\\ if (x) {
\\ f(x);
\\ };
\\}
\\
);
}

test "zig fmt: if while" {
try testCanonical(
\\test {
\\ if (a) while (x) : (cont) f(x);
\\
\\ if (a) while (x) : (cont)
\\ f(x);
\\
\\ if (a) while (x) : (cont) {
\\ f(x);
\\ };
\\
\\ if (a)
\\ while (x) : (cont)
\\ f(x);
\\
\\ if (a)
\\ while (x) : (cont) {
\\ f(x);
\\ };
\\}
\\
);
}

test "zig fmt: while for" {
try testCanonical(
\\test {
\\ while (a) for (x) |x| f(x);
\\
\\ while (a) for (x) |x|
\\ f(x);
\\
\\ while (a) for (x) |x| {
\\ f(x);
\\ };
\\
\\ while (a)
\\ for (x) |x|
\\ f(x);
\\
\\ while (a)
\\ for (x) |x| {
\\ f(x);
\\ };
\\}
\\
);
}

test "zig fmt: for while" {
try testCanonical(
\\test {
\\ for (a) |a| while (x) |x| f(x);
\\
\\ for (a) |a| while (x) |x|
\\ f(x);
\\
\\ for (a) |a| while (x) |x| {
\\ f(x);
\\ };
\\
\\ for (a) |a|
\\ while (x) |x|
\\ f(x);
\\
\\ for (a) |a|
\\ while (x) |x| {
\\ f(x);
\\ };
\\}
\\
);
}

test "zig fmt: if" {
try testCanonical(
\\test "if" {
Expand Down Expand Up @@ -3258,6 +3383,82 @@ test "zig fmt: if" {
);
}

test "zig fmt: fix single statement if/for/while line breaks" {
try testTransform(
\\test {
\\ if (cond) a
\\ else b;
\\
\\ if (cond)
\\ a
\\ else b;
\\
\\ for (xs) |x| foo()
\\ else bar();
\\
\\ for (xs) |x|
\\ foo()
\\ else bar();
\\
\\ while (a) : (b) foo()
\\ else bar();
\\
\\ while (a) : (b)
\\ foo()
\\ else bar();
\\}
\\
,
\\test {
\\ if (cond) a else b;
\\
\\ if (cond)
\\ a
\\ else
\\ b;
\\
\\ for (xs) |x| foo() else bar();
\\
\\ for (xs) |x|
\\ foo()
\\ else
\\ bar();
\\
\\ while (a) : (b) foo() else bar();
\\
\\ while (a) : (b)
\\ foo()
\\ else
\\ bar();
\\}
\\
);
}

test "zig fmt: anon struct/array literal in if" {
try testCanonical(
\\test {
\\ const a = if (cond) .{
\\ 1, 2,
\\ 3, 4,
\\ } else .{
\\ 1,
\\ 2,
\\ 3,
\\ };
\\
\\ const rl_and_tag: struct { rl: ResultLoc, tag: zir.Inst.Tag } = if (any_payload_is_ref) .{
\\ .rl = .ref,
\\ .tag = .switchbr_ref,
\\ } else .{
\\ .rl = .none,
\\ .tag = .switchbr,
\\ };
\\}
\\
);
}

test "zig fmt: defer" {
try testCanonical(
\\test "defer" {
Expand Down Expand Up @@ -3845,13 +4046,28 @@ test "zig fmt: comments in ternary ifs" {
\\ // Comment
\\ 1
\\else
\\ // Comment
\\ 0;
\\
\\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
\\
);
}

test "zig fmt: while statement in blockless if" {
try testCanonical(
\\pub fn main() void {
\\ const zoom_node = if (focused_node == layout_first)
\\ while (it.next()) |node| {
\\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node;
\\ } else null
\\ else
\\ focused_node;
\\}
\\
);
}

test "zig fmt: test comments in field access chain" {
try testCanonical(
\\pub const str = struct {
Expand Down
Loading

0 comments on commit f12f2ad

Please sign in to comment.