From 69d5a106da3fd339c7d1ed177b706aa30d8cb1a9 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 22 Feb 2021 16:59:44 +0200 Subject: [PATCH] render: handle comments ending in EOF --- lib/std/zig/parser_test.zig | 37 +++++++++++++++++++++++-------------- lib/std/zig/render.zig | 30 +++++++++++++++++++++++++----- src/main.zig | 3 +-- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 3802427af2..9748c07557 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -84,6 +84,15 @@ test "zig fmt: empty file" { ); } +test "zig fmt: file ends in comment" { + try testTransform( + \\ //foobar + , + \\//foobar + \\ + ); +} + test "zig fmt: doc comments on test" { try testCanonical( \\/// hello @@ -3385,20 +3394,20 @@ test "zig fmt: file ends with struct field" { ); } -//test "zig fmt: comment after empty comment" { -// try testTransform( -// \\const x = true; // -// \\// -// \\// -// \\//a -// \\ -// , -// \\const x = true; -// \\//a -// \\ -// ); -//} -// +test "zig fmt: comment after empty comment" { + try testTransform( + \\const x = true; // + \\// + \\// + \\//a + \\ + , + \\const x = true; + \\//a + \\ + ); +} + //test "zig fmt: line comment in array" { // try testTransform( // \\test "a" { diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index b9edbbf515..cbed4ac14d 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -26,7 +26,10 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void { const ais = &auto_indenting_stream; // Render all the line comments at the beginning of the file. - const comment_end_loc: usize = tree.tokens.items(.start)[0]; + const comment_end_loc = if (tree.tokens.items(.tag)[0] == .eof) + tree.source.len + else + tree.tokens.items(.start)[0]; _ = try renderComments(ais, tree, 0, comment_end_loc); try renderMembers(ais, tree, tree.rootDecls()); @@ -1995,11 +1998,20 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp /// that end is the last byte before the next token. fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!bool { var index: usize = start; + var rendered_empty_comments = false; while (mem.indexOf(u8, tree.source[index..end], "//")) |offset| { const comment_start = index + offset; - const newline = comment_start + - mem.indexOfScalar(u8, tree.source[comment_start..end], '\n').?; - + const newline_index = mem.indexOfScalar(u8, tree.source[comment_start..end], '\n') orelse { + // comment ends in EOF. + const untrimmed_comment = tree.source[comment_start..]; + const trimmed_comment = mem.trimRight(u8, untrimmed_comment, &std.ascii.spaces); + if (trimmed_comment.len != 2) { + try ais.writer().print("{s}\n", .{trimmed_comment}); + index = end; + } + return index != start; + }; + const newline = comment_start + newline_index; const untrimmed_comment = tree.source[comment_start..newline]; const trimmed_comment = mem.trimRight(u8, untrimmed_comment, &std.ascii.spaces); @@ -2013,6 +2025,11 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo // Respect the newline directly before the comment. // Note: This allows an empty line between comments try ais.insertNewline(); + } else if (trimmed_comment.len == 2) { + if (!rendered_empty_comments) { + try ais.writer().writeByte('\n'); + rendered_empty_comments = true; + } } else if (index == start) { // Otherwise if the first comment is on the same line as // the token before it, prefix it with a single space. @@ -2020,7 +2037,10 @@ fn renderComments(ais: *Ais, tree: ast.Tree, start: usize, end: usize) Error!boo } } - try ais.writer().print("{s}\n", .{trimmed_comment}); + if (trimmed_comment.len != 2) { + try ais.writer().print("{s}\n", .{trimmed_comment}); + rendered_empty_comments = false; + } index = newline + 1; if (ais.disabled_offset) |disabled_offset| { diff --git a/src/main.zig b/src/main.zig index 09d791cfb5..38da3d5a3b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2866,8 +2866,7 @@ fn fmtPathFile( try fmt.out_buffer.ensureCapacity(source_code.len); try tree.renderToArrayList(&fmt.out_buffer); - const anything_changed = mem.eql(u8, fmt.out_buffer.items, source_code); - if (!anything_changed) + if (mem.eql(u8, fmt.out_buffer.items, source_code)) return; if (check_mode) {