Commit 9ea0e4ca68

Andrew Kelley <superjoe30@gmail.com>
2018-05-17 06:15:52
zig fmt: same line comments after tokens in expression
1 parent 967bad4
Changed files (2)
std/zig/parser_test.zig
@@ -1,3 +1,46 @@
+test "zig fmt: same line comments in expression" {
+    try testCanonical(
+        \\test "aoeu" {
+        \\    const x = ( // a
+        \\        0 // b
+        \\    ); // c
+        \\}
+        \\
+    );
+}
+
+//test "zig fmt: line comment between if block and else keyword" {
+//    try testTransform(
+//        test "aoeu" {
+//            // cexp(finite|nan +- i inf|nan) = nan + i nan
+//            if ((hx & 0x7fffffff) != 0x7f800000) {
+//                return Complex(f32).new(y - y, y - y);
+//            }
+//            // cexp(-inf +- i inf|nan) = 0 + i0
+//            else if (hx & 0x80000000 != 0) {
+//                return Complex(f32).new(0, 0);
+//            }
+//            // cexp(+inf +- i inf|nan) = inf + i nan
+//            else {
+//                return Complex(f32).new(x, y - y);
+//            }
+//        }
+//    ,
+//        test "aoeu" {
+//            // cexp(finite|nan +- i inf|nan) = nan + i nan
+//            if ((hx & 0x7fffffff) != 0x7f800000) {
+//                return Complex(f32).new(y - y, y - y);
+//            } // cexp(-inf +- i inf|nan) = 0 + i0
+//            else if (hx & 0x80000000 != 0) {
+//                return Complex(f32).new(0, 0);
+//            } // cexp(+inf +- i inf|nan) = inf + i nan
+//            else {
+//                return Complex(f32).new(x, y - y);
+//            }
+//        }
+//    );
+//}
+
 test "zig fmt: add comma on last switch prong" {
     try testTransform(
         \\test "aoeu" {
std/zig/render.zig
@@ -81,7 +81,7 @@ fn renderTopLevelDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, i
             }
             try stream.print("{}: ", tree.tokenSlice(field.name_token));
             try renderExpression(allocator, stream, tree, indent, field.type_expr);
-            try renderToken(tree, stream, field.lastToken() + 1, indent, true);
+            try renderToken(tree, stream, field.lastToken() + 1, indent, true, true);
         },
         ast.Node.Id.UnionTag => {
             const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);
@@ -513,9 +513,9 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
         ast.Node.Id.GroupedExpression => {
             const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);
 
-            try stream.write("(");
+            try renderToken(tree, stream, grouped_expr.lparen, indent, false, false);
             try renderExpression(allocator, stream, tree, indent, grouped_expr.expr);
-            try stream.write(")");
+            try renderToken(tree, stream, grouped_expr.rparen, indent, false, false);
         },
 
         ast.Node.Id.FieldInitializer => {
@@ -527,7 +527,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
 
         ast.Node.Id.IntegerLiteral => {
             const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);
-            try stream.print("{}", tree.tokenSlice(integer_literal.token));
+            try renderToken(tree, stream, integer_literal.token, indent, false, false);
         },
         ast.Node.Id.FloatLiteral => {
             const float_literal = @fieldParentPtr(ast.Node.FloatLiteral, "base", base);
@@ -535,7 +535,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
         },
         ast.Node.Id.StringLiteral => {
             const string_literal = @fieldParentPtr(ast.Node.StringLiteral, "base", base);
-            try stream.print("{}", tree.tokenSlice(string_literal.token));
+            try renderToken(tree, stream, string_literal.token, indent, false, false);
         },
         ast.Node.Id.CharLiteral => {
             const char_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
@@ -840,9 +840,9 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
                     },
                     Token.Id.LineComment => {
                         try stream.write(", ");
-                        try renderToken(tree, stream, index, indent, true);
+                        try renderToken(tree, stream, index, indent, true, true);
                     },
