| author | |
| committer | |
| log | 5df7fc36c6e5d7caf7b5b5437bf40fec77a2b971 |
| tree | a8a4539ba9abe8681729ccab0f9b4c30b5819ac1 |
| parent | 928f6f48a62b4b356a0031ba54e247dbbcde4256 |
4 files changed, 98 insertions(+), 61 deletions(-)
lib/std/zig/ast.zig+31-15| ... | ... | @@ -259,6 +259,7 @@ pub const Tree = struct { |
| 259 | 259 | .ArrayInitDotTwo, |
| 260 | 260 | .ArrayInitDotTwoComma, |
| 261 | 261 | .StructInitDot, |
| 262 | .StructInitDotComma, | |
| 262 | 263 | .StructInitDotTwo, |
| 263 | 264 | .StructInitDotTwoComma, |
| 264 | 265 | .EnumLiteral, |
| ... | ... | @@ -316,7 +317,9 @@ pub const Tree = struct { |
| 316 | 317 | .ArrayInit, |
| 317 | 318 | .ArrayInitComma, |
| 318 | 319 | .StructInitOne, |
| 320 | .StructInitOneComma, | |
| 319 | 321 | .StructInit, |
| 322 | .StructInitComma, | |
| 320 | 323 | .CallOne, |
| 321 | 324 | .CallOneComma, |
| 322 | 325 | .Call, |
| ... | ... | @@ -607,13 +610,16 @@ pub const Tree = struct { |
| 607 | 610 | const extra = tree.extraData(datas[n].rhs, Node.Asm); |
| 608 | 611 | return extra.rparen + end_offset; |
| 609 | 612 | }, |
| 610 | .ArrayInit => { | |
| 613 | .ArrayInit, | |
| 614 | .StructInit, | |
| 615 | => { | |
| 611 | 616 | const elements = tree.extraData(datas[n].rhs, Node.SubRange); |
| 612 | 617 | assert(elements.end - elements.start > 0); |
| 613 | 618 | end_offset += 1; // for the rbrace |
| 614 | 619 | n = tree.extra_data[elements.end - 1]; // last element |
| 615 | 620 | }, |
| 616 | 621 | .ArrayInitComma, |
| 622 | .StructInitComma, | |
| 617 | 623 | .ContainerDeclArgComma, |
| 618 | 624 | .SwitchComma, |
| 619 | 625 | => { |
| ... | ... | @@ -623,6 +629,7 @@ pub const Tree = struct { |
| 623 | 629 | n = tree.extra_data[members.end - 1]; // last parameter |
| 624 | 630 | }, |
| 625 | 631 | .ArrayInitDot, |
| 632 | .StructInitDot, | |
| 626 | 633 | .Block, |
| 627 | 634 | .ContainerDecl, |
| 628 | 635 | .TaggedUnion, |
| ... | ... | @@ -633,6 +640,7 @@ pub const Tree = struct { |
| 633 | 640 | n = tree.extra_data[datas[n].rhs - 1]; // last statement |
| 634 | 641 | }, |
| 635 | 642 | .ArrayInitDotComma, |
| 643 | .StructInitDotComma, | |
| 636 | 644 | .BlockSemicolon, |
| 637 | 645 | .ContainerDeclComma, |
| 638 | 646 | .TaggedUnionComma, |
| ... | ... | @@ -784,7 +792,9 @@ pub const Tree = struct { |
| 784 | 792 | } |
| 785 | 793 | }, |
| 786 | 794 | |
| 787 | .ArrayInitOne => { | |
| 795 | .ArrayInitOne, | |
| 796 | .StructInitOne, | |
| 797 | => { | |
| 788 | 798 | end_offset += 1; // rbrace |
| 789 | 799 | n = datas[n].rhs; |
| 790 | 800 | assert(n != 0); |
| ... | ... | @@ -793,6 +803,7 @@ pub const Tree = struct { |
| 793 | 803 | .CallOneComma, |
| 794 | 804 | .AsyncCallOneComma, |
| 795 | 805 | .ArrayInitOneComma, |
| 806 | .StructInitOneComma, | |
| 796 | 807 | => { |
| 797 | 808 | end_offset += 2; // ellipsis2 + rbracket, or comma + rparen |
| 798 | 809 | n = datas[n].rhs; |
| ... | ... | @@ -929,14 +940,6 @@ pub const Tree = struct { |
| 929 | 940 | n = extra.elem_type; |
| 930 | 941 | }, |
| 931 | 942 | |
| 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 | ||
| 940 | 943 | .TaggedUnionEnumTag => unreachable, // TODO |
| 941 | 944 | .TaggedUnionEnumTagComma => unreachable, // TODO |
| 942 | 945 | .SwitchRange => unreachable, // TODO |
| ... | ... | @@ -1118,7 +1121,8 @@ pub const Tree = struct { |
| 1118 | 1121 | } |
| 1119 | 1122 | |
| 1120 | 1123 | 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); | |
| 1122 | 1126 | const data = tree.nodes.items(.data)[node]; |
| 1123 | 1127 | buffer[0] = data.rhs; |
| 1124 | 1128 | const fields = if (data.rhs == 0) buffer[0..0] else buffer[0..1]; |
| ... | ... | @@ -1148,7 +1152,8 @@ pub const Tree = struct { |
| 1148 | 1152 | } |
| 1149 | 1153 | |
| 1150 | 1154 | 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); | |
| 1152 | 1157 | const data = tree.nodes.items(.data)[node]; |
| 1153 | 1158 | return tree.fullStructInit(.{ |
| 1154 | 1159 | .lbrace = tree.nodes.items(.main_token)[node], |
| ... | ... | @@ -1158,7 +1163,8 @@ pub const Tree = struct { |
| 1158 | 1163 | } |
| 1159 | 1164 | |
| 1160 | 1165 | 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); | |
| 1162 | 1168 | const data = tree.nodes.items(.data)[node]; |
| 1163 | 1169 | const fields_range = tree.extraData(data.rhs, Node.SubRange); |
| 1164 | 1170 | return tree.fullStructInit(.{ |
| ... | ... | @@ -2281,6 +2287,8 @@ pub const Node = struct { |
| 2281 | 2287 | assert(@sizeOf(Tag) == 1); |
| 2282 | 2288 | } |
| 2283 | 2289 | |
| 2290 | /// Note: The FooComma/FooSemicolon variants exist to ease the implementation of | |
| 2291 | /// Tree.lastToken() | |
| 2284 | 2292 | pub const Tag = enum { |
| 2285 | 2293 | /// sub_list[lhs...rhs] |
| 2286 | 2294 | Root, |
| ... | ... | @@ -2477,21 +2485,29 @@ pub const Node = struct { |
| 2477 | 2485 | /// `lhs{.a = rhs}`. rhs can be omitted making it empty. |
| 2478 | 2486 | /// main_token is the lbrace. |
| 2479 | 2487 | StructInitOne, |
| 2488 | /// `lhs{.a = rhs,}`. rhs can *not* be omitted. | |
| 2489 | /// main_token is the lbrace. | |
| 2490 | StructInitOneComma, | |
| 2480 | 2491 | /// `.{.a = lhs, .b = rhs}`. lhs and rhs can be omitted. |
| 2481 | 2492 | /// main_token is the lbrace. |
| 2482 | 2493 | /// No trailing comma before the rbrace. |
| 2483 | 2494 | StructInitDotTwo, |
| 2484 | 2495 | /// 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. | |
| 2487 | 2497 | StructInitDotTwoComma, |
| 2488 | 2498 | /// `.{.a = b, .c = d}`. `sub_list[lhs..rhs]`. |
| 2489 | 2499 | /// main_token is the lbrace. |
| 2490 | 2500 | StructInitDot, |
| 2501 | /// Same as `StructInitDot` except there is known to be a trailing comma | |
| 2502 | /// before the final rbrace. | |
| 2503 | StructInitDotComma, | |
| 2491 | 2504 | /// `lhs{.a = b, .c = d}`. `sub_range_list[rhs]`. |
| 2492 | 2505 | /// lhs can be omitted which means `.{.a = b, .c = d}`. |
| 2493 | 2506 | /// main_token is the lbrace. |
| 2494 | 2507 | StructInit, |
| 2508 | /// Same as `StructInit` except there is known to be a trailing comma | |
| 2509 | /// before the final rbrace. | |
| 2510 | StructInitComma, | |
| 2495 | 2511 | /// `lhs(rhs)`. rhs can be omitted. |
| 2496 | 2512 | CallOne, |
| 2497 | 2513 | /// `lhs(rhs,)`. rhs can be omitted. |
lib/std/zig/parse.zig+6-13| ... | ... | @@ -2147,7 +2147,7 @@ const Parser = struct { |
| 2147 | 2147 | const comma_one = p.eatToken(.Comma); |
| 2148 | 2148 | if (p.eatToken(.RBrace)) |_| { |
| 2149 | 2149 | return p.addNode(.{ |
| 2150 | .tag = .StructInitOne, | |
| 2150 | .tag = if (comma_one != null) .StructInitOneComma else .StructInitOne, | |
| 2151 | 2151 | .main_token = lbrace, |
| 2152 | 2152 | .data = .{ |
| 2153 | 2153 | .lhs = lhs, |
| ... | ... | @@ -2192,7 +2192,7 @@ const Parser = struct { |
| 2192 | 2192 | } |
| 2193 | 2193 | const span = try p.listToSpan(init_list.items); |
| 2194 | 2194 | return p.addNode(.{ |
| 2195 | .tag = .StructInit, | |
| 2195 | .tag = if (p.token_tags[p.tok_i - 2] == .Comma) .StructInitComma else .StructInit, | |
| 2196 | 2196 | .main_token = lbrace, |
| 2197 | 2197 | .data = .{ |
| 2198 | 2198 | .lhs = lhs, |
| ... | ... | @@ -2709,12 +2709,8 @@ const Parser = struct { |
| 2709 | 2709 | if (field_init_one != 0) { |
| 2710 | 2710 | const comma_one = p.eatToken(.Comma); |
| 2711 | 2711 | if (p.eatToken(.RBrace)) |_| { |
| 2712 | const tag: Node.Tag = if (comma_one != null) | |
| 2713 | .StructInitDotTwoComma | |
| 2714 | else | |
| 2715 | .StructInitDotTwo; | |
| 2716 | 2712 | return p.addNode(.{ |
| 2717 | .tag = tag, | |
| 2713 | .tag = if (comma_one != null) .StructInitDotTwoComma else .StructInitDotTwo, | |
| 2718 | 2714 | .main_token = lbrace, |
| 2719 | 2715 | .data = .{ |
| 2720 | 2716 | .lhs = field_init_one, |
| ... | ... | @@ -2730,12 +2726,8 @@ const Parser = struct { |
| 2730 | 2726 | const field_init_two = try p.expectFieldInit(); |
| 2731 | 2727 | const comma_two = p.eatToken(.Comma); |
| 2732 | 2728 | if (p.eatToken(.RBrace)) |_| { |
| 2733 | const tag: Node.Tag = if (comma_two != null) | |
| 2734 | .StructInitDotTwoComma | |
| 2735 | else | |
| 2736 | .StructInitDotTwo; | |
| 2737 | 2729 | return p.addNode(.{ |
| 2738 | .tag = tag, | |
| 2730 | .tag = if (comma_two != null) .StructInitDotTwoComma else .StructInitDotTwo, | |
| 2739 | 2731 | .main_token = lbrace, |
| 2740 | 2732 | .data = .{ |
| 2741 | 2733 | .lhs = field_init_one, |
| ... | ... | @@ -2784,8 +2776,9 @@ const Parser = struct { |
| 2784 | 2776 | } |
| 2785 | 2777 | } |
| 2786 | 2778 | const span = try p.listToSpan(init_list.items); |
| 2779 | const trailing_comma = p.token_tags[p.tok_i - 2] == .Comma; | |
| 2787 | 2780 | return p.addNode(.{ |
| 2788 | .tag = .StructInitDot, | |
| 2781 | .tag = if (trailing_comma) .StructInitDotComma else .StructInitDot, | |
| 2789 | 2782 | .main_token = lbrace, |
| 2790 | 2783 | .data = .{ |
| 2791 | 2784 | .lhs = span.start, |
lib/std/zig/parser_test.zig+54-30| ... | ... | @@ -466,102 +466,126 @@ test "zig fmt: anon literal in array" { |
| 466 | 466 | |
| 467 | 467 | test "zig fmt: anon struct literal 1 element" { |
| 468 | 468 | try testCanonical( |
| 469 | \\const x = .{ .a = b }; | |
| 469 | \\test { | |
| 470 | \\ const x = .{ .a = b }; | |
| 471 | \\} | |
| 470 | 472 | \\ |
| 471 | 473 | ); |
| 472 | 474 | } |
| 473 | 475 | |
| 474 | 476 | test "zig fmt: anon struct literal 1 element comma" { |
| 475 | 477 | try testCanonical( |
| 476 | \\const x = .{ | |
| 477 | \\ .a = b, | |
| 478 | \\}; | |
| 478 | \\test { | |
| 479 | \\ const x = .{ | |
| 480 | \\ .a = b, | |
| 481 | \\ }; | |
| 482 | \\} | |
| 479 | 483 | \\ |
| 480 | 484 | ); |
| 481 | 485 | } |
| 482 | 486 | |
| 483 | 487 | test "zig fmt: anon struct literal 2 element" { |
| 484 | 488 | try testCanonical( |
| 485 | \\const x = .{ .a = b, .c = d }; | |
| 489 | \\test { | |
| 490 | \\ const x = .{ .a = b, .c = d }; | |
| 491 | \\} | |
| 486 | 492 | \\ |
| 487 | 493 | ); |
| 488 | 494 | } |
| 489 | 495 | |
| 490 | 496 | test "zig fmt: anon struct literal 2 element comma" { |
| 491 | 497 | 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 | \\} | |
| 496 | 504 | \\ |
| 497 | 505 | ); |
| 498 | 506 | } |
| 499 | 507 | |
| 500 | 508 | test "zig fmt: anon struct literal 3 element" { |
| 501 | 509 | try testCanonical( |
| 502 | \\const x = .{ .a = b, .c = d, .e = f }; | |
| 510 | \\test { | |
| 511 | \\ const x = .{ .a = b, .c = d, .e = f }; | |
| 512 | \\} | |
| 503 | 513 | \\ |
| 504 | 514 | ); |
| 505 | 515 | } |
| 506 | 516 | |
| 507 | 517 | test "zig fmt: anon struct literal 3 element comma" { |
| 508 | 518 | 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 | \\} | |
| 514 | 526 | \\ |
| 515 | 527 | ); |
| 516 | 528 | } |
| 517 | 529 | |
| 518 | 530 | test "zig fmt: struct literal 1 element" { |
| 519 | 531 | try testCanonical( |
| 520 | \\const x = X{ .a = b }; | |
| 532 | \\test { | |
| 533 | \\ const x = X{ .a = b }; | |
| 534 | \\} | |
| 521 | 535 | \\ |
| 522 | 536 | ); |
| 523 | 537 | } |
| 524 | 538 | |
| 525 | 539 | test "zig fmt: struct literal 1 element comma" { |
| 526 | 540 | try testCanonical( |
| 527 | \\const x = X{ | |
| 528 | \\ .a = b, | |
| 529 | \\}; | |
| 541 | \\test { | |
| 542 | \\ const x = X{ | |
| 543 | \\ .a = b, | |
| 544 | \\ }; | |
| 545 | \\} | |
| 530 | 546 | \\ |
| 531 | 547 | ); |
| 532 | 548 | } |
| 533 | 549 | |
| 534 | 550 | test "zig fmt: struct literal 2 element" { |
| 535 | 551 | try testCanonical( |
| 536 | \\const x = X{ .a = b, .c = d }; | |
| 552 | \\test { | |
| 553 | \\ const x = X{ .a = b, .c = d }; | |
| 554 | \\} | |
| 537 | 555 | \\ |
| 538 | 556 | ); |
| 539 | 557 | } |
| 540 | 558 | |
| 541 | 559 | test "zig fmt: struct literal 2 element comma" { |
| 542 | 560 | 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 | \\} | |
| 547 | 567 | \\ |
| 548 | 568 | ); |
| 549 | 569 | } |
| 550 | 570 | |
| 551 | 571 | test "zig fmt: struct literal 3 element" { |
| 552 | 572 | 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 | \\} | |
| 554 | 576 | \\ |
| 555 | 577 | ); |
| 556 | 578 | } |
| 557 | 579 | |
| 558 | 580 | test "zig fmt: struct literal 3 element comma" { |
| 559 | 581 | 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 | \\} | |
| 565 | 589 | \\ |
| 566 | 590 | ); |
| 567 | 591 | } |
lib/std/zig/render.zig+7-3| ... | ... | @@ -405,7 +405,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 405 | 405 | .ArrayInitComma, |
| 406 | 406 | => return renderArrayInit(ais, tree, tree.arrayInit(node), space), |
| 407 | 407 | |
| 408 | .StructInitOne => { | |
| 408 | .StructInitOne, .StructInitOneComma => { | |
| 409 | 409 | var fields: [1]ast.Node.Index = undefined; |
| 410 | 410 | return renderStructInit(ais, tree, tree.structInitOne(&fields, node), space); |
| 411 | 411 | }, |
| ... | ... | @@ -413,8 +413,12 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 413 | 413 | var fields: [2]ast.Node.Index = undefined; |
| 414 | 414 | return renderStructInit(ais, tree, tree.structInitDotTwo(&fields, node), space); |
| 415 | 415 | }, |
| 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), | |
| 418 | 422 | |
| 419 | 423 | .CallOne, .CallOneComma, .AsyncCallOne, .AsyncCallOneComma => { |
| 420 | 424 | var params: [1]ast.Node.Index = undefined; |