authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-19 22:54:47+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-19 22:59:27+01:00
log95b95ea33e4b595d2fc6fbea850694b79f27fe55
tree7f22d836466700d51acaaf1a943dcdf8dd25f256
parent6f6568b1fdb30fc8574b3047470510b798307717
signaturelock-open Commit is signed but in an unrecognized format.

stage2: make same line doc comments a parse error

Allowing same line doc comments causes some ambiguity as to how generated docs should represent the case in which both same line and preceding line doc comments are present: /// preceding line const foobar = 42; /// same line Furthermore disallowing these makes things simpler as there is now only one way to add a doc comment to a decl or struct field.

3 files changed, 39 insertions(+), 59 deletions(-)

lib/std/zig/ast.zig+4
...@@ -146,6 +146,7 @@ pub const Tree = struct {...@@ -146,6 +146,7 @@ pub const Tree = struct {
146 .ExpectedFn => |*x| return x.render(tokens, stream),146 .ExpectedFn => |*x| return x.render(tokens, stream),
147 .ExpectedReturnType => |*x| return x.render(tokens, stream),147 .ExpectedReturnType => |*x| return x.render(tokens, stream),
148 .ExpectedAggregateKw => |*x| return x.render(tokens, stream),148 .ExpectedAggregateKw => |*x| return x.render(tokens, stream),
149 .SameLineDocComment => |*x| return x.render(tokens, stream),
149 .UnattachedDocComment => |*x| return x.render(tokens, stream),150 .UnattachedDocComment => |*x| return x.render(tokens, stream),
150 .ExpectedEqOrSemi => |*x| return x.render(tokens, stream),151 .ExpectedEqOrSemi => |*x| return x.render(tokens, stream),
151 .ExpectedSemiOrLBrace => |*x| return x.render(tokens, stream),152 .ExpectedSemiOrLBrace => |*x| return x.render(tokens, stream),
...@@ -200,6 +201,7 @@ pub const Tree = struct {...@@ -200,6 +201,7 @@ pub const Tree = struct {
200 .ExpectedFn => |x| return x.token,201 .ExpectedFn => |x| return x.token,
201 .ExpectedReturnType => |x| return x.token,202 .ExpectedReturnType => |x| return x.token,
202 .ExpectedAggregateKw => |x| return x.token,203 .ExpectedAggregateKw => |x| return x.token,
204 .SameLineDocComment => |x| return x.token,
203 .UnattachedDocComment => |x| return x.token,205 .UnattachedDocComment => |x| return x.token,
204 .ExpectedEqOrSemi => |x| return x.token,206 .ExpectedEqOrSemi => |x| return x.token,
205 .ExpectedSemiOrLBrace => |x| return x.token,207 .ExpectedSemiOrLBrace => |x| return x.token,
...@@ -2250,6 +2252,7 @@ pub const Error = union(enum) {...@@ -2250,6 +2252,7 @@ pub const Error = union(enum) {
2250 ExpectedFn: ExpectedFn,2252 ExpectedFn: ExpectedFn,
2251 ExpectedReturnType: ExpectedReturnType,2253 ExpectedReturnType: ExpectedReturnType,
2252 ExpectedAggregateKw: ExpectedAggregateKw,2254 ExpectedAggregateKw: ExpectedAggregateKw,
2255 SameLineDocComment: SameLineDocComment,
2253 UnattachedDocComment: UnattachedDocComment,2256 UnattachedDocComment: UnattachedDocComment,
2254 ExpectedEqOrSemi: ExpectedEqOrSemi,2257 ExpectedEqOrSemi: ExpectedEqOrSemi,
2255 ExpectedSemiOrLBrace: ExpectedSemiOrLBrace,2258 ExpectedSemiOrLBrace: ExpectedSemiOrLBrace,
...@@ -2326,6 +2329,7 @@ pub const Error = union(enum) {...@@ -2326,6 +2329,7 @@ pub const Error = union(enum) {
23262329
2327 pub const ExpectedParamType = SimpleError("Expected parameter type");2330 pub const ExpectedParamType = SimpleError("Expected parameter type");
2328 pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub");2331 pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub");
2332 pub const SameLineDocComment = SimpleError("Same line documentation comment");
2329 pub const UnattachedDocComment = SimpleError("Unattached documentation comment");2333 pub const UnattachedDocComment = SimpleError("Unattached documentation comment");
2330 pub const ExtraAlignQualifier = SimpleError("Extra align qualifier");2334 pub const ExtraAlignQualifier = SimpleError("Extra align qualifier");
2331 pub const ExtraConstQualifier = SimpleError("Extra const qualifier");2335 pub const ExtraConstQualifier = SimpleError("Extra const qualifier");
lib/std/zig/parse.zig+10-16
...@@ -190,7 +190,7 @@ const Parser = struct {...@@ -190,7 +190,7 @@ const Parser = struct {
190190
191 var trailing_comma = false;191 var trailing_comma = false;
192 while (true) {192 while (true) {
193 const doc_comment = p.eatDocComments();193 const doc_comment = try p.eatDocComments ();
194194
195 switch (p.token_tags[p.tok_i]) {195 switch (p.token_tags[p.tok_i]) {
196 .keyword_test => {196 .keyword_test => {
...@@ -515,7 +515,6 @@ const Parser = struct {...@@ -515,7 +515,6 @@ const Parser = struct {
515 switch (p.token_tags[p.tok_i]) {515 switch (p.token_tags[p.tok_i]) {
516 .semicolon => {516 .semicolon => {
517 const semicolon_token = p.nextToken();517 const semicolon_token = p.nextToken();
518 try p.parseAppendedDocComment(semicolon_token);
519 return p.addNode(.{518 return p.addNode(.{
520 .tag = .fn_decl,519 .tag = .fn_decl,
521 .main_token = p.nodes.items(.main_token)[fn_proto],520 .main_token = p.nodes.items(.main_token)[fn_proto],
...@@ -557,7 +556,6 @@ const Parser = struct {...@@ -557,7 +556,6 @@ const Parser = struct {
557 const var_decl = try p.parseVarDecl();556 const var_decl = try p.parseVarDecl();
558 if (var_decl != 0) {557 if (var_decl != 0) {
559 const semicolon_token = try p.expectToken(.semicolon);558 const semicolon_token = try p.expectToken(.semicolon);
560 try p.parseAppendedDocComment(semicolon_token);
561 return var_decl;559 return var_decl;
562 }560 }
563 if (thread_local_token != null) {561 if (thread_local_token != null) {
...@@ -585,7 +583,6 @@ const Parser = struct {...@@ -585,7 +583,6 @@ const Parser = struct {
585 const usingnamespace_token = try p.expectToken(.keyword_usingnamespace);583 const usingnamespace_token = try p.expectToken(.keyword_usingnamespace);
586 const expr = try p.expectExpr();584 const expr = try p.expectExpr();
587 const semicolon_token = try p.expectToken(.semicolon);585 const semicolon_token = try p.expectToken(.semicolon);
588 try p.parseAppendedDocComment(semicolon_token);
589 return p.addNode(.{586 return p.addNode(.{
590 .tag = .@"usingnamespace",587 .tag = .@"usingnamespace",
591 .main_token = usingnamespace_token,588 .main_token = usingnamespace_token,
...@@ -2885,7 +2882,7 @@ const Parser = struct {...@@ -2885,7 +2882,7 @@ const Parser = struct {
2885 }2882 }
28862883
2887 while (true) {2884 while (true) {
2888 const doc_comment = p.eatDocComments();2885 const doc_comment = try p.eatDocComments();
2889 const identifier = try p.expectToken(.identifier);2886 const identifier = try p.expectToken(.identifier);
2890 switch (p.token_tags[p.nextToken()]) {2887 switch (p.token_tags[p.nextToken()]) {
2891 .comma => {2888 .comma => {
...@@ -3274,7 +3271,7 @@ const Parser = struct {...@@ -3274,7 +3271,7 @@ const Parser = struct {
3274 /// such as in the case of anytype and `...`. Caller must look for rparen to find3271 /// such as in the case of anytype and `...`. Caller must look for rparen to find
3275 /// out when there are no more param decls left.3272 /// out when there are no more param decls left.
3276 fn expectParamDecl(p: *Parser) !Node.Index {3273 fn expectParamDecl(p: *Parser) !Node.Index {
3277 _ = p.eatDocComments();3274 _ = try p.eatDocComments();
3278 switch (p.token_tags[p.tok_i]) {3275 switch (p.token_tags[p.tok_i]) {
3279 .keyword_noalias, .keyword_comptime => p.tok_i += 1,3276 .keyword_noalias, .keyword_comptime => p.tok_i += 1,
3280 .ellipsis3 => {3277 .ellipsis3 => {
...@@ -4075,8 +4072,13 @@ const Parser = struct {...@@ -4075,8 +4072,13 @@ const Parser = struct {
4075 }4072 }
40764073
4077 /// Skips over doc comment tokens. Returns the first one, if any.4074 /// Skips over doc comment tokens. Returns the first one, if any.
4078 fn eatDocComments(p: *Parser) ?TokenIndex {4075 fn eatDocComments(p: *Parser) !?TokenIndex {
4079 if (p.eatToken(.doc_comment)) |first_line| {4076 if (p.eatToken(.doc_comment)) |tok| {
4077 var first_line = tok;
4078 if (tok > 0 and tokensOnSameLine(p, tok - 1, tok)) {
4079 try p.warn(.{ .SameLineDocComment = .{ .token = tok } });
4080 first_line = p.eatToken(.doc_comment) orelse return null;
4081 }
4080 while (p.eatToken(.doc_comment)) |_| {}4082 while (p.eatToken(.doc_comment)) |_| {}
4081 return first_line;4083 return first_line;
4082 }4084 }
...@@ -4087,14 +4089,6 @@ const Parser = struct {...@@ -4087,14 +4089,6 @@ const Parser = struct {
4087 return std.mem.indexOfScalar(u8, p.source[p.token_starts[token1]..p.token_starts[token2]], '\n') == null;4089 return std.mem.indexOfScalar(u8, p.source[p.token_starts[token1]..p.token_starts[token2]], '\n') == null;
4088 }4090 }
40894091
4090 /// Eat a single-line doc comment on the same line as another node
4091 fn parseAppendedDocComment(p: *Parser, after_token: TokenIndex) !void {
4092 const comment_token = p.eatToken(.doc_comment) orelse return;
4093 if (!p.tokensOnSameLine(after_token, comment_token)) {
4094 p.tok_i -= 1;
4095 }
4096 }
4097
4098 fn eatToken(p: *Parser, tag: Token.Tag) ?TokenIndex {4092 fn eatToken(p: *Parser, tag: Token.Tag) ?TokenIndex {
4099 return if (p.token_tags[p.tok_i] == tag) p.nextToken() else null;4093 return if (p.token_tags[p.tok_i] == tag) p.nextToken() else null;
4100 }4094 }
lib/std/zig/parser_test.zig+25-43
...@@ -1016,23 +1016,6 @@ test "zig fmt: linksection" {...@@ -1016,23 +1016,6 @@ test "zig fmt: linksection" {
1016 );1016 );
1017}1017}
10181018
1019//test "zig fmt: correctly move doc comments on struct fields" {
1020// try testTransform(
1021// \\pub const section_64 = extern struct {
1022// \\ sectname: [16]u8, /// name of this section
1023// \\ segname: [16]u8, /// segment this section goes in
1024// \\};
1025// ,
1026// \\pub const section_64 = extern struct {
1027// \\ /// name of this section
1028// \\ sectname: [16]u8,
1029// \\ /// segment this section goes in
1030// \\ segname: [16]u8,
1031// \\};
1032// \\
1033// );
1034//}
1035
1036test "zig fmt: correctly space struct fields with doc comments" {1019test "zig fmt: correctly space struct fields with doc comments" {
1037 try testTransform(1020 try testTransform(
1038 \\pub const S = struct {1021 \\pub const S = struct {
...@@ -1449,31 +1432,6 @@ test "zig fmt: async call in if condition" {...@@ -1449,31 +1432,6 @@ test "zig fmt: async call in if condition" {
1449// \\1432// \\
1450// );1433// );
1451//}1434//}
1452//
1453//test "zig fmt: same-line doc comment on variable declaration" {
1454// try testTransform(
1455// \\pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
1456// \\pub const MAP_FILE = 0x0000; /// map from file (default)
1457// \\
1458// \\pub const EMEDIUMTYPE = 124; /// Wrong medium type
1459// \\
1460// \\// nameserver query return codes
1461// \\pub const ENSROK = 0; /// DNS server returned answer with no data
1462// ,
1463// \\/// allocated from memory, swap space
1464// \\pub const MAP_ANONYMOUS = 0x1000;
1465// \\/// map from file (default)
1466// \\pub const MAP_FILE = 0x0000;
1467// \\
1468// \\/// Wrong medium type
1469// \\pub const EMEDIUMTYPE = 124;
1470// \\
1471// \\// nameserver query return codes
1472// \\/// DNS server returned answer with no data
1473// \\pub const ENSROK = 0;
1474// \\
1475// );
1476//}
14771435
1478test "zig fmt: if-else with comment before else" {1436test "zig fmt: if-else with comment before else" {
1479 try testCanonical(1437 try testCanonical(
...@@ -3625,6 +3583,30 @@ test "zig fmt: file ends with struct field" {...@@ -3625,6 +3583,30 @@ test "zig fmt: file ends with struct field" {
3625// });3583// });
3626//}3584//}
36273585
3586test "zig fmt: same line doc comment returns error" {
3587 try testError(
3588 \\const Foo = struct{
3589 \\ bar: u32, /// comment
3590 \\ foo: u32, /// comment
3591 \\ /// commment
3592 \\};
3593 \\
3594 \\const a = 42; /// comment
3595 \\
3596 \\extern fn foo() void; /// comment
3597 \\
3598 \\/// comment
3599 \\
3600 , &[_]Error{
3601 .SameLineDocComment,
3602 .SameLineDocComment,
3603 .UnattachedDocComment,
3604 .SameLineDocComment,
3605 .SameLineDocComment,
3606 .UnattachedDocComment,
3607 });
3608}
3609
3628test "zig fmt: integer literals with underscore separators" {3610test "zig fmt: integer literals with underscore separators" {
3629 try testTransform(3611 try testTransform(
3630 \\const3612 \\const
...@@ -4388,6 +4370,6 @@ fn testError(source: []const u8, expected_errors: []const Error) !void {...@@ -4388,6 +4370,6 @@ fn testError(source: []const u8, expected_errors: []const Error) !void {
43884370
4389 std.testing.expect(tree.errors.len == expected_errors.len);4371 std.testing.expect(tree.errors.len == expected_errors.len);
4390 for (expected_errors) |expected, i| {4372 for (expected_errors) |expected, i| {
4391 std.testing.expect(expected == tree.errors[i]);4373 std.testing.expectEqual(expected, tree.errors[i]);
4392 }4374 }
4393}4375}