authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-10 19:16:25+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-10 11:53:53-08:00
log5df7fc36c6e5d7caf7b5b5437bf40fec77a2b971
treea8a4539ba9abe8681729ccab0f9b4c30b5819ac1
parent928f6f48a62b4b356a0031ba54e247dbbcde4256

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


4 files changed, 98 insertions(+), 61 deletions(-)

lib/std/zig/ast.zig+31-15
......@@ -259,6 +259,7 @@ pub const Tree = struct {
259259 .ArrayInitDotTwo,
260260 .ArrayInitDotTwoComma,
261261 .StructInitDot,
262 .StructInitDotComma,
262263 .StructInitDotTwo,
263264 .StructInitDotTwoComma,
264265 .EnumLiteral,
......@@ -316,7 +317,9 @@ pub const Tree = struct {
316317 .ArrayInit,
317318 .ArrayInitComma,
318319 .StructInitOne,
320 .StructInitOneComma,
319321 .StructInit,
322 .StructInitComma,
320323 .CallOne,
321324 .CallOneComma,
322325 .Call,
......@@ -607,13 +610,16 @@ pub const Tree = struct {
607610 const extra = tree.extraData(datas[n].rhs, Node.Asm);
608611 return extra.rparen + end_offset;
609612 },
610 .ArrayInit => {
613 .ArrayInit,
614 .StructInit,
615 => {
611616 const elements = tree.extraData(datas[n].rhs, Node.SubRange);
612617 assert(elements.end - elements.start > 0);
613618 end_offset += 1; // for the rbrace
614619 n = tree.extra_data[elements.end - 1]; // last element
615620 },
616621 .ArrayInitComma,
622 .StructInitComma,
617623 .ContainerDeclArgComma,
618624 .SwitchComma,
619625 => {
......@@ -623,6 +629,7 @@ pub const Tree = struct {
623629 n = tree.extra_data[members.end - 1]; // last parameter
624630 },
625631 .ArrayInitDot,
632 .StructInitDot,
626633 .Block,
627634 .ContainerDecl,
628635 .TaggedUnion,
......@@ -633,6 +640,7 @@ pub const Tree = struct {
633640 n = tree.extra_data[datas[n].rhs - 1]; // last statement
634641 },
635642 .ArrayInitDotComma,
643 .StructInitDotComma,
636644 .BlockSemicolon,
637645 .ContainerDeclComma,
638646 .TaggedUnionComma,
......@@ -784,7 +792,9 @@ pub const Tree = struct {
784792 }
785793 },
786794
787 .ArrayInitOne => {
795 .ArrayInitOne,
796 .StructInitOne,
797 => {
788798 end_offset += 1; // rbrace
789799 n = datas[n].rhs;
790800 assert(n != 0);
......@@ -793,6 +803,7 @@ pub const Tree = struct {
793803 .CallOneComma,
794804 .AsyncCallOneComma,
795805 .ArrayInitOneComma,
806 .StructInitOneComma,
796807 => {
797808 end_offset += 2; // ellipsis2 + rbracket, or comma + rparen
798809 n = datas[n].rhs;
......@@ -929,14 +940,6 @@ pub const Tree = struct {
929940 n = extra.elem_type;
930941 },
931942
932 // These are not supported by lastToken() because implementation would
933 // require recursion due to the optional comma followed by rbrace.
934 // TODO follow the pattern set by StructInitDotTwoComma which will allow
935 // lastToken to work for all of these.
936 .StructInit => unreachable, // TODO
937 .StructInitOne => unreachable, // TODO
938 .StructInitDot => unreachable, // TODO
939
940943 .TaggedUnionEnumTag => unreachable, // TODO
941944 .TaggedUnionEnumTagComma => unreachable, // TODO
942945 .SwitchRange => unreachable, // TODO
......@@ -1118,7 +1121,8 @@ pub const Tree = struct {
11181121 }
11191122
11201123 pub fn structInitOne(tree: Tree, buffer: *[1]Node.Index, node: Node.Index) full.StructInit {
1121 assert(tree.nodes.items(.tag)[node] == .StructInitOne);
1124 assert(tree.nodes.items(.tag)[node] == .StructInitOne or
1125 tree.nodes.items(.tag)[node] == .StructInitOneComma);
11221126 const data = tree.nodes.items(.data)[node];
11231127 buffer[0] = data.rhs;
11241128 const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1];
......@@ -1148,7 +1152,8 @@ pub const Tree = struct {
11481152 }
11491153
11501154 pub fn structInitDot(tree: Tree, node: Node.Index) full.StructInit {
1151 assert(tree.nodes.items(.tag)[node] == .StructInitDot);
1155 assert(tree.nodes.items(.tag)[node] == .StructInitDot or
1156 tree.nodes.items(.tag)[node] == .StructInitDotComma);
11521157 const data = tree.nodes.items(.data)[node];
11531158 return tree.fullStructInit(.{
11541159 .lbrace = tree.nodes.items(.main_token)[node],
......@@ -1158,7 +1163,8 @@ pub const Tree = struct {
11581163 }
11591164
11601165 pub fn structInit(tree: Tree, node: Node.Index) full.StructInit {
1161 assert(tree.nodes.items(.tag)[node] == .StructInit);
1166 assert(tree.nodes.items(.tag)[node] == .StructInit or
1167 tree.nodes.items(.tag)[node] == .StructInitComma);
11621168 const data = tree.nodes.items(.data)[node];
11631169 const fields_range = tree.extraData(data.rhs, Node.SubRange);
11641170 return tree.fullStructInit(.{
......@@ -2281,6 +2287,8 @@ pub const Node = struct {
22812287 assert(@sizeOf(Tag) == 1);
22822288 }
22832289
2290 /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of
2291 /// Tree.lastToken()
22842292 pub const Tag = enum {
22852293 /// sub_list[lhs...rhs]
22862294 Root,
......@@ -2477,21 +2485,29 @@ pub const Node = struct {
24772485 /// `lhs{.a = rhs}`. rhs can be omitted making it empty.
24782486 /// main_token is the lbrace.
24792487 StructInitOne,
2488 /// `lhs{.a = rhs,}`. rhs can *not* be omitted.
2489 /// main_token is the lbrace.
2490 StructInitOneComma,
24802491 /// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted.
24812492 /// main_token is the lbrace.
24822493 /// No trailing comma before the rbrace.
24832494 StructInitDotTwo,
24842495 /// Same as `StructInitDotTwo` except there is known to be a trailing comma
2485 /// before the final rbrace. This tag exists to facilitate lastToken() implemented
2486 /// without recursion.
2496 /// before the final rbrace.
24872497 StructInitDotTwoComma,
24882498 /// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`.
24892499 /// main_token is the lbrace.
24902500 StructInitDot,
2501 /// Same as `StructInitDot` except there is known to be a trailing comma
2502 /// before the final rbrace.
2503 StructInitDotComma,
24912504 /// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`.
24922505 /// lhs can be omitted which means `.{.a = b, .c = d}`.
24932506 /// main_token is the lbrace.
24942507 StructInit,
2508 /// Same as `StructInit` except there is known to be a trailing comma
2509 /// before the final rbrace.
2510 StructInitComma,
24952511 /// `lhs(rhs)`. rhs can be omitted.
24962512 CallOne,
24972513 /// `lhs(rhs,)`. rhs can be omitted.
lib/std/zig/parse.zig+6-13
......@@ -2147,7 +2147,7 @@ const Parser = struct {
21472147 const comma_one = p.eatToken(.Comma);
21482148 if (p.eatToken(.RBrace)) |_| {
21492149 return p.addNode(.{
2150 .tag = .StructInitOne,
2150 .tag = if (comma_one != null) .StructInitOneComma else .StructInitOne,
21512151 .main_token = lbrace,
21522152 .data = .{
21532153 .lhs = lhs,
......@@ -2192,7 +2192,7 @@ const Parser = struct {
21922192 }
21932193 const span = try p.listToSpan(init_list.items);
21942194 return p.addNode(.{
2195 .tag = .StructInit,
2195 .tag = if (p.token_tags[p.tok_i - 2] == .Comma) .StructInitComma else .StructInit,
21962196 .main_token = lbrace,
21972197 .data = .{
21982198 .lhs = lhs,
......@@ -2709,12 +2709,8 @@ const Parser = struct {
27092709 if (field_init_one != 0) {
27102710 const comma_one = p.eatToken(.Comma);
27112711 if (p.eatToken(.RBrace)) |_| {
2712 const tag: Node.Tag = if (comma_one != null)
2713 .StructInitDotTwoComma
2714 else
2715 .StructInitDotTwo;
27162712 return p.addNode(.{
2717 .tag = tag,
2713 .tag = if (comma_one != null) .StructInitDotTwoComma else .StructInitDotTwo,
27182714 .main_token = lbrace,
27192715 .data = .{
27202716 .lhs = field_init_one,
......@@ -2730,12 +2726,8 @@ const Parser = struct {
27302726 const field_init_two = try p.expectFieldInit();
27312727 const comma_two = p.eatToken(.Comma);
27322728 if (p.eatToken(.RBrace)) |_| {
2733 const tag: Node.Tag = if (comma_two != null)
2734 .StructInitDotTwoComma
2735 else
2736 .StructInitDotTwo;
27372729 return p.addNode(.{
2738 .tag = tag,
2730 .tag = if (comma_two != null) .StructInitDotTwoComma else .StructInitDotTwo,
27392731 .main_token = lbrace,
27402732 .data = .{
27412733 .lhs = field_init_one,
......@@ -2784,8 +2776,9 @@ const Parser = struct {
27842776 }
27852777 }
27862778 const span = try p.listToSpan(init_list.items);
2779 const trailing_comma = p.token_tags[p.tok_i - 2] == .Comma;
27872780 return p.addNode(.{
2788 .tag = .StructInitDot,
2781 .tag = if (trailing_comma) .StructInitDotComma else .StructInitDot,
27892782 .main_token = lbrace,
27902783 .data = .{
27912784 .lhs = span.start,
lib/std/zig/parser_test.zig+54-30
......@@ -466,102 +466,126 @@ test "zig fmt: anon literal in array" {
466466
467467test "zig fmt: anon struct literal 1 element" {
468468 try testCanonical(
469 \\const x = .{ .a = b };
469 \\test {
470 \\ const x = .{ .a = b };
471 \\}
470472 \\
471473 );
472474}
473475
474476test "zig fmt: anon struct literal 1 element comma" {
475477 try testCanonical(
476 \\const x = .{
477 \\ .a = b,
478 \\};
478 \\test {
479 \\ const x = .{
480 \\ .a = b,
481 \\ };
482 \\}
479483 \\
480484 );
481485}
482486
483487test "zig fmt: anon struct literal 2 element" {
484488 try testCanonical(
485 \\const x = .{ .a = b, .c = d };
489 \\test {
490 \\ const x = .{ .a = b, .c = d };
491 \\}
486492 \\
487493 );
488494}
489495
490496test "zig fmt: anon struct literal 2 element comma" {
491497 try testCanonical(
492 \\const x = .{
493 \\ .a = b,
494 \\ .c = d,
495 \\};
498 \\test {
499 \\ const x = .{
500 \\ .a = b,
501 \\ .c = d,
502 \\ };
503 \\}
496504 \\
497505 );
498506}
499507
500508test "zig fmt: anon struct literal 3 element" {
501509 try testCanonical(
502 \\const x = .{ .a = b, .c = d, .e = f };
510 \\test {
511 \\ const x = .{ .a = b, .c = d, .e = f };
512 \\}
503513 \\
504514 );
505515}
506516
507517test "zig fmt: anon struct literal 3 element comma" {
508518 try testCanonical(
509 \\const x = .{
510 \\ .a = b,
511 \\ .c = d,
512 \\ .e = f,
513 \\};
519 \\test {
520 \\ const x = .{
521 \\ .a = b,
522 \\ .c = d,
523 \\ .e = f,
524 \\ };
525 \\}
514526 \\
515527 );
516528}
517529
518530test "zig fmt: struct literal 1 element" {
519531 try testCanonical(
520 \\const x = X{ .a = b };
532 \\test {
533 \\ const x = X{ .a = b };
534 \\}
521535 \\
522536 );
523537}
524538
525539test "zig fmt: struct literal 1 element comma" {
526540 try testCanonical(
527 \\const x = X{
528 \\ .a = b,
529 \\};
541 \\test {
542 \\ const x = X{
543 \\ .a = b,
544 \\ };
545 \\}
530546 \\
531547 );
532548}
533549
534550test "zig fmt: struct literal 2 element" {
535551 try testCanonical(
536 \\const x = X{ .a = b, .c = d };
552 \\test {
553 \\ const x = X{ .a = b, .c = d };
554 \\}
537555 \\
538556 );
539557}
540558
541559test "zig fmt: struct literal 2 element comma" {
542560 try testCanonical(
543 \\const x = X{
544 \\ .a = b,
545 \\ .c = d,
546 \\};
561 \\test {
562 \\ const x = X{
563 \\ .a = b,
564 \\ .c = d,
565 \\ };
566 \\}
547567 \\
548568 );
549569}
550570
551571test "zig fmt: struct literal 3 element" {
552572 try testCanonical(
553 \\const x = X{ .a = b, .c = d, .e = f };
573 \\test {
574 \\ const x = X{ .a = b, .c = d, .e = f };
575 \\}
554576 \\
555577 );
556578}
557579
558580test "zig fmt: struct literal 3 element comma" {
559581 try testCanonical(
560 \\const x = X{
561 \\ .a = b,
562 \\ .c = d,
563 \\ .e = f,
564 \\};
582 \\test {
583 \\ const x = X{
584 \\ .a = b,
585 \\ .c = d,
586 \\ .e = f,
587 \\ };
588 \\}
565589 \\
566590 );
567591}
lib/std/zig/render.zig+7-3
......@@ -405,7 +405,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
405405 .ArrayInitComma,
406406 => return renderArrayInit(ais, tree, tree.arrayInit(node), space),
407407
408 .StructInitOne => {
408 .StructInitOne, .StructInitOneComma => {
409409 var fields: [1]ast.Node.Index = undefined;
410410 return renderStructInit(ais, tree, tree.structInitOne(&fields, node), space);
411411 },
......@@ -413,8 +413,12 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
413413 var fields: [2]ast.Node.Index = undefined;
414414 return renderStructInit(ais, tree, tree.structInitDotTwo(&fields, node), space);
415415 },
416 .StructInitDot => return renderStructInit(ais, tree, tree.structInitDot(node), space),
417 .StructInit => return renderStructInit(ais, tree, tree.structInit(node), space),
416 .StructInitDot,
417 .StructInitDotComma,
418 => return renderStructInit(ais, tree, tree.structInitDot(node), space),
419 .StructInit,
420 .StructInitComma,
421 => return renderStructInit(ais, tree, tree.structInit(node), space),
418422
419423 .CallOne, .CallOneComma, .AsyncCallOne, .AsyncCallOneComma => {
420424 var params: [1]ast.Node.Index = undefined;