| author | |
| committer | |
| log | 95b95ea33e4b595d2fc6fbea850694b79f27fe55 |
| tree | 7f22d836466700d51acaaf1a943dcdf8dd25f256 |
| parent | 6f6568b1fdb30fc8574b3047470510b798307717 |
| signature |
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) { |
| 2326 | 2329 | ||
| 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 { |
| 190 | 190 | ||
| 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 (); |
| 194 | 194 | ||
| 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 | } |
| 2886 | 2883 | ||
| 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 find | 3271 | /// 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 | } |
| 4076 | 4073 | ||
| 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 | } |
| 4089 | 4091 | ||
| 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 | } |
| 1018 | 1018 | ||
| 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 | |||
| 1036 | test "zig fmt: correctly space struct fields with doc comments" { | 1019 | test "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 | //} | ||
| 1477 | 1435 | ||
| 1478 | test "zig fmt: if-else with comment before else" { | 1436 | test "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 | //} |
| 3627 | 3585 | ||
| 3586 | test "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 | |||
| 3628 | test "zig fmt: integer literals with underscore separators" { | 3610 | test "zig fmt: integer literals with underscore separators" { |
| 3629 | try testTransform( | 3611 | try testTransform( |
| 3630 | \\const | 3612 | \\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 { |
| 4388 | 4370 | ||
| 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 | } |