From 6f4a1bafcf9cc1120881dabc462b46696481720e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 23 Feb 2021 16:09:51 -0700 Subject: [PATCH] zig fmt: fn call with comments and multiline strings forcing the parameters over multiple lines --- lib/std/zig/parser_test.zig | 78 ++++++++++++++++++------------------- lib/std/zig/render.zig | 32 ++++++++++----- 2 files changed, 62 insertions(+), 48 deletions(-) diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 9701cd4e29..17e0701621 100644 --- a/lib/std/zig/parser_test.zig +++ b/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( diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index bd25868e12..3a37781de6 100644 --- a/lib/std/zig/render.zig +++ b/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),