| ... | ... | @@ -229,6 +229,7 @@ pub const Parser = struct { |
| 229 | 229 | ComptimeStatement: ComptimeStatementCtx, |
| 230 | 230 | Semicolon: &&ast.Node, |
| 231 | 231 | AddComments: AddCommentsCtx, |
| 232 | LookForSameLineComment: &&ast.Node, |
| 232 | 233 | |
| 233 | 234 | AsmOutputItems: &ArrayList(&ast.Node.AsmOutput), |
| 234 | 235 | AsmOutputReturnOrType: &ast.Node.AsmOutput, |
| ... | ... | @@ -356,7 +357,8 @@ pub const Parser = struct { |
| 356 | 357 | const block = try arena.construct(ast.Node.Block { |
| 357 | 358 | .base = ast.Node { |
| 358 | 359 | .id = ast.Node.Id.Block, |
| 359 | | .comments = null, |
| 360 | .before_comments = null, |
| 361 | .same_line_comment = null, |
| 360 | 362 | }, |
| 361 | 363 | .label = null, |
| 362 | 364 | .lbrace = undefined, |
| ... | ... | @@ -366,7 +368,8 @@ pub const Parser = struct { |
| 366 | 368 | const test_node = try arena.construct(ast.Node.TestDecl { |
| 367 | 369 | .base = ast.Node { |
| 368 | 370 | .id = ast.Node.Id.TestDecl, |
| 369 | | .comments = comments, |
| 371 | .before_comments = comments, |
| 372 | .same_line_comment = null, |
| 370 | 373 | }, |
| 371 | 374 | .test_token = token, |
| 372 | 375 | .name = undefined, |
| ... | ... | @@ -547,7 +550,8 @@ pub const Parser = struct { |
| 547 | 550 | const fn_proto = try arena.construct(ast.Node.FnProto { |
| 548 | 551 | .base = ast.Node { |
| 549 | 552 | .id = ast.Node.Id.FnProto, |
| 550 | | .comments = ctx.comments, |
| 553 | .before_comments = ctx.comments, |
| 554 | .same_line_comment = null, |
| 551 | 555 | }, |
| 552 | 556 | .visib_token = ctx.visib_token, |
| 553 | 557 | .name_token = null, |
| ... | ... | @@ -812,7 +816,8 @@ pub const Parser = struct { |
| 812 | 816 | const var_decl = try arena.construct(ast.Node.VarDecl { |
| 813 | 817 | .base = ast.Node { |
| 814 | 818 | .id = ast.Node.Id.VarDecl, |
| 815 | | .comments = ctx.comments, |
| 819 | .before_comments = ctx.comments, |
| 820 | .same_line_comment = null, |
| 816 | 821 | }, |
| 817 | 822 | .visib_token = ctx.visib_token, |
| 818 | 823 | .mut_token = ctx.mut_token, |
| ... | ... | @@ -1242,7 +1247,8 @@ pub const Parser = struct { |
| 1242 | 1247 | const node = try arena.construct(ast.Node.Defer { |
| 1243 | 1248 | .base = ast.Node { |
| 1244 | 1249 | .id = ast.Node.Id.Defer, |
| 1245 | | .comments = comments, |
| 1250 | .before_comments = comments, |
| 1251 | .same_line_comment = null, |
| 1246 | 1252 | }, |
| 1247 | 1253 | .defer_token = token, |
| 1248 | 1254 | .kind = switch (token.id) { |
| ... | ... | @@ -1275,7 +1281,8 @@ pub const Parser = struct { |
| 1275 | 1281 | else => { |
| 1276 | 1282 | self.putBackToken(token); |
| 1277 | 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 | 1286 | try stack.append(State { .AddComments = AddCommentsCtx { |
| 1280 | 1287 | .node_ptr = statement, |
| 1281 | 1288 | .comments = comments, |
| ... | ... | @@ -1324,7 +1331,28 @@ pub const Parser = struct { |
| 1324 | 1331 | |
| 1325 | 1332 | State.AddComments => |add_comments_ctx| { |
| 1326 | 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 | 1356 | continue; |
| 1329 | 1357 | }, |
| 1330 | 1358 | |
| ... | ... | @@ -1614,7 +1642,8 @@ pub const Parser = struct { |
| 1614 | 1642 | const fn_proto = try arena.construct(ast.Node.FnProto { |
| 1615 | 1643 | .base = ast.Node { |
| 1616 | 1644 | .id = ast.Node.Id.FnProto, |
| 1617 | | .comments = ctx.comments, |
| 1645 | .before_comments = ctx.comments, |
| 1646 | .same_line_comment = null, |
| 1618 | 1647 | }, |
| 1619 | 1648 | .visib_token = null, |
| 1620 | 1649 | .name_token = null, |
| ... | ... | @@ -2585,7 +2614,8 @@ pub const Parser = struct { |
| 2585 | 2614 | const fn_proto = try arena.construct(ast.Node.FnProto { |
| 2586 | 2615 | .base = ast.Node { |
| 2587 | 2616 | .id = ast.Node.Id.FnProto, |
| 2588 | | .comments = null, |
| 2617 | .before_comments = null, |
| 2618 | .same_line_comment = null, |
| 2589 | 2619 | }, |
| 2590 | 2620 | .visib_token = null, |
| 2591 | 2621 | .name_token = null, |
| ... | ... | @@ -2608,7 +2638,8 @@ pub const Parser = struct { |
| 2608 | 2638 | const fn_proto = try arena.construct(ast.Node.FnProto { |
| 2609 | 2639 | .base = ast.Node { |
| 2610 | 2640 | .id = ast.Node.Id.FnProto, |
| 2611 | | .comments = null, |
| 2641 | .before_comments = null, |
| 2642 | .same_line_comment = null, |
| 2612 | 2643 | }, |
| 2613 | 2644 | .visib_token = null, |
| 2614 | 2645 | .name_token = null, |
| ... | ... | @@ -2788,7 +2819,8 @@ pub const Parser = struct { |
| 2788 | 2819 | const comment_node = try arena.construct(ast.Node.LineComment { |
| 2789 | 2820 | .base = ast.Node { |
| 2790 | 2821 | .id = ast.Node.Id.LineComment, |
| 2791 | | .comments = null, |
| 2822 | .before_comments = null, |
| 2823 | .same_line_comment = null, |
| 2792 | 2824 | }, |
| 2793 | 2825 | .lines = ArrayList(Token).init(arena), |
| 2794 | 2826 | }); |
| ... | ... | @@ -3134,7 +3166,11 @@ pub const Parser = struct { |
| 3134 | 3166 | *node = *init_to; |
| 3135 | 3167 | node.base = blk: { |
| 3136 | 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 | }; |
| 3139 | 3175 | |
| 3140 | 3176 | return node; |
| ... | ... | @@ -3270,6 +3306,7 @@ pub const Parser = struct { |
| 3270 | 3306 | FieldInitializer: &ast.Node.FieldInitializer, |
| 3271 | 3307 | PrintIndent, |
| 3272 | 3308 | Indent: usize, |
| 3309 | PrintSameLineComment: ?&Token, |
| 3273 | 3310 | }; |
| 3274 | 3311 | |
| 3275 | 3312 | pub fn renderSource(self: &Parser, stream: var, root_node: &ast.Node.Root) !void { |
| ... | ... | @@ -4370,6 +4407,7 @@ pub const Parser = struct { |
| 4370 | 4407 | }, |
| 4371 | 4408 | RenderState.Statement => |base| { |
| 4372 | 4409 | try self.renderComments(stream, base, indent); |
| 4410 | try stack.append(RenderState { .PrintSameLineComment = base.same_line_comment } ); |
| 4373 | 4411 | switch (base.id) { |
| 4374 | 4412 | ast.Node.Id.VarDecl => { |
| 4375 | 4413 | const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base); |
| ... | ... | @@ -4385,12 +4423,16 @@ pub const Parser = struct { |
| 4385 | 4423 | }, |
| 4386 | 4424 | RenderState.Indent => |new_indent| indent = new_indent, |
| 4387 | 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 | } |
| 4391 | 4433 | |
| 4392 | 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 | 4436 | for (comment.lines.toSliceConst()) |line_token| { |
| 4395 | 4437 | try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token)); |
| 4396 | 4438 | try stream.writeByteNTimes(' ', indent); |
| ... | ... | @@ -4471,6 +4513,17 @@ fn testCanonical(source: []const u8) !void { |
| 4471 | 4513 | } |
| 4472 | 4514 | } |
| 4473 | 4515 | |
| 4516 | test "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 | |
| 4474 | 4527 | test "zig fmt: preserve comments before global variables" { |
| 4475 | 4528 | try testCanonical( |
| 4476 | 4529 | \\/// Foo copies keys and values before they go into the map, and |