Commit 6f4a1bafcf

Andrew Kelley <andrew@ziglang.org>
2021-02-24 00:09:51
zig fmt: fn call with comments and multiline strings
forcing the parameters over multiple lines
1 parent 4ee368c
Changed files (2)
lib/std/zig/parser_test.zig
@@ -4049,45 +4049,45 @@ test "zig fmt: allow trailing line comments to do manual array formatting" {
 //    );
 //}
 
-//test "zig fmt: use of comments and Multiline string literals may force the parameters over multiple lines" {
-//    try testCanonical(
-//        \\pub fn makeMemUndefined(qzz: []u8) i1 {
-//        \\    cases.add( // fixed bug #2032
-//        \\        "compile diagnostic string for top level decl type",
-//        \\        \\export fn entry() void {
-//        \\        \\    var foo: u32 = @This(){};
-//        \\        \\}
-//        \\    , &[_][]const u8{
-//        \\        "tmp.zig:2:27: error: type 'u32' does not support array initialization",
-//        \\    });
-//        \\    @compileError(
-//        \\        \\ unknown-length pointers and C pointers cannot be hashed deeply.
-//        \\        \\ Consider providing your own hash function.
-//        \\        \\ unknown-length pointers and C pointers cannot be hashed deeply.
-//        \\        \\ Consider providing your own hash function.
-//        \\    );
-//        \\    return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
-//        \\        .MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
-//        \\}
-//        \\
-//        \\// This looks like garbage don't do this
-//        \\const rparen = tree.prevToken(
-//        \\// the first token for the annotation expressions is the left
-//        \\// parenthesis, hence the need for two prevToken
-//        \\    if (fn_proto.getAlignExpr()) |align_expr|
-//        \\    tree.prevToken(tree.prevToken(align_expr.firstToken()))
-//        \\else if (fn_proto.getSectionExpr()) |section_expr|
-//        \\    tree.prevToken(tree.prevToken(section_expr.firstToken()))
-//        \\else if (fn_proto.getCallconvExpr()) |callconv_expr|
-//        \\    tree.prevToken(tree.prevToken(callconv_expr.firstToken()))
-//        \\else switch (fn_proto.return_type) {
-//        \\    .Explicit => |node| node.firstToken(),
-//        \\    .InferErrorSet => |node| tree.prevToken(node.firstToken()),
-//        \\    .Invalid => unreachable,
-//        \\});
-//        \\
-//    );
-//}
+test "zig fmt: use of comments and multiline string literals may force the parameters over multiple lines" {
+    try testCanonical(
+        \\pub fn makeMemUndefined(qzz: []u8) i1 {
+        \\    cases.add( // fixed bug foo
+        \\        "compile diagnostic string for top level decl type",
+        \\        \\export fn entry() void {
+        \\        \\    var foo: u32 = @This(){};
+        \\        \\}
+        \\    , &[_][]const u8{
+        \\        "tmp.zig:2:27: error: type 'u32' does not support array initialization",
+        \\    });
+        \\    @compileError(
+        \\        \\ unknown-length pointers and C pointers cannot be hashed deeply.
+        \\        \\ Consider providing your own hash function.
+        \\        \\ unknown-length pointers and C pointers cannot be hashed deeply.
+        \\        \\ Consider providing your own hash function.
+        \\    );
+        \\    return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
+        \\        .MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
+        \\}
+        \\
+        \\// This looks like garbage don't do this
+        \\const rparen = tree.prevToken(
+        \\// the first token for the annotation expressions is the left
+        \\// parenthesis, hence the need for two prevToken
+        \\if (fn_proto.getAlignExpr()) |align_expr|
+        \\    tree.prevToken(tree.prevToken(align_expr.firstToken()))
+        \\else if (fn_proto.getSectionExpr()) |section_expr|
+        \\    tree.prevToken(tree.prevToken(section_expr.firstToken()))
+        \\else if (fn_proto.getCallconvExpr()) |callconv_expr|
+        \\    tree.prevToken(tree.prevToken(callconv_expr.firstToken()))
+        \\else switch (fn_proto.return_type) {
+        \\    .Explicit => |node| node.firstToken(),
+        \\    .InferErrorSet => |node| tree.prevToken(node.firstToken()),
+        \\    .Invalid => unreachable,
+        \\});
+        \\
+    );
+}
 
 test "zig fmt: single argument trailing commas in @builtins()" {
     try testCanonical(
lib/std/zig/render.zig
@@ -1291,6 +1291,12 @@ fn renderBuiltinCall(
         try renderToken(ais, tree, builtin_token + 1, .none); // (
 
         for (params) |param_node, i| {
+            const first_param_token = tree.firstToken(param_node);
+            if (token_tags[first_param_token] == .multiline_string_literal_line or
+                hasSameLineComment(tree, first_param_token - 1))
+            {
+                ais.pushIndentOneShot();
+            }
             try renderExpression(gpa, ais, tree, param_node, .none);
 
             if (i + 1 < params.len) {
@@ -1733,12 +1739,8 @@ fn renderArrayInit(
 
                 const maybe_comma = expr_last_token + 1;
                 if (token_tags[maybe_comma] == .comma) {
-                    const after_comma_src = tree.source[token_starts[maybe_comma]..token_starts[maybe_comma + 1]];
-                    for (after_comma_src) |byte| switch (byte) {
-                        '\n' => break,
-                        '/' => break :sec_end i - this_line_size.? + 1,
-                        else => continue,
-                    };
+                    if (hasSameLineComment(tree, maybe_comma))
+                        break :sec_end i - this_line_size.? + 1;
                 }
             }
             break :sec_end row_exprs.len;
@@ -2106,9 +2108,10 @@ fn renderCall(
     try renderToken(ais, tree, lparen, .none); // (
 
     for (params) |param_node, i| {
-        const this_multiline_string =
-            token_tags[tree.firstToken(param_node)] == .multiline_string_literal_line;
-        if (this_multiline_string) {
+        const first_param_token = tree.firstToken(param_node);
+        if (token_tags[first_param_token] == .multiline_string_literal_line or
+            hasSameLineComment(tree, first_param_token - 1))
+        {
             ais.pushIndentOneShot();
         }
         try renderExpression(gpa, ais, tree, param_node, .none);
@@ -2339,6 +2342,17 @@ fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 {
     return ret;
 }
 
+fn hasSameLineComment(tree: ast.Tree, token_index: ast.TokenIndex) bool {
+    const token_starts = tree.tokens.items(.start);
+    const between_source = tree.source[token_starts[token_index]..token_starts[token_index + 1]];
+    for (between_source) |byte| switch (byte) {
+        '\n' => return false,
+        '/' => return true,
+        else => continue,
+    };
+    return false;
+}
+
 fn writeFixingWhitespace(writer: std.ArrayList(u8).Writer, slice: []const u8) Error!void {
     for (slice) |byte| switch (byte) {
         '\t' => try writer.writeAll(" " ** 4),