| ... | ... | @@ -55,6 +55,7 @@ pub const Parser = struct { |
| 55 | 55 | visib_token: ?Token, |
| 56 | 56 | extern_export_inline_token: ?Token, |
| 57 | 57 | lib_name: ?&ast.Node, |
| 58 | comments: ?&ast.Node.LineComment, |
| 58 | 59 | }; |
| 59 | 60 | |
| 60 | 61 | const VarDeclCtx = struct { |
| ... | ... | @@ -70,6 +71,7 @@ pub const Parser = struct { |
| 70 | 71 | const TopLevelExternOrFieldCtx = struct { |
| 71 | 72 | visib_token: Token, |
| 72 | 73 | container_decl: &ast.Node.ContainerDecl, |
| 74 | comments: ?&ast.Node.LineComment, |
| 73 | 75 | }; |
| 74 | 76 | |
| 75 | 77 | const ExternTypeCtx = struct { |
| ... | ... | @@ -393,6 +395,7 @@ pub const Parser = struct { |
| 393 | 395 | .visib_token = token, |
| 394 | 396 | .extern_export_inline_token = null, |
| 395 | 397 | .lib_name = null, |
| 398 | .comments = comments, |
| 396 | 399 | } |
| 397 | 400 | }); |
| 398 | 401 | continue; |
| ... | ... | @@ -433,6 +436,7 @@ pub const Parser = struct { |
| 433 | 436 | .visib_token = null, |
| 434 | 437 | .extern_export_inline_token = null, |
| 435 | 438 | .lib_name = null, |
| 439 | .comments = comments, |
| 436 | 440 | } |
| 437 | 441 | }); |
| 438 | 442 | continue; |
| ... | ... | @@ -449,6 +453,7 @@ pub const Parser = struct { |
| 449 | 453 | .visib_token = ctx.visib_token, |
| 450 | 454 | .extern_export_inline_token = token, |
| 451 | 455 | .lib_name = null, |
| 456 | .comments = ctx.comments, |
| 452 | 457 | }, |
| 453 | 458 | }) catch unreachable; |
| 454 | 459 | continue; |
| ... | ... | @@ -460,6 +465,7 @@ pub const Parser = struct { |
| 460 | 465 | .visib_token = ctx.visib_token, |
| 461 | 466 | .extern_export_inline_token = token, |
| 462 | 467 | .lib_name = null, |
| 468 | .comments = ctx.comments, |
| 463 | 469 | }, |
| 464 | 470 | }) catch unreachable; |
| 465 | 471 | continue; |
| ... | ... | @@ -486,12 +492,12 @@ pub const Parser = struct { |
| 486 | 492 | .visib_token = ctx.visib_token, |
| 487 | 493 | .extern_export_inline_token = ctx.extern_export_inline_token, |
| 488 | 494 | .lib_name = lib_name, |
| 495 | .comments = ctx.comments, |
| 489 | 496 | }, |
| 490 | 497 | }) catch unreachable; |
| 491 | 498 | continue; |
| 492 | 499 | }, |
| 493 | 500 | State.TopLevelDecl => |ctx| { |
| 494 | | const comments = try self.eatComments(arena); |
| 495 | 501 | const token = self.getNextToken(); |
| 496 | 502 | switch (token.id) { |
| 497 | 503 | Token.Id.Keyword_use => { |
| ... | ... | @@ -525,7 +531,7 @@ pub const Parser = struct { |
| 525 | 531 | |
| 526 | 532 | stack.append(State { |
| 527 | 533 | .VarDecl = VarDeclCtx { |
| 528 | | .comments = comments, |
| 534 | .comments = ctx.comments, |
| 529 | 535 | .visib_token = ctx.visib_token, |
| 530 | 536 | .lib_name = ctx.lib_name, |
| 531 | 537 | .comptime_token = null, |
| ... | ... | @@ -541,7 +547,7 @@ pub const Parser = struct { |
| 541 | 547 | const fn_proto = try arena.construct(ast.Node.FnProto { |
| 542 | 548 | .base = ast.Node { |
| 543 | 549 | .id = ast.Node.Id.FnProto, |
| 544 | | .comments = comments, |
| 550 | .comments = ctx.comments, |
| 545 | 551 | }, |
| 546 | 552 | .visib_token = ctx.visib_token, |
| 547 | 553 | .name_token = null, |
| ... | ... | @@ -628,6 +634,7 @@ pub const Parser = struct { |
| 628 | 634 | .visib_token = ctx.visib_token, |
| 629 | 635 | .extern_export_inline_token = null, |
| 630 | 636 | .lib_name = null, |
| 637 | .comments = ctx.comments, |
| 631 | 638 | } |
| 632 | 639 | }); |
| 633 | 640 | continue; |
| ... | ... | @@ -746,6 +753,7 @@ pub const Parser = struct { |
| 746 | 753 | .TopLevelExternOrField = TopLevelExternOrFieldCtx { |
| 747 | 754 | .visib_token = token, |
| 748 | 755 | .container_decl = container_decl, |
| 756 | .comments = null, |
| 749 | 757 | } |
| 750 | 758 | }); |
| 751 | 759 | continue; |
| ... | ... | @@ -758,6 +766,7 @@ pub const Parser = struct { |
| 758 | 766 | .visib_token = token, |
| 759 | 767 | .extern_export_inline_token = null, |
| 760 | 768 | .lib_name = null, |
| 769 | .comments = null, |
| 761 | 770 | } |
| 762 | 771 | }); |
| 763 | 772 | continue; |
| ... | ... | @@ -772,6 +781,7 @@ pub const Parser = struct { |
| 772 | 781 | .visib_token = token, |
| 773 | 782 | .extern_export_inline_token = null, |
| 774 | 783 | .lib_name = null, |
| 784 | .comments = null, |
| 775 | 785 | } |
| 776 | 786 | }); |
| 777 | 787 | continue; |
| ... | ... | @@ -789,6 +799,7 @@ pub const Parser = struct { |
| 789 | 799 | .visib_token = null, |
| 790 | 800 | .extern_export_inline_token = null, |
| 791 | 801 | .lib_name = null, |
| 802 | .comments = null, |
| 792 | 803 | } |
| 793 | 804 | }); |
| 794 | 805 | continue; |
| ... | ... | @@ -3318,6 +3329,7 @@ pub const Parser = struct { |
| 3318 | 3329 | }, |
| 3319 | 3330 | ast.Node.Id.VarDecl => { |
| 3320 | 3331 | const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl); |
| 3332 | try self.renderComments(stream, &var_decl.base, indent); |
| 3321 | 3333 | try stack.append(RenderState { .VarDecl = var_decl}); |
| 3322 | 3334 | }, |
| 3323 | 3335 | ast.Node.Id.TestDecl => { |
| ... | ... | @@ -3827,41 +3839,45 @@ pub const Parser = struct { |
| 3827 | 3839 | ast.Node.ContainerDecl.Kind.Union => try stream.print("union"), |
| 3828 | 3840 | } |
| 3829 | 3841 | |
| 3830 | | try stack.append(RenderState { .Text = "}"}); |
| 3831 | | try stack.append(RenderState.PrintIndent); |
| 3832 | | try stack.append(RenderState { .Indent = indent }); |
| 3833 | | try stack.append(RenderState { .Text = "\n"}); |
| 3834 | | |
| 3835 | 3842 | const fields_and_decls = container_decl.fields_and_decls.toSliceConst(); |
| 3836 | | var i = fields_and_decls.len; |
| 3837 | | while (i != 0) { |
| 3838 | | i -= 1; |
| 3839 | | const node = fields_and_decls[i]; |
| 3840 | | switch (node.id) { |
| 3841 | | ast.Node.Id.StructField, |
| 3842 | | ast.Node.Id.UnionTag, |
| 3843 | | ast.Node.Id.EnumTag => { |
| 3844 | | try stack.append(RenderState { .Text = "," }); |
| 3845 | | }, |
| 3846 | | else => { } |
| 3847 | | } |
| 3848 | | try stack.append(RenderState { .TopLevelDecl = node}); |
| 3843 | if (fields_and_decls.len == 0) { |
| 3844 | try stack.append(RenderState { .Text = "{}"}); |
| 3845 | } else { |
| 3846 | try stack.append(RenderState { .Text = "}"}); |
| 3849 | 3847 | try stack.append(RenderState.PrintIndent); |
| 3850 | | try stack.append(RenderState { |
| 3851 | | .Text = blk: { |
| 3852 | | if (i != 0) { |
| 3853 | | const prev_node = fields_and_decls[i - 1]; |
| 3854 | | const loc = self.tokenizer.getTokenLocation(prev_node.lastToken().end, node.firstToken()); |
| 3855 | | if (loc.line >= 2) { |
| 3856 | | break :blk "\n\n"; |
| 3848 | try stack.append(RenderState { .Indent = indent }); |
| 3849 | try stack.append(RenderState { .Text = "\n"}); |
| 3850 | |
| 3851 | var i = fields_and_decls.len; |
| 3852 | while (i != 0) { |
| 3853 | i -= 1; |
| 3854 | const node = fields_and_decls[i]; |
| 3855 | switch (node.id) { |
| 3856 | ast.Node.Id.StructField, |
| 3857 | ast.Node.Id.UnionTag, |
| 3858 | ast.Node.Id.EnumTag => { |
| 3859 | try stack.append(RenderState { .Text = "," }); |
| 3860 | }, |
| 3861 | else => { } |
| 3862 | } |
| 3863 | try stack.append(RenderState { .TopLevelDecl = node}); |
| 3864 | try stack.append(RenderState.PrintIndent); |
| 3865 | try stack.append(RenderState { |
| 3866 | .Text = blk: { |
| 3867 | if (i != 0) { |
| 3868 | const prev_node = fields_and_decls[i - 1]; |
| 3869 | const loc = self.tokenizer.getTokenLocation(prev_node.lastToken().end, node.firstToken()); |
| 3870 | if (loc.line >= 2) { |
| 3871 | break :blk "\n\n"; |
| 3872 | } |
| 3857 | 3873 | } |
| 3858 | | } |
| 3859 | | break :blk "\n"; |
| 3860 | | }, |
| 3861 | | }); |
| 3874 | break :blk "\n"; |
| 3875 | }, |
| 3876 | }); |
| 3877 | } |
| 3878 | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| 3879 | try stack.append(RenderState { .Text = "{"}); |
| 3862 | 3880 | } |
| 3863 | | try stack.append(RenderState { .Indent = indent + indent_delta}); |
| 3864 | | try stack.append(RenderState { .Text = "{"}); |
| 3865 | 3881 | |
| 3866 | 3882 | switch (container_decl.init_arg_expr) { |
| 3867 | 3883 | ast.Node.ContainerDecl.InitArg.None => try stack.append(RenderState { .Text = " "}), |
| ... | ... | @@ -4455,6 +4471,15 @@ fn testCanonical(source: []const u8) !void { |
| 4455 | 4471 | } |
| 4456 | 4472 | } |
| 4457 | 4473 | |
| 4474 | test "zig fmt: preserve comments before global variables" { |
| 4475 | try testCanonical( |
| 4476 | \\/// Foo copies keys and values before they go into the map, and |
| 4477 | \\/// frees them when they get removed. |
| 4478 | \\pub const Foo = struct {}; |
| 4479 | \\ |
| 4480 | ); |
| 4481 | } |
| 4482 | |
| 4458 | 4483 | test "zig fmt: preserve comments before statements" { |
| 4459 | 4484 | try testCanonical( |
| 4460 | 4485 | \\test "std" { |