diff options
| author | Isaac Freund <ifreund@ifreund.xyz> | 2021-02-23 18:32:47 +0100 |
|---|---|---|
| committer | Isaac Freund <ifreund@ifreund.xyz> | 2021-02-23 18:32:47 +0100 |
| commit | 5306b1a9ab5cb0730fcc21da095db39b0197e99b (patch) | |
| tree | bd7ba4faa7a0c25726d0ce19da12c8b33777873c /lib/std | |
| parent | 1f62e87031cbb85387934313a7a9e7091d424b84 (diff) | |
| download | zig-5306b1a9ab5cb0730fcc21da095db39b0197e99b.tar.gz zig-5306b1a9ab5cb0730fcc21da095db39b0197e99b.zip | |
zig fmt: container doc comments
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/zig/ast.zig | 82 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 54 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 110 | ||||
| -rw-r--r-- | lib/std/zig/render.zig | 69 |
4 files changed, 169 insertions, 146 deletions
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index abe4993d3e..98ffe26818 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -525,17 +525,17 @@ pub const Tree = struct { }, .container_decl, - .container_decl_comma, + .container_decl_trailing, .container_decl_two, - .container_decl_two_comma, + .container_decl_two_trailing, .container_decl_arg, - .container_decl_arg_comma, + .container_decl_arg_trailing, .tagged_union, - .tagged_union_comma, + .tagged_union_trailing, .tagged_union_two, - .tagged_union_two_comma, + .tagged_union_two_trailing, .tagged_union_enum_tag, - .tagged_union_enum_tag_comma, + .tagged_union_enum_tag_trailing, => { const main_token = main_tokens[n]; switch (token_tags[main_token - 1]) { @@ -606,6 +606,7 @@ pub const Tree = struct { const datas = tree.nodes.items(.data); const main_tokens = tree.nodes.items(.main_token); const token_starts = tree.tokens.items(.start); + const token_tags = tree.tokens.items(.tag); var n = node; var end_offset: TokenIndex = 0; while (true) switch (tags[n]) { @@ -738,9 +739,9 @@ pub const Tree = struct { }, .call_comma, .async_call_comma, - .tagged_union_enum_tag_comma, + .tagged_union_enum_tag_trailing, => { - end_offset += 2; // for the comma + rparen/rbrace + end_offset += 2; // for the comma/semicolon + rparen/rbrace const params = tree.extraData(datas[n].rhs, Node.SubRange); assert(params.end > params.start); n = tree.extra_data[params.end - 1]; // last parameter @@ -779,7 +780,7 @@ pub const Tree = struct { }, .array_init_comma, .struct_init_comma, - .container_decl_arg_comma, + .container_decl_arg_trailing, .switch_comma, => { const members = tree.extraData(datas[n].rhs, Node.SubRange); @@ -801,8 +802,8 @@ pub const Tree = struct { .array_init_dot_comma, .struct_init_dot_comma, .block_semicolon, - .container_decl_comma, - .tagged_union_comma, + .container_decl_trailing, + .tagged_union_trailing, .builtin_call_comma, => { assert(datas[n].rhs - datas[n].lhs > 0); @@ -838,10 +839,17 @@ pub const Tree = struct { .block_two, .struct_init_dot_two, => end_offset += 1, // rbrace - .builtin_call_two, - .container_decl_two, - => end_offset += 2, // lparen/lbrace + rparen/rbrace - .tagged_union_two => end_offset += 5, // (enum) {} + .builtin_call_two => end_offset += 2, // lparen/lbrace + rparen/rbrace + .container_decl_two => { + var i: u32 = 2; // lbrace + rbrace + while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1; + end_offset += i; + }, + .tagged_union_two => { + var i: u32 = 5; // (enum) {} + while (token_tags[main_tokens[n] + i] == .container_doc_comment) i += 1; + end_offset += i; + }, else => unreachable, } return main_tokens[n] + end_offset; @@ -851,8 +859,8 @@ pub const Tree = struct { .builtin_call_two_comma, .block_two_semicolon, .struct_init_dot_two_comma, - .container_decl_two_comma, - .tagged_union_two_comma, + .container_decl_two_trailing, + .tagged_union_two_trailing, => { end_offset += 2; // for the comma/semicolon + rbrace/rparen if (datas[n].rhs != 0) { @@ -1531,7 +1539,7 @@ pub const Tree = struct { pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { assert(tree.nodes.items(.tag)[node] == .container_decl_two or - tree.nodes.items(.tag)[node] == .container_decl_two_comma); + tree.nodes.items(.tag)[node] == .container_decl_two_trailing); const data = tree.nodes.items(.data)[node]; buffer.* = .{ data.lhs, data.rhs }; const members = if (data.rhs != 0) @@ -1550,7 +1558,7 @@ pub const Tree = struct { pub fn containerDecl(tree: Tree, node: Node.Index) full.ContainerDecl { assert(tree.nodes.items(.tag)[node] == .container_decl or - tree.nodes.items(.tag)[node] == .container_decl_comma); + tree.nodes.items(.tag)[node] == .container_decl_trailing); const data = tree.nodes.items(.data)[node]; return tree.fullContainerDecl(.{ .main_token = tree.nodes.items(.main_token)[node], @@ -1562,7 +1570,7 @@ pub const Tree = struct { pub fn containerDeclArg(tree: Tree, node: Node.Index) full.ContainerDecl { assert(tree.nodes.items(.tag)[node] == .container_decl_arg or - tree.nodes.items(.tag)[node] == .container_decl_arg_comma); + tree.nodes.items(.tag)[node] == .container_decl_arg_trailing); const data = tree.nodes.items(.data)[node]; const members_range = tree.extraData(data.rhs, Node.SubRange); return tree.fullContainerDecl(.{ @@ -1575,7 +1583,7 @@ pub const Tree = struct { pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) full.ContainerDecl { assert(tree.nodes.items(.tag)[node] == .tagged_union_two or - tree.nodes.items(.tag)[node] == .tagged_union_two_comma); + tree.nodes.items(.tag)[node] == .tagged_union_two_trailing); const data = tree.nodes.items(.data)[node]; buffer.* = .{ data.lhs, data.rhs }; const members = if (data.rhs != 0) @@ -1595,7 +1603,7 @@ pub const Tree = struct { pub fn taggedUnion(tree: Tree, node: Node.Index) full.ContainerDecl { assert(tree.nodes.items(.tag)[node] == .tagged_union or - tree.nodes.items(.tag)[node] == .tagged_union_comma); + tree.nodes.items(.tag)[node] == .tagged_union_trailing); const data = tree.nodes.items(.data)[node]; const main_token = tree.nodes.items(.main_token)[node]; return tree.fullContainerDecl(.{ @@ -1608,7 +1616,7 @@ pub const Tree = struct { pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) full.ContainerDecl { assert(tree.nodes.items(.tag)[node] == .tagged_union_enum_tag or - tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_comma); + tree.nodes.items(.tag)[node] == .tagged_union_enum_tag_trailing); const data = tree.nodes.items(.data)[node]; const members_range = tree.extraData(data.rhs, Node.SubRange); const main_token = tree.nodes.items(.main_token)[node]; @@ -2762,36 +2770,40 @@ pub const Node = struct { /// `struct {}`, `union {}`, `opaque {}`, `enum {}`. `extra_data[lhs..rhs]`. /// main_token is `struct`, `union`, `opaque`, `enum` keyword. container_decl, - /// Same as ContainerDecl but there is known to be a trailing comma before the rbrace. - container_decl_comma, + /// Same as ContainerDecl but there is known to be a trailing comma + /// or semicolon before the rbrace. + container_decl_trailing, /// `struct {lhs, rhs}`, `union {lhs, rhs}`, `opaque {lhs, rhs}`, `enum {lhs, rhs}`. /// lhs or rhs can be omitted. /// main_token is `struct`, `union`, `opaque`, `enum` keyword. container_decl_two, /// Same as ContainerDeclTwo except there is known to be a trailing comma - /// before the rbrace. - container_decl_two_comma, + /// or semicolon before the rbrace. + container_decl_two_trailing, /// `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`. container_decl_arg, - /// Same as container_decl_arg but there is known to be a trailing comma before the rbrace. - container_decl_arg_comma, + /// Same as container_decl_arg but there is known to be a trailing + /// comma or semicolon before the rbrace. + container_decl_arg_trailing, /// `union(enum) {}`. `sub_list[lhs..rhs]`. /// Note that tagged unions with explicitly provided enums are represented /// by `container_decl_arg`. tagged_union, - /// Same as tagged_union but there is known to be a trailing comma before the rbrace. - tagged_union_comma, + /// Same as tagged_union but there is known to be a trailing comma + /// or semicolon before the rbrace. + tagged_union_trailing, /// `union(enum) {lhs, rhs}`. lhs or rhs may be omitted. /// Note that tagged unions with explicitly provided enums are represented /// by `container_decl_arg`. tagged_union_two, - /// Same as tagged_union_two but there is known to be a trailing comma before the rbrace. - tagged_union_two_comma, + /// Same as tagged_union_two but there is known to be a trailing comma + /// or semicolon before the rbrace. + tagged_union_two_trailing, /// `union(enum(lhs)) {}`. `SubRange[rhs]`. tagged_union_enum_tag, /// Same as tagged_union_enum_tag but there is known to be a trailing comma - /// before the rbrace. - tagged_union_enum_tag_comma, + /// or semicolon before the rbrace. + tagged_union_enum_tag_trailing, /// `a: lhs = rhs,`. lhs and rhs can be omitted. /// main_token is the field name identifier. /// lastToken() does not include the possible trailing comma. diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index f5672bedf9..528b684e46 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -113,7 +113,7 @@ const Parser = struct { len: usize, lhs: Node.Index, rhs: Node.Index, - trailing_comma: bool, + trailing: bool, fn toSpan(self: Members, p: *Parser) !Node.SubRange { if (self.len <= 2) { @@ -215,7 +215,7 @@ const Parser = struct { // Skip container doc comments. while (p.eatToken(.container_doc_comment)) |_| {} - var trailing_comma = false; + var trailing = false; while (true) { const doc_comment = try p.eatDocComments(); @@ -228,7 +228,7 @@ const Parser = struct { } try list.append(test_decl_node); } - trailing_comma = false; + trailing = false; }, .keyword_comptime => switch (p.token_tags[p.tok_i + 1]) { .identifier => { @@ -251,11 +251,11 @@ const Parser = struct { switch (p.token_tags[p.tok_i]) { .comma => { p.tok_i += 1; - trailing_comma = true; + trailing = true; continue; }, .r_brace, .eof => { - trailing_comma = false; + trailing = false; break; }, else => {}, @@ -289,7 +289,7 @@ const Parser = struct { } try list.append(comptime_node); } - trailing_comma = false; + trailing = false; }, else => { p.tok_i += 1; @@ -305,7 +305,7 @@ const Parser = struct { } try list.append(top_level_decl); } - trailing_comma = false; + trailing = p.token_tags[p.tok_i - 1] == .semicolon; }, .keyword_usingnamespace => { const node = try p.expectUsingNamespaceRecoverable(); @@ -315,7 +315,7 @@ const Parser = struct { } try list.append(node); } - trailing_comma = false; + trailing = p.token_tags[p.tok_i - 1] == .semicolon; }, .keyword_const, .keyword_var, @@ -333,7 +333,7 @@ const Parser = struct { } try list.append(top_level_decl); } - trailing_comma = false; + trailing = p.token_tags[p.tok_i - 1] == .semicolon; }, .identifier => { const container_field = try p.expectContainerFieldRecoverable(); @@ -354,11 +354,11 @@ const Parser = struct { switch (p.token_tags[p.tok_i]) { .comma => { p.tok_i += 1; - trailing_comma = true; + trailing = true; continue; }, .r_brace, .eof => { - trailing_comma = false; + trailing = false; break; }, else => {}, @@ -391,19 +391,19 @@ const Parser = struct { .len = 0, .lhs = 0, .rhs = 0, - .trailing_comma = trailing_comma, + .trailing = trailing, }, 1 => return Members{ .len = 1, .lhs = list.items[0], .rhs = 0, - .trailing_comma = trailing_comma, + .trailing = trailing, }, 2 => return Members{ .len = 2, .lhs = list.items[0], .rhs = list.items[1], - .trailing_comma = trailing_comma, + .trailing = trailing, }, else => { const span = try p.listToSpan(list.items); @@ -411,7 +411,7 @@ const Parser = struct { .len = list.items.len, .lhs = span.start, .rhs = span.end, - .trailing_comma = trailing_comma, + .trailing = trailing, }; }, } @@ -3575,8 +3575,8 @@ const Parser = struct { const members_span = try members.toSpan(p); _ = try p.expectToken(.r_brace); return p.addNode(.{ - .tag = switch (members.trailing_comma) { - true => .tagged_union_enum_tag_comma, + .tag = switch (members.trailing) { + true => .tagged_union_enum_tag_trailing, false => .tagged_union_enum_tag, }, .main_token = main_token, @@ -3593,8 +3593,8 @@ const Parser = struct { _ = try p.expectToken(.r_brace); if (members.len <= 2) { return p.addNode(.{ - .tag = switch (members.trailing_comma) { - true => .tagged_union_two_comma, + .tag = switch (members.trailing) { + true => .tagged_union_two_trailing, false => .tagged_union_two, }, .main_token = main_token, @@ -3606,8 +3606,8 @@ const Parser = struct { } else { const span = try members.toSpan(p); return p.addNode(.{ - .tag = switch (members.trailing_comma) { - true => .tagged_union_comma, + .tag = switch (members.trailing) { + true => .tagged_union_trailing, false => .tagged_union, }, .main_token = main_token, @@ -3638,8 +3638,8 @@ const Parser = struct { if (arg_expr == 0) { if (members.len <= 2) { return p.addNode(.{ - .tag = switch (members.trailing_comma) { - true => .container_decl_two_comma, + .tag = switch (members.trailing) { + true => .container_decl_two_trailing, false => .container_decl_two, }, .main_token = main_token, @@ -3651,8 +3651,8 @@ const Parser = struct { } else { const span = try members.toSpan(p); return p.addNode(.{ - .tag = switch (members.trailing_comma) { - true => .container_decl_comma, + .tag = switch (members.trailing) { + true => .container_decl_trailing, false => .container_decl, }, .main_token = main_token, @@ -3665,8 +3665,8 @@ const Parser = struct { } else { const span = try members.toSpan(p); return p.addNode(.{ - .tag = switch (members.trailing_comma) { - true => .container_decl_arg_comma, + .tag = switch (members.trailing) { + true => .container_decl_arg_trailing, false => .container_decl_arg, }, .main_token = main_token, diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 27e49b4c01..7185eb1588 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -3577,61 +3577,61 @@ test "zig fmt: file ends with struct field" { // ); //} -//test "zig fmt: top level doc comments" { -// try testCanonical( -// \\//! tld 1 -// \\//! tld 2 -// \\//! tld 3 -// \\ -// \\// comment -// \\ -// \\/// A doc -// \\const A = struct { -// \\ //! A tld 1 -// \\ //! A tld 2 -// \\ //! A tld 3 -// \\}; -// \\ -// \\/// B doc -// \\const B = struct { -// \\ //! B tld 1 -// \\ //! B tld 2 -// \\ //! B tld 3 -// \\ -// \\ /// b doc -// \\ b: u32, -// \\}; -// \\ -// \\/// C doc -// \\const C = struct { -// \\ //! C tld 1 -// \\ //! C tld 2 -// \\ //! C tld 3 -// \\ -// \\ /// c1 doc -// \\ c1: u32, -// \\ -// \\ //! C tld 4 -// \\ //! C tld 5 -// \\ //! C tld 6 -// \\ -// \\ /// c2 doc -// \\ c2: u32, -// \\}; -// \\ -// ); -// try testCanonical( -// \\//! Top-level documentation. -// \\ -// \\/// This is A -// \\pub const A = usize; -// \\ -// ); -// try testCanonical( -// \\//! Nothing here -// \\ -// ); -//} +test "zig fmt: container doc comments" { + try testCanonical( + \\//! tld 1 + \\//! tld 2 + \\//! tld 3 + \\ + \\// comment + \\ + \\/// A doc + \\const A = struct { + \\ //! A tld 1 + \\ //! A tld 2 + \\ //! A tld 3 + \\}; + \\ + \\/// B doc + \\const B = struct { + \\ //! B tld 1 + \\ //! B tld 2 + \\ //! B tld 3 + \\ + \\ /// B doc + \\ b: u32, + \\}; + \\ + \\/// C doc + \\const C = union(enum) { // comment + \\ //! C tld 1 + \\ //! C tld 2 + \\ //! C tld 3 + \\}; + \\ + \\/// D doc + \\const D = union(Foo) { + \\ //! D tld 1 + \\ //! D tld 2 + \\ //! D tld 3 + \\ + \\ /// D doc + \\ b: u32, + \\}; + \\ + ); + try testCanonical( + \\//! Top-level documentation. + \\ + \\/// This is A + \\pub const A = usize; + \\ + ); + try testCanonical( + \\//! Nothing here + \\ + ); +} test "zig fmt: extern without container keyword returns error" { try testError( diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 0a1b6c19c0..ab00a787c5 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -30,6 +30,10 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void { const comment_end_loc = tree.tokens.items(.start)[0]; _ = try renderComments(ais, tree, 0, comment_end_loc); + if (tree.tokens.items(.tag)[0] == .container_doc_comment) { + try renderContainerDocComments(ais, tree, 0); + } + try renderMembers(buffer.allocator, ais, tree, tree.rootDecls()); if (ais.disabled_offset) |disabled_offset| { @@ -506,28 +510,28 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I }, .container_decl, - .container_decl_comma, - => return renderContainerDecl(gpa, ais, tree, tree.containerDecl(node), space), + .container_decl_trailing, + => return renderContainerDecl(gpa, ais, tree, node, tree.containerDecl(node), space), - .container_decl_two, .container_decl_two_comma => { + .container_decl_two, .container_decl_two_trailing => { var buffer: [2]ast.Node.Index = undefined; - return renderContainerDecl(gpa, ais, tree, tree.containerDeclTwo(&buffer, node), space); + return renderContainerDecl(gpa, ais, tree, node, tree.containerDeclTwo(&buffer, node), space); }, .container_decl_arg, - .container_decl_arg_comma, - => return renderContainerDecl(gpa, ais, tree, tree.containerDeclArg(node), space), + .container_decl_arg_trailing, + => return renderContainerDecl(gpa, ais, tree, node, tree.containerDeclArg(node), space), .tagged_union, - .tagged_union_comma, - => return renderContainerDecl(gpa, ais, tree, tree.taggedUnion(node), space), + .tagged_union_trailing, + => return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnion(node), space), - .tagged_union_two, .tagged_union_two_comma => { + .tagged_union_two, .tagged_union_two_trailing => { var buffer: [2]ast.Node.Index = undefined; - return renderContainerDecl(gpa, ais, tree, tree.taggedUnionTwo(&buffer, node), space); + return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnionTwo(&buffer, node), space); }, .tagged_union_enum_tag, - .tagged_union_enum_tag_comma, - => return renderContainerDecl(gpa, ais, tree, tree.taggedUnionEnumTag(node), space), + .tagged_union_enum_tag_trailing, + => return renderContainerDecl(gpa, ais, tree, node, tree.taggedUnionEnumTag(node), space), .error_set_decl => { const error_token = main_tokens[node]; @@ -1662,7 +1666,6 @@ fn renderArrayInit( ais.pushIndentNextLine(); try renderToken(ais, tree, array_init.ast.lbrace, .newline); - var expr_index: usize = 0; while (rowSize(tree, array_init.ast.elements[expr_index..], rbrace)) |row_size| { const row_exprs = array_init.ast.elements[expr_index..]; @@ -1806,6 +1809,7 @@ fn renderContainerDecl( gpa: *Allocator, ais: *Ais, tree: ast.Tree, + container_decl_node: ast.Node.Index, container_decl: ast.full.ContainerDecl, space: Space, ) Error!void { @@ -1844,25 +1848,20 @@ fn renderContainerDecl( lbrace = container_decl.ast.main_token + 1; } + const rbrace = tree.lastToken(container_decl_node); if (container_decl.ast.members.len == 0) { - try renderToken(ais, tree, lbrace, Space.none); // lbrace - return renderToken(ais, tree, lbrace + 1, space); // rbrace + ais.pushIndentNextLine(); + if (token_tags[lbrace + 1] == .container_doc_comment) { + try renderToken(ais, tree, lbrace, .newline); // lbrace + try renderContainerDocComments(ais, tree, lbrace + 1); + } else { + try renderToken(ais, tree, lbrace, .none); // lbrace + } + ais.popIndent(); + return renderToken(ais, tree, rbrace, space); // rbrace } - const last_member = container_decl.ast.members[container_decl.ast.members.len - 1]; - const last_member_token = tree.lastToken(last_member); - const rbrace = switch (token_tags[last_member_token + 1]) { - .doc_comment => last_member_token + 2, - .comma, .semicolon => switch (token_tags[last_member_token + 2]) { - .doc_comment => last_member_token + 3, - .r_brace => last_member_token + 2, - else => unreachable, - }, - .r_brace => last_member_token + 1, - else => unreachable, - }; - const src_has_trailing_comma = token_tags[last_member_token + 1] == .comma; - + const src_has_trailing_comma = token_tags[rbrace - 1] == .comma; if (!src_has_trailing_comma) one_line: { // We can only print all the members in-line if all the members are fields. for (container_decl.ast.members) |member| { @@ -1879,6 +1878,9 @@ fn renderContainerDecl( // One member per line. ais.pushIndentNextLine(); try renderToken(ais, tree, lbrace, .newline); // lbrace + if (token_tags[lbrace + 1] == .container_doc_comment) { + try renderContainerDocComments(ais, tree, lbrace + 1); + } try renderMembers(gpa, ais, tree, container_decl.ast.members); ais.popIndent(); @@ -2272,6 +2274,15 @@ fn renderDocComments(ais: *Ais, tree: ast.Tree, end_token: ast.TokenIndex) Error } } +/// start_token is first container doc comment token. +fn renderContainerDocComments(ais: *Ais, tree: ast.Tree, start_token: ast.TokenIndex) Error!void { + const token_tags = tree.tokens.items(.tag); + var tok = start_token; + while (token_tags[tok] == .container_doc_comment) : (tok += 1) { + try renderToken(ais, tree, tok, .newline); + } +} + fn tokenSliceForRender(tree: ast.Tree, token_index: ast.TokenIndex) []const u8 { var ret = tree.tokenSlice(token_index); if (tree.tokens.items(.tag)[token_index] == .multiline_string_literal_line) { |