-                    else => try renderToken(tree, stream, index, indent, true),
+                    else => try renderToken(tree, stream, index, indent, true, true),
                 }
             }
         },
@@ -971,7 +971,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
             try stream.print("{} (", tree.tokenSlice(if_node.if_token));
 
             try renderExpression(allocator, stream, tree, indent, if_node.condition);
-            try renderToken(tree, stream, if_node.condition.lastToken() + 1, indent, false);
+            try renderToken(tree, stream, if_node.condition.lastToken() + 1, indent, false, true);
 
             if (if_node.payload) |payload| {
                 try renderExpression(allocator, stream, tree, indent, payload);
@@ -1126,11 +1126,11 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
 
 fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent: usize, var_decl: &ast.Node.VarDecl) (@typeOf(stream).Child.Error || Error)!void {
     if (var_decl.visib_token) |visib_token| {
-        try stream.print("{} ", tree.tokenSlice(visib_token));
+        try renderToken(tree, stream, visib_token, indent, false, true);
     }
 
     if (var_decl.extern_export_token) |extern_export_token| {
-        try stream.print("{} ", tree.tokenSlice(extern_export_token));
+        try renderToken(tree, stream, extern_export_token, indent, false, true);
 
         if (var_decl.lib_name) |lib_name| {
             try renderExpression(allocator, stream, tree, indent, lib_name);
@@ -1139,10 +1139,11 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent
     }
 
     if (var_decl.comptime_token) |comptime_token| {
-        try stream.print("{} ", tree.tokenSlice(comptime_token));
+        try renderToken(tree, stream, comptime_token, indent, false, true);
     }
 
-    try stream.print("{} {}", tree.tokenSlice(var_decl.mut_token), tree.tokenSlice(var_decl.name_token));
+    try renderToken(tree, stream, var_decl.mut_token, indent, false, true);
+    try renderToken(tree, stream, var_decl.name_token, indent, false, false);
 
     if (var_decl.type_node) |type_node| {
         try stream.write(": ");
@@ -1161,14 +1162,14 @@ fn renderVarDecl(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, indent
         try renderExpression(allocator, stream, tree, indent, init_node);
     }
 
-    try renderToken(tree, stream, var_decl.semicolon_token, indent, true);
+    try renderToken(tree, stream, var_decl.semicolon_token, indent, true, false);
 }
 
 fn maybeRenderSemicolon(stream: var, tree: &ast.Tree, indent: usize, base: &ast.Node) (@typeOf(stream).Child.Error || Error)!void {
     if (base.requireSemiColon()) {
         const semicolon_index = base.lastToken() + 1;
         assert(tree.tokens.at(semicolon_index).id == Token.Id.Semicolon);
-        try renderToken(tree, stream, semicolon_index, indent, true);
+        try renderToken(tree, stream, semicolon_index, indent, true, true);
     }
 }
 
@@ -1203,7 +1204,7 @@ fn renderStatement(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, inde
     }
 }
 
-fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool) (@typeOf(stream).Child.Error || Error)!void {
+fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent: usize, line_break: bool, space: bool) (@typeOf(stream).Child.Error || Error)!void {
     const token = tree.tokens.at(token_index);
     try stream.write(tree.tokenSlicePtr(token));
 
@@ -1214,13 +1215,19 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent
             try stream.print(" {}", tree.tokenSlicePtr(next_token));
             if (!line_break) {
                 try stream.write("\n");
-                try stream.writeByteNTimes(' ', indent + indent_delta);
+
+                const after_comment_token = tree.tokens.at(token_index + 2);
+                const next_line_indent = switch (after_comment_token.id) {
+                    Token.Id.RParen, Token.Id.RBrace, Token.Id.RBracket => indent,
+                    else => indent + indent_delta,
+                };
+                try stream.writeByteNTimes(' ', next_line_indent);
                 return;
             }
         }
     }
 
-    if (!line_break) {
+    if (!line_break and space) {
         try stream.writeByte(' ');
     }
 }