authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-10 18:17:50+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-10 11:53:53-08:00
log928f6f48a62b4b356a0031ba54e247dbbcde4256
tree7e9878fd8f8e1f9c65afbce8013240e79e0b31e7
parent3110a73486223aba9152946fa0184536fc3c4b76

zig fmt: implement Tree.lastToken() for array init


4 files changed, 117 insertions(+), 48 deletions(-)

lib/std/zig/ast.zig+36-7
...@@ -255,6 +255,7 @@ pub const Tree = struct {...@@ -255,6 +255,7 @@ pub const Tree = struct {
255 => return main_tokens[n] - end_offset,255 => return main_tokens[n] - end_offset,
256256
257 .ArrayInitDot,257 .ArrayInitDot,
258 .ArrayInitDotComma,
258 .ArrayInitDotTwo,259 .ArrayInitDotTwo,
259 .ArrayInitDotTwoComma,260 .ArrayInitDotTwoComma,
260 .StructInitDot,261 .StructInitDot,
...@@ -311,7 +312,9 @@ pub const Tree = struct {...@@ -311,7 +312,9 @@ pub const Tree = struct {
311 .Deref,312 .Deref,
312 .ArrayAccess,313 .ArrayAccess,
313 .ArrayInitOne,314 .ArrayInitOne,
315 .ArrayInitOneComma,
314 .ArrayInit,316 .ArrayInit,
317 .ArrayInitComma,
315 .StructInitOne,318 .StructInitOne,
316 .StructInit,319 .StructInit,
317 .CallOne,320 .CallOne,
...@@ -604,6 +607,13 @@ pub const Tree = struct {...@@ -604,6 +607,13 @@ pub const Tree = struct {
604 const extra = tree.extraData(datas[n].rhs, Node.Asm);607 const extra = tree.extraData(datas[n].rhs, Node.Asm);
605 return extra.rparen + end_offset;608 return extra.rparen + end_offset;
606 },609 },
610 .ArrayInit => {
611 const elements = tree.extraData(datas[n].rhs, Node.SubRange);
612 assert(elements.end - elements.start > 0);
613 end_offset += 1; // for the rbrace
614 n = tree.extra_data[elements.end - 1]; // last element
615 },
616 .ArrayInitComma,
607 .ContainerDeclArgComma,617 .ContainerDeclArgComma,
608 .SwitchComma,618 .SwitchComma,
609 => {619 => {
...@@ -612,6 +622,7 @@ pub const Tree = struct {...@@ -612,6 +622,7 @@ pub const Tree = struct {
612 end_offset += 2; // for the comma + rbrace622 end_offset += 2; // for the comma + rbrace
613 n = tree.extra_data[members.end - 1]; // last parameter623 n = tree.extra_data[members.end - 1]; // last parameter
614 },624 },
625 .ArrayInitDot,
615 .Block,626 .Block,
616 .ContainerDecl,627 .ContainerDecl,
617 .TaggedUnion,628 .TaggedUnion,
...@@ -621,6 +632,7 @@ pub const Tree = struct {...@@ -621,6 +632,7 @@ pub const Tree = struct {
621 end_offset += 1; // for the rbrace632 end_offset += 1; // for the rbrace
622 n = tree.extra_data[datas[n].rhs - 1]; // last statement633 n = tree.extra_data[datas[n].rhs - 1]; // last statement
623 },634 },
635 .ArrayInitDotComma,
624 .BlockSemicolon,636 .BlockSemicolon,
625 .ContainerDeclComma,637 .ContainerDeclComma,
626 .TaggedUnionComma,638 .TaggedUnionComma,
...@@ -772,7 +784,16 @@ pub const Tree = struct {...@@ -772,7 +784,16 @@ pub const Tree = struct {
772 }784 }
773 },785 },
774786
775 .SliceOpen, .CallOneComma, .AsyncCallOneComma => {787 .ArrayInitOne => {
788 end_offset += 1; // rbrace
789 n = datas[n].rhs;
790 assert(n != 0);
791 },
792 .SliceOpen,
793 .CallOneComma,
794 .AsyncCallOneComma,
795 .ArrayInitOneComma,
796 => {
776 end_offset += 2; // ellipsis2 + rbracket, or comma + rparen797 end_offset += 2; // ellipsis2 + rbracket, or comma + rparen
777 n = datas[n].rhs;798 n = datas[n].rhs;
778 assert(n != 0);799 assert(n != 0);
...@@ -912,9 +933,6 @@ pub const Tree = struct {...@@ -912,9 +933,6 @@ pub const Tree = struct {
912 // require recursion due to the optional comma followed by rbrace.933 // require recursion due to the optional comma followed by rbrace.
913 // TODO follow the pattern set by StructInitDotTwoComma which will allow934 // TODO follow the pattern set by StructInitDotTwoComma which will allow
914 // lastToken to work for all of these.935 // lastToken to work for all of these.
915 .ArrayInit => unreachable, // TODO
916 .ArrayInitOne => unreachable, // TODO
917 .ArrayInitDot => unreachable, // TODO
918 .StructInit => unreachable, // TODO936 .StructInit => unreachable, // TODO
919 .StructInitOne => unreachable, // TODO937 .StructInitOne => unreachable, // TODO
920 .StructInitDot => unreachable, // TODO938 .StructInitDot => unreachable, // TODO
...@@ -1151,7 +1169,8 @@ pub const Tree = struct {...@@ -1151,7 +1169,8 @@ pub const Tree = struct {
1151 }1169 }
11521170
1153 pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit {1171 pub fn arrayInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.ArrayInit {
1154 assert(tree.nodes.items(.tag)[node] == .ArrayInitOne);1172 assert(tree.nodes.items(.tag)[node] == .ArrayInitOne or
1173 tree.nodes.items(.tag)[node] == .ArrayInitOneComma);
1155 const data = tree.nodes.items(.data)[node];1174 const data = tree.nodes.items(.data)[node];
1156 buffer[0] = data.rhs;1175 buffer[0] = data.rhs;
1157 const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1];1176 const elements = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
...@@ -1185,7 +1204,8 @@ pub const Tree = struct {...@@ -1185,7 +1204,8 @@ pub const Tree = struct {
1185 }1204 }
11861205
1187 pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {1206 pub fn arrayInitDot(tree: Tree, node: Node.Index) full.ArrayInit {
1188 assert(tree.nodes.items(.tag)[node] == .ArrayInitDot);1207 assert(tree.nodes.items(.tag)[node] == .ArrayInitDot or
1208 tree.nodes.items(.tag)[node] == .ArrayInitDotComma);
1189 const data = tree.nodes.items(.data)[node];1209 const data = tree.nodes.items(.data)[node];
1190 return .{1210 return .{
1191 .ast = .{1211 .ast = .{
...@@ -1197,7 +1217,8 @@ pub const Tree = struct {...@@ -1197,7 +1217,8 @@ pub const Tree = struct {
1197 }1217 }
11981218
1199 pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {1219 pub fn arrayInit(tree: Tree, node: Node.Index) full.ArrayInit {
1200 assert(tree.nodes.items(.tag)[node] == .ArrayInit);1220 assert(tree.nodes.items(.tag)[node] == .ArrayInit or
1221 tree.nodes.items(.tag)[node] == .ArrayInitComma);
1201 const data = tree.nodes.items(.data)[node];1222 const data = tree.nodes.items(.data)[node];
1202 const elem_range = tree.extraData(data.rhs, Node.SubRange);1223 const elem_range = tree.extraData(data.rhs, Node.SubRange);
1203 return .{1224 return .{
...@@ -2436,6 +2457,8 @@ pub const Node = struct {...@@ -2436,6 +2457,8 @@ pub const Node = struct {
2436 ArrayAccess,2457 ArrayAccess,
2437 /// `lhs{rhs}`. rhs can be omitted.2458 /// `lhs{rhs}`. rhs can be omitted.
2438 ArrayInitOne,2459 ArrayInitOne,
2460 /// `lhs{rhs,}`. rhs can *not* be omitted
2461 ArrayInitOneComma,
2439 /// `.{lhs, rhs}`. lhs and rhs can be omitted.2462 /// `.{lhs, rhs}`. lhs and rhs can be omitted.
2440 ArrayInitDotTwo,2463 ArrayInitDotTwo,
2441 /// Same as `ArrayInitDotTwo` except there is known to be a trailing comma2464 /// Same as `ArrayInitDotTwo` except there is known to be a trailing comma
...@@ -2443,8 +2466,14 @@ pub const Node = struct {...@@ -2443,8 +2466,14 @@ pub const Node = struct {
2443 ArrayInitDotTwoComma,2466 ArrayInitDotTwoComma,
2444 /// `.{a, b}`. `sub_list[lhs..rhs]`.2467 /// `.{a, b}`. `sub_list[lhs..rhs]`.
2445 ArrayInitDot,2468 ArrayInitDot,
2469 /// Same as `ArrayInitDot` except there is known to be a trailing comma
2470 /// before the final rbrace.
2471 ArrayInitDotComma,
2446 /// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`.2472 /// `lhs{a, b}`. `sub_range_list[rhs]`. lhs can be omitted which means `.{a, b}`.
2447 ArrayInit,2473 ArrayInit,
2474 /// Same as `ArrayInit` except there is known to be a trailing comma
2475 /// before the final rbrace.
2476 ArrayInitComma,
2448 /// `lhs{.a = rhs}`. rhs can be omitted making it empty.2477 /// `lhs{.a = rhs}`. rhs can be omitted making it empty.
2449 /// main_token is the lbrace.2478 /// main_token is the lbrace.
2450 StructInitOne,2479 StructInitOne,
lib/std/zig/parse.zig+17-7
...@@ -2205,9 +2205,10 @@ const Parser = struct {...@@ -2205,9 +2205,10 @@ const Parser = struct {
2205 }2205 }
22062206
2207 const elem_init = try p.expectExpr();2207 const elem_init = try p.expectExpr();
2208 const comma_one = p.eatToken(.Comma);
2208 if (p.eatToken(.RBrace)) |_| {2209 if (p.eatToken(.RBrace)) |_| {
2209 return p.addNode(.{2210 return p.addNode(.{
2210 .tag = .ArrayInitOne,2211 .tag = if (comma_one != null) .ArrayInitOneComma else .ArrayInitOne,
2211 .main_token = lbrace,2212 .main_token = lbrace,
2212 .data = .{2213 .data = .{
2213 .lhs = lhs,2214 .lhs = lhs,
...@@ -2215,21 +2216,30 @@ const Parser = struct {...@@ -2215,21 +2216,30 @@ const Parser = struct {
2215 },2216 },
2216 });2217 });
2217 }2218 }
2219 if (comma_one == null) {
2220 try p.warn(.{
2221 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .Comma },
2222 });
2223 }
22182224
2219 var init_list = std.ArrayList(Node.Index).init(p.gpa);2225 var init_list = std.ArrayList(Node.Index).init(p.gpa);
2220 defer init_list.deinit();2226 defer init_list.deinit();
22212227
2222 try init_list.append(elem_init);2228 try init_list.append(elem_init);
22232229
2224 while (p.eatToken(.Comma)) |_| {2230 var trailing_comma = true;
2225 const next = try p.parseExpr();2231 var next = try p.parseExpr();
2226 if (next == 0) break;2232 while (next != 0) : (next = try p.parseExpr()) {
2227 try init_list.append(next);2233 try init_list.append(next);
2234 if (p.eatToken(.Comma) == null) {
2235 trailing_comma = false;
2236 break;
2237 }
2228 }2238 }
2229 _ = try p.expectToken(.RBrace);2239 _ = try p.expectToken(.RBrace);
2230 const span = try p.listToSpan(init_list.items);2240 const span = try p.listToSpan(init_list.items);
2231 return p.addNode(.{2241 return p.addNode(.{
2232 .tag = .ArrayInit,2242 .tag = if (trailing_comma) .ArrayInitComma else .ArrayInit,
2233 .main_token = lbrace,2243 .main_token = lbrace,
2234 .data = .{2244 .data = .{
2235 .lhs = lhs,2245 .lhs = lhs,
...@@ -2805,7 +2815,7 @@ const Parser = struct {...@@ -2805,7 +2815,7 @@ const Parser = struct {
2805 const comma_two = p.eatToken(.Comma);2815 const comma_two = p.eatToken(.Comma);
2806 if (p.eatToken(.RBrace)) |_| {2816 if (p.eatToken(.RBrace)) |_| {
2807 return p.addNode(.{2817 return p.addNode(.{
2808 .tag = if (comma_one != null) .ArrayInitDotTwoComma else .ArrayInitDotTwo,2818 .tag = if (comma_two != null) .ArrayInitDotTwoComma else .ArrayInitDotTwo,
2809 .main_token = lbrace,2819 .main_token = lbrace,
2810 .data = .{2820 .data = .{
2811 .lhs = elem_init_one,2821 .lhs = elem_init_one,
...@@ -2855,7 +2865,7 @@ const Parser = struct {...@@ -2855,7 +2865,7 @@ const Parser = struct {
2855 }2865 }
2856 const span = try p.listToSpan(init_list.items);2866 const span = try p.listToSpan(init_list.items);
2857 return p.addNode(.{2867 return p.addNode(.{
2858 .tag = .ArrayInitDot,2868 .tag = if (p.token_tags[p.tok_i - 2] == .Comma) .ArrayInitDotComma else .ArrayInitDot,
2859 .main_token = lbrace,2869 .main_token = lbrace,
2860 .data = .{2870 .data = .{
2861 .lhs = span.start,2871 .lhs = span.start,
lib/std/zig/parser_test.zig+57-31
...@@ -568,109 +568,135 @@ test "zig fmt: struct literal 3 element comma" {...@@ -568,109 +568,135 @@ test "zig fmt: struct literal 3 element comma" {
568568
569test "zig fmt: anon list literal 1 element" {569test "zig fmt: anon list literal 1 element" {
570 try testCanonical(570 try testCanonical(
571 \\const x = .{a};571 \\test {
572 \\ const x = .{a};
573 \\}
572 \\574 \\
573 );575 );
574}576}
575577
576test "zig fmt: anon list literal 1 element comma" {578test "zig fmt: anon list literal 1 element comma" {
577 try testCanonical(579 try testCanonical(
578 \\const x = .{580 \\test {
579 \\ a,581 \\ const x = .{
580 \\};582 \\ a,
583 \\ };
584 \\}
581 \\585 \\
582 );586 );
583}587}
584588
585test "zig fmt: anon list literal 2 element" {589test "zig fmt: anon list literal 2 element" {
586 try testCanonical(590 try testCanonical(
587 \\const x = .{ a, b };591 \\test {
592 \\ const x = .{ a, b };
593 \\}
588 \\594 \\
589 );595 );
590}596}
591597
592test "zig fmt: anon list literal 2 element comma" {598test "zig fmt: anon list literal 2 element comma" {
593 try testCanonical(599 try testCanonical(
594 \\const x = .{600 \\test {
595 \\ a,601 \\ const x = .{
596 \\ b,602 \\ a,
597 \\};603 \\ b,
604 \\ };
605 \\}
598 \\606 \\
599 );607 );
600}608}
601609
602test "zig fmt: anon list literal 3 element" {610test "zig fmt: anon list literal 3 element" {
603 try testCanonical(611 try testCanonical(
604 \\const x = .{ a, b, c };612 \\test {
613 \\ const x = .{ a, b, c };
614 \\}
605 \\615 \\
606 );616 );
607}617}
608618
609test "zig fmt: anon list literal 3 element comma" {619test "zig fmt: anon list literal 3 element comma" {
610 try testCanonical(620 try testCanonical(
611 \\const x = .{621 \\test {
612 \\ a,622 \\ const x = .{
613 \\ b,623 \\ a,
614 \\ c,624 \\ b,
615 \\};625 \\ c,
626 \\ };
627 \\}
616 \\628 \\
617 );629 );
618}630}
619631
620test "zig fmt: array literal 1 element" {632test "zig fmt: array literal 1 element" {
621 try testCanonical(633 try testCanonical(
622 \\const x = [_]u32{a};634 \\test {
635 \\ const x = [_]u32{a};
636 \\}
623 \\637 \\
624 );638 );
625}639}
626640
627test "zig fmt: array literal 1 element comma" {641test "zig fmt: array literal 1 element comma" {
628 try testCanonical(642 try testCanonical(
629 \\const x = [1]u32{643 \\test {
630 \\ a,644 \\ const x = [1]u32{
631 \\};645 \\ a,
646 \\ };
647 \\}
632 \\648 \\
633 );649 );
634}650}
635651
636test "zig fmt: array literal 2 element" {652test "zig fmt: array literal 2 element" {
637 try testCanonical(653 try testCanonical(
638 \\const x = [_]u32{ a, b };654 \\test {
655 \\ const x = [_]u32{ a, b };
656 \\}
639 \\657 \\
640 );658 );
641}659}
642660
643test "zig fmt: array literal 2 element comma" {661test "zig fmt: array literal 2 element comma" {
644 try testCanonical(662 try testCanonical(
645 \\const x = [2]u32{663 \\test {
646 \\ a,664 \\ const x = [2]u32{
647 \\ b,665 \\ a,
648 \\};666 \\ b,
667 \\ };
668 \\}
649 \\669 \\
650 );670 );
651}671}
652672
653test "zig fmt: array literal 3 element" {673test "zig fmt: array literal 3 element" {
654 try testCanonical(674 try testCanonical(
655 \\const x = [_]u32{ a, b, c };675 \\test {
676 \\ const x = [_]u32{ a, b, c };
677 \\}
656 \\678 \\
657 );679 );
658}680}
659681
660test "zig fmt: array literal 3 element comma" {682test "zig fmt: array literal 3 element comma" {
661 try testCanonical(683 try testCanonical(
662 \\const x = [3]u32{684 \\test {
663 \\ a,685 \\ const x = [3]u32{
664 \\ b,686 \\ a,
665 \\ c,687 \\ b,
666 \\};688 \\ c,
689 \\ };
690 \\}
667 \\691 \\
668 );692 );
669}693}
670694
671test "zig fmt: sentinel array literal 1 element" {695test "zig fmt: sentinel array literal 1 element" {
672 try testCanonical(696 try testCanonical(
673 \\const x = [_:9000]u32{a};697 \\test {
698 \\ const x = [_:9000]u32{a};
699 \\}
674 \\700 \\
675 );701 );
676}702}
lib/std/zig/render.zig+7-3
...@@ -390,7 +390,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -390,7 +390,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
390 .PtrType => return renderPtrType(ais, tree, tree.ptrType(node), space),390 .PtrType => return renderPtrType(ais, tree, tree.ptrType(node), space),
391 .PtrTypeBitRange => return renderPtrType(ais, tree, tree.ptrTypeBitRange(node), space),391 .PtrTypeBitRange => return renderPtrType(ais, tree, tree.ptrTypeBitRange(node), space),
392392
393 .ArrayInitOne => {393 .ArrayInitOne, .ArrayInitOneComma => {
394 var elements: [1]ast.Node.Index = undefined;394 var elements: [1]ast.Node.Index = undefined;
395 return renderArrayInit(ais, tree, tree.arrayInitOne(&elements, node), space);395 return renderArrayInit(ais, tree, tree.arrayInitOne(&elements, node), space);
396 },396 },
...@@ -398,8 +398,12 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -398,8 +398,12 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
398 var elements: [2]ast.Node.Index = undefined;398 var elements: [2]ast.Node.Index = undefined;
399 return renderArrayInit(ais, tree, tree.arrayInitDotTwo(&elements, node), space);399 return renderArrayInit(ais, tree, tree.arrayInitDotTwo(&elements, node), space);
400 },400 },
401 .ArrayInitDot => return renderArrayInit(ais, tree, tree.arrayInitDot(node), space),401 .ArrayInitDot,
402 .ArrayInit => return renderArrayInit(ais, tree, tree.arrayInit(node), space),402 .ArrayInitDotComma,
403 => return renderArrayInit(ais, tree, tree.arrayInitDot(node), space),
404 .ArrayInit,
405 .ArrayInitComma,
406 => return renderArrayInit(ais, tree, tree.arrayInit(node), space),
403407
404 .StructInitOne => {408 .StructInitOne => {
405 var fields: [1]ast.Node.Index = undefined;409 var fields: [1]ast.Node.Index = undefined;