Commit 4ee368c4b3

Isaac Freund <ifreund@ifreund.xyz>
2021-02-23 23:17:00
zig fmt: comments/line breaks in field access chain
1 parent ca92593
Changed files (2)
lib/std/zig/parser_test.zig
@@ -3790,40 +3790,88 @@ test "zig fmt: comments in ternary ifs" {
     );
 }
 
-//test "zig fmt: test comments in field access chain" {
-//    try testCanonical(
-//        \\pub const str = struct {
-//        \\    pub const Thing = more.more //
-//        \\        .more() //
-//        \\        .more().more() //
-//        \\        .more() //
-//        \\    // .more() //
-//        \\        .more() //
-//        \\        .more();
-//        \\    data: Data,
-//        \\};
-//        \\
-//        \\pub const str = struct {
-//        \\    pub const Thing = more.more //
-//        \\        .more() //
-//        \\    // .more() //
-//        \\    // .more() //
-//        \\    // .more() //
-//        \\        .more() //
-//        \\        .more();
-//        \\    data: Data,
-//        \\};
-//        \\
-//        \\pub const str = struct {
-//        \\    pub const Thing = more //
-//        \\        .more //
-//        \\        .more() //
-//        \\        .more();
-//        \\    data: Data,
-//        \\};
-//        \\
-//    );
-//}
+test "zig fmt: test comments in field access chain" {
+    try testCanonical(
+        \\pub const str = struct {
+        \\    pub const Thing = more.more //
+        \\        .more() //
+        \\        .more().more() //
+        \\        .more() //
+        \\    // .more() //
+        \\        .more() //
+        \\        .more();
+        \\    data: Data,
+        \\};
+        \\
+        \\pub const str = struct {
+        \\    pub const Thing = more.more //
+        \\        .more() //
+        \\    // .more() //
+        \\    // .more() //
+        \\    // .more() //
+        \\        .more() //
+        \\        .more();
+        \\    data: Data,
+        \\};
+        \\
+        \\pub const str = struct {
+        \\    pub const Thing = more //
+        \\        .more //
+        \\        .more() //
+        \\        .more();
+        \\    data: Data,
+        \\};
+        \\
+    );
+}
+
+test "zig fmt: allow line break before field access" {
+    try testCanonical(
+        \\test {
+        \\    const w = foo.bar().zippy(zag).iguessthisisok();
+        \\
+        \\    const x = foo
+        \\        .bar()
+        \\        . // comment
+        \\    // comment
+        \\        swooop().zippy(zag)
+        \\        .iguessthisisok();
+        \\
+        \\    const y = view.output.root.server.input_manager.default_seat.wlr_seat.name;
+        \\
+        \\    const z = view.output.root.server
+        \\        .input_manager //
+        \\        .default_seat
+        \\        . // comment
+        \\    // another comment
+        \\        wlr_seat.name;
+        \\}
+        \\
+    );
+    try testTransform(
+        \\test {
+        \\    const x = foo.
+        \\        bar()
+        \\        .zippy(zag).iguessthisisok();
+        \\
+        \\    const z = view.output.root.server.
+        \\        input_manager.
+        \\        default_seat.wlr_seat.name;
+        \\}
+        \\
+    ,
+        \\test {
+        \\    const x = foo
+        \\        .bar()
+        \\        .zippy(zag).iguessthisisok();
+        \\
+        \\    const z = view.output.root.server
+        \\        .input_manager
+        \\        .default_seat.wlr_seat.name;
+        \\}
+        \\
+    );
+}
 
 test "zig fmt: Indent comma correctly after multiline string literals in arg list (trailing comma)" {
     try testCanonical(
lib/std/zig/render.zig
@@ -298,9 +298,31 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
         },
 
         .field_access => {
+            const main_token = main_tokens[node];
             const field_access = datas[node];
+
             try renderExpression(gpa, ais, tree, field_access.lhs, .none);
-            try renderToken(ais, tree, main_tokens[node], .none);
+
+            // Allow a line break between the lhs and the dot if the lhs and rhs
+            // are on different lines.
+            const lhs_last_token = tree.lastToken(field_access.lhs);
+            const same_line = tree.tokensOnSameLine(lhs_last_token, main_token + 1);
+            if (!same_line) {
+                if (!hasComment(tree, lhs_last_token, main_token)) try ais.insertNewline();
+                ais.pushIndentOneShot();
+            }
+
+            try renderToken(ais, tree, main_token, .none);
+
+            // This check ensures that zag() is indented in the following example:
+            // const x = foo
+            //     .bar()
+            //     . // comment
+            //     zag();
+            if (!same_line and hasComment(tree, main_token, main_token + 1)) {
+                ais.pushIndentOneShot();
+            }
+
             return renderToken(ais, tree, field_access.rhs, space);
         },