authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-29 17:37:02-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-29 17:37:15-04:00
logc03b9010db55e52dfa227b17e35203b93b5ee1df
tree06be415170adf4ea9f500026f115603386f729a5
parent2387292f204c59259fc64d7c960d201e808af5a9

zig fmt: preserve same-line comment after statement


2 files changed, 68 insertions(+), 14 deletions(-)

std/zig/ast.zig+2-1
...@@ -6,7 +6,8 @@ const mem = std.mem;...@@ -6,7 +6,8 @@ const mem = std.mem;
66
7pub const Node = struct {7pub const Node = struct {
8 id: Id,8 id: Id,
9 comments: ?&LineComment,9 before_comments: ?&LineComment,
10 same_line_comment: ?&Token,
1011
11 pub const Id = enum {12 pub const Id = enum {
12 // Top level13 // Top level
std/zig/parser.zig+66-13
...@@ -229,6 +229,7 @@ pub const Parser = struct {...@@ -229,6 +229,7 @@ pub const Parser = struct {
229 ComptimeStatement: ComptimeStatementCtx,229 ComptimeStatement: ComptimeStatementCtx,
230 Semicolon: &&ast.Node,230 Semicolon: &&ast.Node,
231 AddComments: AddCommentsCtx,231 AddComments: AddCommentsCtx,
232 LookForSameLineComment: &&ast.Node,
232233
233 AsmOutputItems: &ArrayList(&ast.Node.AsmOutput),234 AsmOutputItems: &ArrayList(&ast.Node.AsmOutput),
234 AsmOutputReturnOrType: &ast.Node.AsmOutput,235 AsmOutputReturnOrType: &ast.Node.AsmOutput,
...@@ -356,7 +357,8 @@ pub const Parser = struct {...@@ -356,7 +357,8 @@ pub const Parser = struct {
356 const block = try arena.construct(ast.Node.Block {357 const block = try arena.construct(ast.Node.Block {
357 .base = ast.Node {358 .base = ast.Node {
358 .id = ast.Node.Id.Block,359 .id = ast.Node.Id.Block,
359 .comments = null,360 .before_comments = null,
361 .same_line_comment = null,
360 },362 },
361 .label = null,363 .label = null,
362 .lbrace = undefined,364 .lbrace = undefined,
...@@ -366,7 +368,8 @@ pub const Parser = struct {...@@ -366,7 +368,8 @@ pub const Parser = struct {
366 const test_node = try arena.construct(ast.Node.TestDecl {368 const test_node = try arena.construct(ast.Node.TestDecl {
367 .base = ast.Node {369 .base = ast.Node {
368 .id = ast.Node.Id.TestDecl,370 .id = ast.Node.Id.TestDecl,
369 .comments = comments,371 .before_comments = comments,
372 .same_line_comment = null,
370 },373 },
371 .test_token = token,374 .test_token = token,
372 .name = undefined,375 .name = undefined,
...@@ -547,7 +550,8 @@ pub const Parser = struct {...@@ -547,7 +550,8 @@ pub const Parser = struct {
547 const fn_proto = try arena.construct(ast.Node.FnProto {550 const fn_proto = try arena.construct(ast.Node.FnProto {
548 .base = ast.Node {551 .base = ast.Node {
549 .id = ast.Node.Id.FnProto,552 .id = ast.Node.Id.FnProto,
550 .comments = ctx.comments,553 .before_comments = ctx.comments,
554 .same_line_comment = null,
551 },555 },
552 .visib_token = ctx.visib_token,556 .visib_token = ctx.visib_token,
553 .name_token = null,557 .name_token = null,
...@@ -812,7 +816,8 @@ pub const Parser = struct {...@@ -812,7 +816,8 @@ pub const Parser = struct {
812 const var_decl = try arena.construct(ast.Node.VarDecl {816 const var_decl = try arena.construct(ast.Node.VarDecl {
813 .base = ast.Node {817 .base = ast.Node {
814 .id = ast.Node.Id.VarDecl,818 .id = ast.Node.Id.VarDecl,
815 .comments = ctx.comments,819 .before_comments = ctx.comments,
820 .same_line_comment = null,
816 },821 },
817 .visib_token = ctx.visib_token,822 .visib_token = ctx.visib_token,
818 .mut_token = ctx.mut_token,823 .mut_token = ctx.mut_token,
...@@ -1242,7 +1247,8 @@ pub const Parser = struct {...@@ -1242,7 +1247,8 @@ pub const Parser = struct {
1242 const node = try arena.construct(ast.Node.Defer {1247 const node = try arena.construct(ast.Node.Defer {
1243 .base = ast.Node {1248 .base = ast.Node {
1244 .id = ast.Node.Id.Defer,1249 .id = ast.Node.Id.Defer,
1245 .comments = comments,1250 .before_comments = comments,
1251 .same_line_comment = null,
1246 },1252 },
1247 .defer_token = token,1253 .defer_token = token,
1248 .kind = switch (token.id) {1254 .kind = switch (token.id) {
...@@ -1275,7 +1281,8 @@ pub const Parser = struct {...@@ -1275,7 +1281,8 @@ pub const Parser = struct {
1275 else => {1281 else => {
1276 self.putBackToken(token);1282 self.putBackToken(token);
1277 const statement = try block.statements.addOne();1283 const statement = try block.statements.addOne();
1278 stack.append(State { .Semicolon = statement }) catch unreachable;1284 stack.append(State { .LookForSameLineComment = statement }) catch unreachable;
1285 try stack.append(State { .Semicolon = statement });
1279 try stack.append(State { .AddComments = AddCommentsCtx {1286 try stack.append(State { .AddComments = AddCommentsCtx {
1280 .node_ptr = statement,1287 .node_ptr = statement,
1281 .comments = comments,1288 .comments = comments,
...@@ -1324,7 +1331,28 @@ pub const Parser = struct {...@@ -1324,7 +1331,28 @@ pub const Parser = struct {
13241331
1325 State.AddComments => |add_comments_ctx| {1332 State.AddComments => |add_comments_ctx| {
1326 const node = *add_comments_ctx.node_ptr;1333 const node = *add_comments_ctx.node_ptr;
1327 node.comments = add_comments_ctx.comments;1334 node.before_comments = add_comments_ctx.comments;
1335 continue;
1336 },
1337
1338 State.LookForSameLineComment => |node_ptr| {
1339 const node = *node_ptr;
1340 const node_last_token = node.lastToken();
1341
1342 const line_comment_token = self.getNextToken();
1343 if (line_comment_token.id != Token.Id.LineComment) {
1344 self.putBackToken(line_comment_token);
1345 continue;
1346 }
1347
1348 const offset_loc = self.tokenizer.getTokenLocation(node_last_token.end, line_comment_token);
1349 const different_line = offset_loc.line != 0;
1350 if (different_line) {
1351 self.putBackToken(line_comment_token);
1352 continue;
1353 }
1354
1355 node.same_line_comment = try arena.construct(line_comment_token);
1328 continue;1356 continue;
1329 },1357 },
13301358
...@@ -1614,7 +1642,8 @@ pub const Parser = struct {...@@ -1614,7 +1642,8 @@ pub const Parser = struct {
1614 const fn_proto = try arena.construct(ast.Node.FnProto {1642 const fn_proto = try arena.construct(ast.Node.FnProto {
1615 .base = ast.Node {1643 .base = ast.Node {
1616 .id = ast.Node.Id.FnProto,1644 .id = ast.Node.Id.FnProto,
1617 .comments = ctx.comments,1645 .before_comments = ctx.comments,
1646 .same_line_comment = null,
1618 },1647 },
1619 .visib_token = null,1648 .visib_token = null,
1620 .name_token = null,1649 .name_token = null,
...@@ -2585,7 +2614,8 @@ pub const Parser = struct {...@@ -2585,7 +2614,8 @@ pub const Parser = struct {
2585 const fn_proto = try arena.construct(ast.Node.FnProto {2614 const fn_proto = try arena.construct(ast.Node.FnProto {
2586 .base = ast.Node {2615 .base = ast.Node {
2587 .id = ast.Node.Id.FnProto,2616 .id = ast.Node.Id.FnProto,
2588 .comments = null,2617 .before_comments = null,
2618 .same_line_comment = null,
2589 },2619 },
2590 .visib_token = null,2620 .visib_token = null,
2591 .name_token = null,2621 .name_token = null,
...@@ -2608,7 +2638,8 @@ pub const Parser = struct {...@@ -2608,7 +2638,8 @@ pub const Parser = struct {
2608 const fn_proto = try arena.construct(ast.Node.FnProto {2638 const fn_proto = try arena.construct(ast.Node.FnProto {
2609 .base = ast.Node {2639 .base = ast.Node {
2610 .id = ast.Node.Id.FnProto,2640 .id = ast.Node.Id.FnProto,
2611 .comments = null,2641 .before_comments = null,
2642 .same_line_comment = null,
2612 },2643 },
2613 .visib_token = null,2644 .visib_token = null,
2614 .name_token = null,2645 .name_token = null,
...@@ -2788,7 +2819,8 @@ pub const Parser = struct {...@@ -2788,7 +2819,8 @@ pub const Parser = struct {
2788 const comment_node = try arena.construct(ast.Node.LineComment {2819 const comment_node = try arena.construct(ast.Node.LineComment {
2789 .base = ast.Node {2820 .base = ast.Node {
2790 .id = ast.Node.Id.LineComment,2821 .id = ast.Node.Id.LineComment,
2791 .comments = null,2822 .before_comments = null,
2823 .same_line_comment = null,
2792 },2824 },
2793 .lines = ArrayList(Token).init(arena),2825 .lines = ArrayList(Token).init(arena),
2794 });2826 });
...@@ -3134,7 +3166,11 @@ pub const Parser = struct {...@@ -3134,7 +3166,11 @@ pub const Parser = struct {
3134 *node = *init_to;3166 *node = *init_to;
3135 node.base = blk: {3167 node.base = blk: {
3136 const id = ast.Node.typeToId(T);3168 const id = ast.Node.typeToId(T);
3137 break :blk ast.Node {.id = id, .comments = null};3169 break :blk ast.Node {
3170 .id = id,
3171 .before_comments = null,
3172 .same_line_comment = null,
3173 };
3138 };3174 };
31393175
3140 return node;3176 return node;
...@@ -3270,6 +3306,7 @@ pub const Parser = struct {...@@ -3270,6 +3306,7 @@ pub const Parser = struct {
3270 FieldInitializer: &ast.Node.FieldInitializer,3306 FieldInitializer: &ast.Node.FieldInitializer,
3271 PrintIndent,3307 PrintIndent,
3272 Indent: usize,3308 Indent: usize,
3309 PrintSameLineComment: ?&Token,
3273 };3310 };
32743311
3275 pub fn renderSource(self: &Parser, stream: var, root_node: &ast.Node.Root) !void {3312 pub fn renderSource(self: &Parser, stream: var, root_node: &ast.Node.Root) !void {
...@@ -4370,6 +4407,7 @@ pub const Parser = struct {...@@ -4370,6 +4407,7 @@ pub const Parser = struct {
4370 },4407 },
4371 RenderState.Statement => |base| {4408 RenderState.Statement => |base| {
4372 try self.renderComments(stream, base, indent);4409 try self.renderComments(stream, base, indent);
4410 try stack.append(RenderState { .PrintSameLineComment = base.same_line_comment } );
4373 switch (base.id) {4411 switch (base.id) {
4374 ast.Node.Id.VarDecl => {4412 ast.Node.Id.VarDecl => {
4375 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);4413 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
...@@ -4385,12 +4423,16 @@ pub const Parser = struct {...@@ -4385,12 +4423,16 @@ pub const Parser = struct {
4385 },4423 },
4386 RenderState.Indent => |new_indent| indent = new_indent,4424 RenderState.Indent => |new_indent| indent = new_indent,
4387 RenderState.PrintIndent => try stream.writeByteNTimes(' ', indent),4425 RenderState.PrintIndent => try stream.writeByteNTimes(' ', indent),
4426 RenderState.PrintSameLineComment => |maybe_comment| blk: {
4427 const comment_token = maybe_comment ?? break :blk;
4428 try stream.print(" {}", self.tokenizer.getTokenSlice(comment_token));
4429 },
4388 }4430 }
4389 }4431 }
4390 }4432 }
43914433
4392 fn renderComments(self: &Parser, stream: var, node: &ast.Node, indent: usize) !void {4434 fn renderComments(self: &Parser, stream: var, node: &ast.Node, indent: usize) !void {
4393 const comment = node.comments ?? return;4435 const comment = node.before_comments ?? return;
4394 for (comment.lines.toSliceConst()) |line_token| {4436 for (comment.lines.toSliceConst()) |line_token| {
4395 try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token));4437 try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token));
4396 try stream.writeByteNTimes(' ', indent);4438 try stream.writeByteNTimes(' ', indent);
...@@ -4471,6 +4513,17 @@ fn testCanonical(source: []const u8) !void {...@@ -4471,6 +4513,17 @@ fn testCanonical(source: []const u8) !void {
4471 }4513 }
4472}4514}
44734515
4516test "zig fmt: preserve same-line comment after a statement" {
4517 try testCanonical(
4518 \\test "" {
4519 \\ a = b;
4520 \\ debug.assert(H.digest_size <= H.block_size); // HMAC makes this assumption
4521 \\ a = b;
4522 \\}
4523 \\
4524 );
4525}
4526
4474test "zig fmt: preserve comments before global variables" {4527test "zig fmt: preserve comments before global variables" {
4475 try testCanonical(4528 try testCanonical(
4476 \\/// Foo copies keys and values before they go into the map, and4529 \\/// Foo copies keys and values before they go into the map, and