authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-29 15:48:53-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-29 15:48:53-04:00
logb7095912c77900eab6ad667a6eeb1add18ac8071
tree5b18212a0caf93462eae9862e9f8c326815561ab
parentf37e79e720215a3a41c603fe41d05d6910c79de2

zig fmt: respect comments before statements


3 files changed, 180 insertions(+), 133 deletions(-)

std/mem.zig+16-2
...@@ -37,6 +37,20 @@ pub const Allocator = struct {...@@ -37,6 +37,20 @@ pub const Allocator = struct {
37 return &slice[0];37 return &slice[0];
38 }38 }
3939
40 // TODO once #733 is solved, this will replace create
41 fn construct(self: &Allocator, init: var) t: {
42 // TODO this is a workaround for type getting parsed as Error!&const T
43 const T = @typeOf(init).Child;
44 break :t Error!&T;
45 } {
46 const T = @typeOf(init).Child;
47 if (@sizeOf(T) == 0) return &{};
48 const slice = try self.alloc(T, 1);
49 const ptr = &slice[0];
50 *ptr = *init;
51 return ptr;
52 }
53
40 fn destroy(self: &Allocator, ptr: var) void {54 fn destroy(self: &Allocator, ptr: var) void {
41 self.free(ptr[0..1]);55 self.free(ptr[0..1]);
42 }56 }
...@@ -54,7 +68,7 @@ pub const Allocator = struct {...@@ -54,7 +68,7 @@ pub const Allocator = struct {
54 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;68 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
55 const byte_slice = try self.allocFn(self, byte_count, alignment);69 const byte_slice = try self.allocFn(self, byte_count, alignment);
56 assert(byte_slice.len == byte_count);70 assert(byte_slice.len == byte_count);
57 // This loop should get optimized out in ReleaseFast mode71 // This loop gets optimized out in ReleaseFast mode
58 for (byte_slice) |*byte| {72 for (byte_slice) |*byte| {
59 *byte = undefined;73 *byte = undefined;
60 }74 }
...@@ -81,7 +95,7 @@ pub const Allocator = struct {...@@ -81,7 +95,7 @@ pub const Allocator = struct {
81 const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment);95 const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment);
82 assert(byte_slice.len == byte_count);96 assert(byte_slice.len == byte_count);
83 if (n > old_mem.len) {97 if (n > old_mem.len) {
84 // This loop should get optimized out in ReleaseFast mode98 // This loop gets optimized out in ReleaseFast mode
85 for (byte_slice[old_byte_slice.len..]) |*byte| {99 for (byte_slice[old_byte_slice.len..]) |*byte| {
86 *byte = undefined;100 *byte = undefined;
87 }101 }
std/zig/ast.zig+1-3
...@@ -6,6 +6,7 @@ const mem = std.mem;...@@ -6,6 +6,7 @@ const mem = std.mem;
66
7pub const Node = struct {7pub const Node = struct {
8 id: Id,8 id: Id,
9 comments: ?&LineComment,
910
10 pub const Id = enum {11 pub const Id = enum {
11 // Top level12 // Top level
...@@ -139,7 +140,6 @@ pub const Node = struct {...@@ -139,7 +140,6 @@ pub const Node = struct {
139140
140 pub const VarDecl = struct {141 pub const VarDecl = struct {
141 base: Node,142 base: Node,
142 comments: ?&LineComment,
143 visib_token: ?Token,143 visib_token: ?Token,
144 name_token: Token,144 name_token: Token,
145 eq_token: Token,145 eq_token: Token,
...@@ -421,7 +421,6 @@ pub const Node = struct {...@@ -421,7 +421,6 @@ pub const Node = struct {
421421
422 pub const FnProto = struct {422 pub const FnProto = struct {
423 base: Node,423 base: Node,
424 comments: ?&LineComment,
425 visib_token: ?Token,424 visib_token: ?Token,
426 fn_token: Token,425 fn_token: Token,
427 name_token: ?Token,426 name_token: ?Token,
...@@ -1732,7 +1731,6 @@ pub const Node = struct {...@@ -1732,7 +1731,6 @@ pub const Node = struct {
17321731
1733 pub const TestDecl = struct {1732 pub const TestDecl = struct {
1734 base: Node,1733 base: Node,
1735 comments: ?&LineComment,
1736 test_token: Token,1734 test_token: Token,
1737 name: &Node,1735 name: &Node,
1738 body_node: &Node,1736 body_node: &Node,
std/zig/parser.zig+163-128
...@@ -182,6 +182,11 @@ pub const Parser = struct {...@@ -182,6 +182,11 @@ pub const Parser = struct {
182 }182 }
183 };183 };
184184
185 const AddCommentsCtx = struct {
186 node_ptr: &&ast.Node,
187 comments: ?&ast.Node.LineComment,
188 };
189
185 const State = union(enum) {190 const State = union(enum) {
186 TopLevel,191 TopLevel,
187 TopLevelExtern: TopLevelDeclCtx,192 TopLevelExtern: TopLevelDeclCtx,
...@@ -221,6 +226,7 @@ pub const Parser = struct {...@@ -221,6 +226,7 @@ pub const Parser = struct {
221 Statement: &ast.Node.Block,226 Statement: &ast.Node.Block,
222 ComptimeStatement: ComptimeStatementCtx,227 ComptimeStatement: ComptimeStatementCtx,
223 Semicolon: &&ast.Node,228 Semicolon: &&ast.Node,
229 AddComments: AddCommentsCtx,
224230
225 AsmOutputItems: &ArrayList(&ast.Node.AsmOutput),231 AsmOutputItems: &ArrayList(&ast.Node.AsmOutput),
226 AsmOutputReturnOrType: &ast.Node.AsmOutput,232 AsmOutputReturnOrType: &ast.Node.AsmOutput,
...@@ -345,24 +351,26 @@ pub const Parser = struct {...@@ -345,24 +351,26 @@ pub const Parser = struct {
345 Token.Id.Keyword_test => {351 Token.Id.Keyword_test => {
346 stack.append(State.TopLevel) catch unreachable;352 stack.append(State.TopLevel) catch unreachable;
347353
348 const block = try self.createNode(arena, ast.Node.Block,354 const block = try arena.construct(ast.Node.Block {
349 ast.Node.Block {355 .base = ast.Node {
350 .base = undefined,356 .id = ast.Node.Id.Block,
351 .label = null,357 .comments = null,
352 .lbrace = undefined,358 },
353 .statements = ArrayList(&ast.Node).init(arena),359 .label = null,
354 .rbrace = undefined,360 .lbrace = undefined,
355 }361 .statements = ArrayList(&ast.Node).init(arena),
356 );362 .rbrace = undefined,
357 const test_node = try self.createAttachNode(arena, &root_node.decls, ast.Node.TestDecl,363 });
358 ast.Node.TestDecl {364 const test_node = try arena.construct(ast.Node.TestDecl {
359 .base = undefined,365 .base = ast.Node {
366 .id = ast.Node.Id.TestDecl,
360 .comments = comments,367 .comments = comments,
361 .test_token = token,368 },
362 .name = undefined,369 .test_token = token,
363 .body_node = &block.base,370 .name = undefined,
364 }371 .body_node = &block.base,
365 );372 });
373 try root_node.decls.append(&test_node.base);
366 stack.append(State { .Block = block }) catch unreachable;374 stack.append(State { .Block = block }) catch unreachable;
367 try stack.append(State {375 try stack.append(State {
368 .ExpectTokenSave = ExpectTokenSave {376 .ExpectTokenSave = ExpectTokenSave {
...@@ -530,24 +538,25 @@ pub const Parser = struct {...@@ -530,24 +538,25 @@ pub const Parser = struct {
530 },538 },
531 Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc,539 Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc,
532 Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {540 Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {
533 const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.Node.FnProto,541 const fn_proto = try arena.construct(ast.Node.FnProto {
534 ast.Node.FnProto {542 .base = ast.Node {
535 .base = undefined,543 .id = ast.Node.Id.FnProto,
536 .comments = comments,544 .comments = comments,
537 .visib_token = ctx.visib_token,545 },
538 .name_token = null,546 .visib_token = ctx.visib_token,
539 .fn_token = undefined,547 .name_token = null,
540 .params = ArrayList(&ast.Node).init(arena),548 .fn_token = undefined,
541 .return_type = undefined,549 .params = ArrayList(&ast.Node).init(arena),
542 .var_args_token = null,550 .return_type = undefined,
543 .extern_export_inline_token = ctx.extern_export_inline_token,551 .var_args_token = null,
544 .cc_token = null,552 .extern_export_inline_token = ctx.extern_export_inline_token,
545 .async_attr = null,553 .cc_token = null,
546 .body_node = null,554 .async_attr = null,
547 .lib_name = ctx.lib_name,555 .body_node = null,
548 .align_expr = null,556 .lib_name = ctx.lib_name,
549 }557 .align_expr = null,
550 );558 });
559 try ctx.decls.append(&fn_proto.base);
551 stack.append(State { .FnDef = fn_proto }) catch unreachable;560 stack.append(State { .FnDef = fn_proto }) catch unreachable;
552 try stack.append(State { .FnProto = fn_proto });561 try stack.append(State { .FnProto = fn_proto });
553562
...@@ -789,24 +798,25 @@ pub const Parser = struct {...@@ -789,24 +798,25 @@ pub const Parser = struct {
789798
790799
791 State.VarDecl => |ctx| {800 State.VarDecl => |ctx| {
792 const var_decl = try self.createAttachNode(arena, ctx.list, ast.Node.VarDecl,801 const var_decl = try arena.construct(ast.Node.VarDecl {
793 ast.Node.VarDecl {802 .base = ast.Node {
794 .base = undefined,803 .id = ast.Node.Id.VarDecl,
795 .comments = ctx.comments,804 .comments = ctx.comments,
796 .visib_token = ctx.visib_token,805 },
797 .mut_token = ctx.mut_token,806 .visib_token = ctx.visib_token,
798 .comptime_token = ctx.comptime_token,807 .mut_token = ctx.mut_token,
799 .extern_export_token = ctx.extern_export_token,808 .comptime_token = ctx.comptime_token,
800 .type_node = null,809 .extern_export_token = ctx.extern_export_token,
801 .align_node = null,810 .type_node = null,
802 .init_node = null,811 .align_node = null,
803 .lib_name = ctx.lib_name,812 .init_node = null,
804 // initialized later813 .lib_name = ctx.lib_name,
805 .name_token = undefined,814 // initialized later
806 .eq_token = undefined,815 .name_token = undefined,
807 .semicolon_token = undefined,816 .eq_token = undefined,
808 }817 .semicolon_token = undefined,
809 );818 });
819 try ctx.list.append(&var_decl.base);
810820
811 stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;821 stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
812 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });822 try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });
...@@ -1218,19 +1228,23 @@ pub const Parser = struct {...@@ -1218,19 +1228,23 @@ pub const Parser = struct {
1218 continue;1228 continue;
1219 },1229 },
1220 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {1230 Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
1221 const node = try self.createAttachNode(arena, &block.statements, ast.Node.Defer,1231 const node = try arena.construct(ast.Node.Defer {
1222 ast.Node.Defer {1232 .base = ast.Node {
1223 .base = undefined,1233 .id = ast.Node.Id.Defer,
1224 .defer_token = token,1234 .comments = comments,
1225 .kind = switch (token.id) {1235 },
1226 Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,1236 .defer_token = token,
1227 Token.Id.Keyword_errdefer => ast.Node.Defer.Kind.Error,1237 .kind = switch (token.id) {
1228 else => unreachable,1238 Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,
1229 },1239 Token.Id.Keyword_errdefer => ast.Node.Defer.Kind.Error,
1230 .expr = undefined,1240 else => unreachable,
1231 }1241 },
1232 );1242 .expr = undefined,
1233 stack.append(State { .Semicolon = &&node.base }) catch unreachable;1243 });
1244 const node_ptr = try block.statements.addOne();
1245 *node_ptr = &node.base;
1246
1247 stack.append(State { .Semicolon = node_ptr }) catch unreachable;
1234 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });1248 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
1235 continue;1249 continue;
1236 },1250 },
...@@ -1249,9 +1263,13 @@ pub const Parser = struct {...@@ -1249,9 +1263,13 @@ pub const Parser = struct {
1249 },1263 },
1250 else => {1264 else => {
1251 self.putBackToken(token);1265 self.putBackToken(token);
1252 const statememt = try block.statements.addOne();1266 const statement = try block.statements.addOne();
1253 stack.append(State { .Semicolon = statememt }) catch unreachable;1267 stack.append(State { .Semicolon = statement }) catch unreachable;
1254 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statememt } });1268 try stack.append(State { .AddComments = AddCommentsCtx {
1269 .node_ptr = statement,
1270 .comments = comments,
1271 }});
1272 try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });
1255 continue;1273 continue;
1256 }1274 }
1257 }1275 }
...@@ -1293,6 +1311,12 @@ pub const Parser = struct {...@@ -1293,6 +1311,12 @@ pub const Parser = struct {
1293 continue;1311 continue;
1294 },1312 },
12951313
1314 State.AddComments => |add_comments_ctx| {
1315 const node = *add_comments_ctx.node_ptr;
1316 node.comments = add_comments_ctx.comments;
1317 continue;
1318 },
1319
12961320
1297 State.AsmOutputItems => |items| {1321 State.AsmOutputItems => |items| {
1298 const lbracket = self.getNextToken();1322 const lbracket = self.getNextToken();
...@@ -1576,24 +1600,25 @@ pub const Parser = struct {...@@ -1576,24 +1600,25 @@ pub const Parser = struct {
15761600
1577 State.ExternType => |ctx| {1601 State.ExternType => |ctx| {
1578 if (self.eatToken(Token.Id.Keyword_fn)) |fn_token| {1602 if (self.eatToken(Token.Id.Keyword_fn)) |fn_token| {
1579 const fn_proto = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.FnProto,1603 const fn_proto = try arena.construct(ast.Node.FnProto {
1580 ast.Node.FnProto {1604 .base = ast.Node {
1581 .base = undefined,1605 .id = ast.Node.Id.FnProto,
1582 .comments = ctx.comments,1606 .comments = ctx.comments,
1583 .visib_token = null,1607 },
1584 .name_token = null,1608 .visib_token = null,
1585 .fn_token = fn_token,1609 .name_token = null,
1586 .params = ArrayList(&ast.Node).init(arena),1610 .fn_token = fn_token,
1587 .return_type = undefined,1611 .params = ArrayList(&ast.Node).init(arena),
1588 .var_args_token = null,1612 .return_type = undefined,
1589 .extern_export_inline_token = ctx.extern_token,1613 .var_args_token = null,
1590 .cc_token = null,1614 .extern_export_inline_token = ctx.extern_token,
1591 .async_attr = null,1615 .cc_token = null,
1592 .body_node = null,1616 .async_attr = null,
1593 .lib_name = null,1617 .body_node = null,
1594 .align_expr = null,1618 .lib_name = null,
1595 }1619 .align_expr = null,
1596 );1620 });
1621 ctx.opt_ctx.store(&fn_proto.base);
1597 stack.append(State { .FnProto = fn_proto }) catch unreachable;1622 stack.append(State { .FnProto = fn_proto }) catch unreachable;
1598 continue;1623 continue;
1599 }1624 }
...@@ -2546,46 +2571,48 @@ pub const Parser = struct {...@@ -2546,46 +2571,48 @@ pub const Parser = struct {
2546 continue;2571 continue;
2547 },2572 },
2548 Token.Id.Keyword_fn => {2573 Token.Id.Keyword_fn => {
2549 const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.Node.FnProto,2574 const fn_proto = try arena.construct(ast.Node.FnProto {
2550 ast.Node.FnProto {2575 .base = ast.Node {
2551 .base = undefined,2576 .id = ast.Node.Id.FnProto,
2552 .comments = null,2577 .comments = null,
2553 .visib_token = null,2578 },
2554 .name_token = null,2579 .visib_token = null,
2555 .fn_token = token,2580 .name_token = null,
2556 .params = ArrayList(&ast.Node).init(arena),2581 .fn_token = token,
2557 .return_type = undefined,2582 .params = ArrayList(&ast.Node).init(arena),
2558 .var_args_token = null,2583 .return_type = undefined,
2559 .extern_export_inline_token = null,2584 .var_args_token = null,
2560 .cc_token = null,2585 .extern_export_inline_token = null,
2561 .async_attr = null,2586 .cc_token = null,
2562 .body_node = null,2587 .async_attr = null,
2563 .lib_name = null,2588 .body_node = null,
2564 .align_expr = null,2589 .lib_name = null,
2565 }2590 .align_expr = null,
2566 );2591 });
2592 opt_ctx.store(&fn_proto.base);
2567 stack.append(State { .FnProto = fn_proto }) catch unreachable;2593 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2568 continue;2594 continue;
2569 },2595 },
2570 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {2596 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
2571 const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.Node.FnProto,2597 const fn_proto = try arena.construct(ast.Node.FnProto {
2572 ast.Node.FnProto {2598 .base = ast.Node {
2573 .base = undefined,2599 .id = ast.Node.Id.FnProto,
2574 .comments = null,2600 .comments = null,
2575 .visib_token = null,2601 },
2576 .name_token = null,2602 .visib_token = null,
2577 .fn_token = undefined,2603 .name_token = null,
2578 .params = ArrayList(&ast.Node).init(arena),2604 .fn_token = undefined,
2579 .return_type = undefined,2605 .params = ArrayList(&ast.Node).init(arena),
2580 .var_args_token = null,2606 .return_type = undefined,
2581 .extern_export_inline_token = null,2607 .var_args_token = null,
2582 .cc_token = token,2608 .extern_export_inline_token = null,
2583 .async_attr = null,2609 .cc_token = token,
2584 .body_node = null,2610 .async_attr = null,
2585 .lib_name = null,2611 .body_node = null,
2586 .align_expr = null,2612 .lib_name = null,
2587 }2613 .align_expr = null,
2588 );2614 });
2615 opt_ctx.store(&fn_proto.base);
2589 stack.append(State { .FnProto = fn_proto }) catch unreachable;2616 stack.append(State { .FnProto = fn_proto }) catch unreachable;
2590 try stack.append(State {2617 try stack.append(State {
2591 .ExpectTokenSave = ExpectTokenSave {2618 .ExpectTokenSave = ExpectTokenSave {
...@@ -2747,13 +2774,13 @@ pub const Parser = struct {...@@ -2747,13 +2774,13 @@ pub const Parser = struct {
2747 if (result) |comment_node| {2774 if (result) |comment_node| {
2748 break :blk comment_node;2775 break :blk comment_node;
2749 } else {2776 } else {
2750 const comment_node = try arena.create(ast.Node.LineComment);2777 const comment_node = try arena.construct(ast.Node.LineComment {
2751 *comment_node = ast.Node.LineComment {
2752 .base = ast.Node {2778 .base = ast.Node {
2753 .id = ast.Node.Id.LineComment,2779 .id = ast.Node.Id.LineComment,
2780 .comments = null,
2754 },2781 },
2755 .lines = ArrayList(Token).init(arena),2782 .lines = ArrayList(Token).init(arena),
2756 };2783 });
2757 result = comment_node;2784 result = comment_node;
2758 break :blk comment_node;2785 break :blk comment_node;
2759 }2786 }
...@@ -3096,7 +3123,7 @@ pub const Parser = struct {...@@ -3096,7 +3123,7 @@ pub const Parser = struct {
3096 *node = *init_to;3123 *node = *init_to;
3097 node.base = blk: {3124 node.base = blk: {
3098 const id = ast.Node.typeToId(T);3125 const id = ast.Node.typeToId(T);
3099 break :blk ast.Node {.id = id};3126 break :blk ast.Node {.id = id, .comments = null};
3100 };3127 };
31013128
3102 return node;3129 return node;
...@@ -3269,7 +3296,7 @@ pub const Parser = struct {...@@ -3269,7 +3296,7 @@ pub const Parser = struct {
3269 switch (decl.id) {3296 switch (decl.id) {
3270 ast.Node.Id.FnProto => {3297 ast.Node.Id.FnProto => {
3271 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);3298 const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
3272 try self.renderComments(stream, fn_proto, indent);3299 try self.renderComments(stream, &fn_proto.base, indent);
32733300
3274 if (fn_proto.body_node) |body_node| {3301 if (fn_proto.body_node) |body_node| {
3275 stack.append(RenderState { .Expression = body_node}) catch unreachable;3302 stack.append(RenderState { .Expression = body_node}) catch unreachable;
...@@ -3295,7 +3322,7 @@ pub const Parser = struct {...@@ -3295,7 +3322,7 @@ pub const Parser = struct {
3295 },3322 },
3296 ast.Node.Id.TestDecl => {3323 ast.Node.Id.TestDecl => {
3297 const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);3324 const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);
3298 try self.renderComments(stream, test_decl, indent);3325 try self.renderComments(stream, &test_decl.base, indent);
3299 try stream.print("test ");3326 try stream.print("test ");
3300 try stack.append(RenderState { .Expression = test_decl.body_node });3327 try stack.append(RenderState { .Expression = test_decl.body_node });
3301 try stack.append(RenderState { .Text = " " });3328 try stack.append(RenderState { .Text = " " });
...@@ -3338,7 +3365,6 @@ pub const Parser = struct {...@@ -3338,7 +3365,6 @@ pub const Parser = struct {
3338 },3365 },
33393366
3340 RenderState.FieldInitializer => |field_init| {3367 RenderState.FieldInitializer => |field_init| {
3341 //TODO try self.renderComments(stream, field_init, indent);
3342 try stream.print(".{}", self.tokenizer.getTokenSlice(field_init.name_token));3368 try stream.print(".{}", self.tokenizer.getTokenSlice(field_init.name_token));
3343 try stream.print(" = ");3369 try stream.print(" = ");
3344 try stack.append(RenderState { .Expression = field_init.expr });3370 try stack.append(RenderState { .Expression = field_init.expr });
...@@ -3385,7 +3411,6 @@ pub const Parser = struct {...@@ -3385,7 +3411,6 @@ pub const Parser = struct {
33853411
3386 RenderState.ParamDecl => |base| {3412 RenderState.ParamDecl => |base| {
3387 const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);3413 const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);
3388 // TODO try self.renderComments(stream, param_decl, indent);
3389 if (param_decl.comptime_token) |comptime_token| {3414 if (param_decl.comptime_token) |comptime_token| {
3390 try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));3415 try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
3391 }3416 }
...@@ -4328,10 +4353,10 @@ pub const Parser = struct {...@@ -4328,10 +4353,10 @@ pub const Parser = struct {
4328 ast.Node.Id.ParamDecl => unreachable,4353 ast.Node.Id.ParamDecl => unreachable,
4329 },4354 },
4330 RenderState.Statement => |base| {4355 RenderState.Statement => |base| {
4356 try self.renderComments(stream, base, indent);
4331 switch (base.id) {4357 switch (base.id) {
4332 ast.Node.Id.VarDecl => {4358 ast.Node.Id.VarDecl => {
4333 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);4359 const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
4334 try self.renderComments(stream, var_decl, indent);
4335 try stack.append(RenderState { .VarDecl = var_decl});4360 try stack.append(RenderState { .VarDecl = var_decl});
4336 },4361 },
4337 else => {4362 else => {
...@@ -4348,7 +4373,7 @@ pub const Parser = struct {...@@ -4348,7 +4373,7 @@ pub const Parser = struct {
4348 }4373 }
4349 }4374 }
43504375
4351 fn renderComments(self: &Parser, stream: var, node: var, indent: usize) !void {4376 fn renderComments(self: &Parser, stream: var, node: &ast.Node, indent: usize) !void {
4352 const comment = node.comments ?? return;4377 const comment = node.comments ?? return;
4353 for (comment.lines.toSliceConst()) |line_token| {4378 for (comment.lines.toSliceConst()) |line_token| {
4354 try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token));4379 try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token));
...@@ -4430,6 +4455,16 @@ fn testCanonical(source: []const u8) !void {...@@ -4430,6 +4455,16 @@ fn testCanonical(source: []const u8) !void {
4430 }4455 }
4431}4456}
44324457
4458test "zig fmt: preserve comments before statements" {
4459 try testCanonical(
4460 \\test "std" {
4461 \\ // statement comment
4462 \\ _ = @import("foo/bar.zig");
4463 \\}
4464 \\
4465 );
4466}
4467
4433test "zig fmt: preserve top level comments" {4468test "zig fmt: preserve top level comments" {
4434 try testCanonical(4469 try testCanonical(
4435 \\// top level comment4470 \\// top level comment