diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 129e62e6dd..ea26f823b5 100644 --- a/std/zig/parser_test.zig +++ b/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" { diff --git a/std/zig/render.zig b/std/zig/render.zig index 5084c1d096..9ce8ba0cbf 100644 --- a/std/zig/render.zig +++ b/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(' '); } }