authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-27 19:21:38-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-27 19:21:38-04:00
log4f2d49fd138be67ad01d9c1b9086cb6a41530944
tree3c7d058ceef97d8ae9948313a1adf47aa9152aa1
parentb92fac329e73280ea5d49af675fea84e777b7f0a
signaturelock-open Commit is signed but in an unrecognized format.

std.zig.parse: fix parsing of doc comments after fields

closes #1404

2 files changed, 73 insertions(+), 13 deletions(-)

std/zig/parse.zig+56-13
...@@ -340,7 +340,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -340,7 +340,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
340 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();340 const node_ptr = try ctx.container_decl.fields_and_decls.addOne();
341 node_ptr.* = &node.base;341 node_ptr.* = &node.base;
342342
343 stack.append(State{ .FieldListCommaOrEnd = ctx.container_decl }) catch unreachable;343 try stack.append(State{
344 .FieldListCommaOrEnd = FieldCtx{
345 .doc_comments = &node.doc_comments,
346 .container_decl = ctx.container_decl,
347 },
348 });
344 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.type_expr } });349 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.type_expr } });
345 try stack.append(State{ .ExpectToken = Token.Id.Colon });350 try stack.append(State{ .ExpectToken = Token.Id.Colon });
346 continue;351 continue;
...@@ -458,7 +463,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -458,7 +463,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
458 const node_ptr = try container_decl.fields_and_decls.addOne();463 const node_ptr = try container_decl.fields_and_decls.addOne();
459 node_ptr.* = &node.base;464 node_ptr.* = &node.base;
460465
461 try stack.append(State{ .FieldListCommaOrEnd = container_decl });466 try stack.append(State{
467 .FieldListCommaOrEnd = FieldCtx{
468 .doc_comments = &node.doc_comments,
469 .container_decl = container_decl,
470 },
471 });
462 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &node.type_expr } });472 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &node.type_expr } });
463 try stack.append(State{ .ExpectToken = Token.Id.Colon });473 try stack.append(State{ .ExpectToken = Token.Id.Colon });
464 continue;474 continue;
...@@ -473,7 +483,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -473,7 +483,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
473 });483 });
474 try container_decl.fields_and_decls.push(&node.base);484 try container_decl.fields_and_decls.push(&node.base);
475485
476 stack.append(State{ .FieldListCommaOrEnd = container_decl }) catch unreachable;486 try stack.append(State{
487 .FieldListCommaOrEnd = FieldCtx{
488 .doc_comments = &node.doc_comments,
489 .container_decl = container_decl,
490 },
491 });
477 try stack.append(State{ .FieldInitValue = OptionalCtx{ .RequiredNull = &node.value_expr } });492 try stack.append(State{ .FieldInitValue = OptionalCtx{ .RequiredNull = &node.value_expr } });
478 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .RequiredNull = &node.type_expr } });493 try stack.append(State{ .TypeExprBegin = OptionalCtx{ .RequiredNull = &node.type_expr } });
479 try stack.append(State{ .IfToken = Token.Id.Colon });494 try stack.append(State{ .IfToken = Token.Id.Colon });
...@@ -488,7 +503,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -488,7 +503,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
488 });503 });
489 try container_decl.fields_and_decls.push(&node.base);504 try container_decl.fields_and_decls.push(&node.base);
490505
491 stack.append(State{ .FieldListCommaOrEnd = container_decl }) catch unreachable;506 try stack.append(State{
507 .FieldListCommaOrEnd = FieldCtx{
508 .doc_comments = &node.doc_comments,
509 .container_decl = container_decl,
510 },
511 });
492 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &node.value } });512 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &node.value } });
493 try stack.append(State{ .IfToken = Token.Id.Equal });513 try stack.append(State{ .IfToken = Token.Id.Equal });
494 continue;514 continue;
...@@ -1265,17 +1285,35 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {...@@ -1265,17 +1285,35 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
1265 },1285 },
1266 }1286 }
1267 },1287 },
1268 State.FieldListCommaOrEnd => |container_decl| {1288 State.FieldListCommaOrEnd => |field_ctx| {
1269 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {1289 const end_token = nextToken(&tok_it, &tree);
1270 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {1290 const end_token_index = end_token.index;
1271 container_decl.rbrace_token = end;1291 const end_token_ptr = end_token.ptr;
1292 switch (end_token_ptr.id) {
1293 Token.Id.Comma => {
1294 if (eatToken(&tok_it, &tree, Token.Id.DocComment)) |doc_comment_token| {
1295 const loc = tree.tokenLocation(end_token_ptr.end, doc_comment_token);
1296 if (loc.line == 0) {
1297 try pushDocComment(arena, doc_comment_token, field_ctx.doc_comments);
1298 } else {
1299 prevToken(&tok_it, &tree);
1300 }
1301 }
1302
1303 try stack.append(State{ .ContainerDecl = field_ctx.container_decl });
1272 continue;1304 continue;
1273 } else {1305 },
1274 try stack.append(State{ .ContainerDecl = container_decl });1306 Token.Id.RBrace => {
1307 field_ctx.container_decl.rbrace_token = end_token_index;
1275 continue;1308 continue;
1276 },1309 },
1277 ExpectCommaOrEndResult.parse_error => |e| {1310 else => {
1278 try tree.errors.push(e);1311 try tree.errors.push(Error{
1312 .ExpectedCommaOrEnd = Error.ExpectedCommaOrEnd{
1313 .token = end_token_index,
1314 .end_id = end_token_ptr.id,
1315 },
1316 });
1279 return tree;1317 return tree;
1280 },1318 },
1281 }1319 }
...@@ -2813,6 +2851,11 @@ const ExprListCtx = struct {...@@ -2813,6 +2851,11 @@ const ExprListCtx = struct {
2813 ptr: *TokenIndex,2851 ptr: *TokenIndex,
2814};2852};
28152853
2854const FieldCtx = struct {
2855 container_decl: *ast.Node.ContainerDecl,
2856 doc_comments: *?*ast.Node.DocComment,
2857};
2858
2816fn ListSave(comptime List: type) type {2859fn ListSave(comptime List: type) type {
2817 return struct {2860 return struct {
2818 list: *List,2861 list: *List,
...@@ -2950,7 +2993,7 @@ const State = union(enum) {...@@ -2950,7 +2993,7 @@ const State = union(enum) {
2950 ExprListCommaOrEnd: ExprListCtx,2993 ExprListCommaOrEnd: ExprListCtx,
2951 FieldInitListItemOrEnd: ListSave(ast.Node.SuffixOp.Op.InitList),2994 FieldInitListItemOrEnd: ListSave(ast.Node.SuffixOp.Op.InitList),
2952 FieldInitListCommaOrEnd: ListSave(ast.Node.SuffixOp.Op.InitList),2995 FieldInitListCommaOrEnd: ListSave(ast.Node.SuffixOp.Op.InitList),
2953 FieldListCommaOrEnd: *ast.Node.ContainerDecl,2996 FieldListCommaOrEnd: FieldCtx,
2954 FieldInitValue: OptionalCtx,2997 FieldInitValue: OptionalCtx,
2955 ErrorTagListItemOrEnd: ListSave(ast.Node.ErrorSetDecl.DeclList),2998 ErrorTagListItemOrEnd: ListSave(ast.Node.ErrorSetDecl.DeclList),
2956 ErrorTagListCommaOrEnd: ListSave(ast.Node.ErrorSetDecl.DeclList),2999 ErrorTagListCommaOrEnd: ListSave(ast.Node.ErrorSetDecl.DeclList),
std/zig/parser_test.zig+17
...@@ -1,3 +1,20 @@...@@ -1,3 +1,20 @@
1test "zig fmt: correctly move doc comments on struct fields" {
2 try testTransform(
3 \\pub const section_64 = extern struct {
4 \\ sectname: [16]u8, /// name of this section
5 \\ segname: [16]u8, /// segment this section goes in
6 \\};
7 ,
8 \\pub const section_64 = extern struct {
9 \\ /// name of this section
10 \\ sectname: [16]u8,
11 \\ /// segment this section goes in
12 \\ segname: [16]u8,
13 \\};
14 \\
15 );
16}
17
1test "zig fmt: preserve space between async fn definitions" {18test "zig fmt: preserve space between async fn definitions" {
2 try testCanonical(19 try testCanonical(
3 \\async fn a() void {}20 \\async fn a() void {}