diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 4ce355dc87..152056c6b4 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -1,3 +1,32 @@ +test "zig fmt: multiline string with backslash at end of line" { + try testCanonical( + \\comptime { + \\ err( + \\ \\\ + \\ ); + \\} + \\ + ); +} + +test "zig fmt: multiline string parameter in fn call with trailing comma" { + try testCanonical( + \\fn foo() void { + \\ try stdout.print( + \\ \\ZIG_CMAKE_BINARY_DIR {} + \\ \\ZIG_C_HEADER_FILES {} + \\ \\ZIG_DIA_GUIDS_LIB {} + \\ \\ + \\ , + \\ std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR), + \\ std.cstr.toSliceConst(c.ZIG_CXX_COMPILER), + \\ std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB), + \\ ); + \\} + \\ + ); +} + test "zig fmt: trailing comma on fn call" { try testCanonical( \\comptime { diff --git a/std/zig/render.zig b/std/zig/render.zig index f068e652bb..409828e070 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -393,15 +393,21 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind var it = call_info.params.iterator(0); while (true) { const param_node = ??it.next(); - try stream.writeByteNTimes(' ', new_indent); + + const param_node_new_indent = if (param_node.*.id == ast.Node.Id.MultilineStringLiteral) blk: { + break :blk indent; + } else blk: { + try stream.writeByteNTimes(' ', new_indent); + break :blk new_indent; + }; if (it.peek()) |next_node| { - try renderExpression(allocator, stream, tree, new_indent, param_node.*, Space.None); + try renderExpression(allocator, stream, tree, param_node_new_indent, param_node.*, Space.None); const comma = tree.nextToken(param_node.*.lastToken()); try renderToken(tree, stream, comma, new_indent, Space.Newline); // , try renderExtraNewline(tree, stream, next_node.*); } else { - try renderTrailingComma(allocator, stream, tree, new_indent, param_node.*, Space.Newline); + try renderTrailingComma(allocator, stream, tree, param_node_new_indent, param_node.*, Space.Newline); try stream.writeByteNTimes(' ', indent); try renderToken(tree, stream, suffix_op.rtoken, indent, space); return; @@ -1502,7 +1508,13 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent if (next_token.id != Token.Id.LineComment) { switch (space) { Space.None, Space.NoNewline, Space.NoIndent => return, - Space.Newline => return stream.write("\n"), + Space.Newline => { + if (next_token.id == Token.Id.MultilineStringLiteralLine) { + return; + } else { + return stream.write("\n"); + } + }, Space.Space => return stream.writeByte(' '), Space.NoComment => unreachable, } @@ -1526,7 +1538,13 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent }; try stream.writeByteNTimes(' ', next_line_indent); }, - Space.Newline, Space.NoIndent => try stream.write("\n"), + Space.Newline, Space.NoIndent => { + if (next_token.id == Token.Id.MultilineStringLiteralLine) { + return; + } else { + return stream.write("\n"); + } + }, Space.NoNewline => {}, Space.NoComment => unreachable, } @@ -1547,7 +1565,13 @@ fn renderToken(tree: &ast.Tree, stream: var, token_index: ast.TokenIndex, indent next_token = tree.tokens.at(token_index + offset); if (next_token.id != Token.Id.LineComment) { switch (space) { - Space.Newline, Space.NoIndent => try stream.writeByte('\n'), + Space.Newline, Space.NoIndent => { + if (next_token.id == Token.Id.MultilineStringLiteralLine) { + return; + } else { + return stream.write("\n"); + } + }, Space.None, Space.Space => { try stream.writeByte('\n'); diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig index f4cd847dff..b90a40108f 100644 --- a/std/zig/tokenizer.zig +++ b/std/zig/tokenizer.zig @@ -217,7 +217,6 @@ pub const Tokenizer = struct { StringLiteral, StringLiteralBackslash, MultilineStringLiteralLine, - MultilineStringLiteralLineBackslash, CharLiteral, CharLiteralBackslash, CharLiteralEscape1, @@ -655,9 +654,6 @@ pub const Tokenizer = struct { }, State.MultilineStringLiteralLine => switch (c) { - '\\' => { - state = State.MultilineStringLiteralLineBackslash; - }, '\n' => { self.index += 1; break; @@ -665,13 +661,6 @@ pub const Tokenizer = struct { else => self.checkLiteralCharacter(), }, - State.MultilineStringLiteralLineBackslash => switch (c) { - '\n' => break, // Look for this error later. - else => { - state = State.MultilineStringLiteralLine; - }, - }, - State.Bang => switch (c) { '=' => { result.id = Token.Id.BangEqual; @@ -1010,7 +999,6 @@ pub const Tokenizer = struct { State.FloatExponentUnsignedHex, State.SawAtSign, State.Backslash, - State.MultilineStringLiteralLineBackslash, State.CharLiteral, State.CharLiteralBackslash, State.CharLiteralEscape1,