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