authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-11 13:10:06-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-11 13:12:45-05:00
logd4e6a6d5e27df845d47b254aab9d14f44d68d620
treeb133bdcf05533b2c43a7b726ff047c676e90a17f
parent725b6ee634f01355da4a6badc5675751b85f0bf0
signaturelock-open Commit is signed but in an unrecognized format.

zig fmt: support anon struct and anon list init syntax


4 files changed, 108 insertions(+), 39 deletions(-)

lib/std/zig/ast.zig+17-4
......@@ -1648,10 +1648,15 @@ pub const Node = struct {
16481648
16491649 pub const SuffixOp = struct {
16501650 base: Node,
1651 lhs: *Node,
1651 lhs: Lhs,
16521652 op: Op,
16531653 rtoken: TokenIndex,
16541654
1655 pub const Lhs = union(enum) {
1656 node: *Node,
1657 dot: TokenIndex,
1658 };
1659
16551660 pub const Op = union(enum) {
16561661 Call: Call,
16571662 ArrayAccess: *Node,
......@@ -1679,8 +1684,13 @@ pub const Node = struct {
16791684 pub fn iterate(self: *SuffixOp, index: usize) ?*Node {
16801685 var i = index;
16811686
1682 if (i < 1) return self.lhs;
1683 i -= 1;
1687 switch (self.lhs) {
1688 .node => |node| {
1689 if (i == 0) return node;
1690 i -= 1;
1691 },
1692 .dot => {},
1693 }
16841694
16851695 switch (self.op) {
16861696 .Call => |*call_info| {
......@@ -1721,7 +1731,10 @@ pub const Node = struct {
17211731 .Call => |*call_info| if (call_info.async_token) |async_token| return async_token,
17221732 else => {},
17231733 }
1724 return self.lhs.firstToken();
1734 switch (self.lhs) {
1735 .node => |node| return node.firstToken(),
1736 .dot => |dot| return dot,
1737 }
17251738 }
17261739
17271740 pub fn lastToken(self: *const SuffixOp) TokenIndex {
lib/std/zig/parse.zig+32-20
......@@ -1026,16 +1026,16 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10261026/// CurlySuffixExpr <- TypeExpr InitList?
10271027fn parseCurlySuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10281028 const type_expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
1029 const init_list = (try parseInitList(arena, it, tree)) orelse return type_expr;
1030 init_list.cast(Node.SuffixOp).?.lhs = type_expr;
1031 return init_list;
1029 const suffix_op = (try parseInitList(arena, it, tree)) orelse return type_expr;
1030 suffix_op.lhs.node = type_expr;
1031 return &suffix_op.base;
10321032}
10331033
10341034/// InitList
10351035/// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
10361036/// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
10371037/// / LBRACE RBRACE
1038fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1038fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.SuffixOp {
10391039 const lbrace = eatToken(it, .LBrace) orelse return null;
10401040 var init_list = Node.SuffixOp.Op.InitList.init(arena);
10411041
......@@ -1064,11 +1064,11 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10641064 const node = try arena.create(Node.SuffixOp);
10651065 node.* = Node.SuffixOp{
10661066 .base = Node{ .id = .SuffixOp },
1067 .lhs = undefined, // set by caller
1067 .lhs = .{.node = undefined}, // set by caller
10681068 .op = op,
10691069 .rtoken = try expectToken(it, tree, .RBrace),
10701070 };
1071 return &node.base;
1071 return node;
10721072}
10731073
10741074/// TypeExpr <- PrefixTypeOp* ErrorUnionExpr
......@@ -1117,7 +1117,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11171117
11181118 while (try parseSuffixOp(arena, it, tree)) |node| {
11191119 switch (node.id) {
1120 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
1120 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
11211121 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,
11221122 else => unreachable,
11231123 }
......@@ -1133,7 +1133,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11331133 const node = try arena.create(Node.SuffixOp);
11341134 node.* = Node.SuffixOp{
11351135 .base = Node{ .id = .SuffixOp },
1136 .lhs = res,
1136 .lhs = .{.node = res},
11371137 .op = Node.SuffixOp.Op{
11381138 .Call = Node.SuffixOp.Op.Call{
11391139 .params = params.list,
......@@ -1150,7 +1150,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11501150 while (true) {
11511151 if (try parseSuffixOp(arena, it, tree)) |node| {
11521152 switch (node.id) {
1153 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,
1153 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
11541154 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,
11551155 else => unreachable,
11561156 }
......@@ -1161,7 +1161,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11611161 const call = try arena.create(Node.SuffixOp);
11621162 call.* = Node.SuffixOp{
11631163 .base = Node{ .id = .SuffixOp },
1164 .lhs = res,
1164 .lhs = .{.node = res},
11651165 .op = Node.SuffixOp.Op{
11661166 .Call = Node.SuffixOp.Op.Call{
11671167 .params = params.list,
......@@ -1215,7 +1215,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
12151215 return &node.base;
12161216 }
12171217 if (try parseContainerDecl(arena, it, tree)) |node| return node;
1218 if (try parseEnumLiteral(arena, it, tree)) |node| return node;
1218 if (try parseAnonLiteral(arena, it, tree)) |node| return node;
12191219 if (try parseErrorSetDecl(arena, it, tree)) |node| return node;
12201220 if (try parseFloatLiteral(arena, it, tree)) |node| return node;
12211221 if (try parseFnProto(arena, it, tree)) |node| return node;
......@@ -1494,16 +1494,28 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
14941494}
14951495
14961496/// DOT IDENTIFIER
1497fn parseEnumLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1497fn parseAnonLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
14981498 const dot = eatToken(it, .Period) orelse return null;
1499 const name = try expectToken(it, tree, .Identifier);
1500 const node = try arena.create(Node.EnumLiteral);
1501 node.* = Node.EnumLiteral{
1502 .base = Node{ .id = .EnumLiteral },
1503 .dot = dot,
1504 .name = name,
1505 };
1506 return &node.base;
1499
1500 // anon enum literal
1501 if (eatToken(it, .Identifier)) |name| {
1502 const node = try arena.create(Node.EnumLiteral);
1503 node.* = Node.EnumLiteral{
1504 .base = Node{ .id = .EnumLiteral },
1505 .dot = dot,
1506 .name = name,
1507 };
1508 return &node.base;
1509 }
1510
1511 // anon container literal
1512 if (try parseInitList(arena, it, tree)) |node| {
1513 node.lhs = .{.dot = dot};
1514 return &node.base;
1515 }
1516
1517 putBackToken(it, dot);
1518 return null;
15071519}
15081520
15091521/// AsmOutput <- COLON AsmOutputList AsmInput?
lib/std/zig/parser_test.zig+17
......@@ -1,3 +1,20 @@
1test "zig fmt: anon struct literal syntax" {
2 try testCanonical(
3 \\const x = .{
4 \\ .a = b,
5 \\ .c = d,
6 \\};
7 \\
8 );
9}
10
11test "zig fmt: anon list literal syntax" {
12 try testCanonical(
13 \\const x = .{ a, b, c };
14 \\
15 );
16}
17
118test "zig fmt: async function" {
219 try testCanonical(
320 \\pub const Server = struct {
lib/std/zig/render.zig+42-15
......@@ -538,9 +538,9 @@ fn renderExpression(
538538 try renderToken(tree, stream, async_token, indent, start_col, Space.Space);
539539 }
540540
541 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
541 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
542542
543 const lparen = tree.nextToken(suffix_op.lhs.lastToken());
543 const lparen = tree.nextToken(suffix_op.lhs.node.lastToken());
544544
545545 if (call_info.params.len == 0) {
546546 try renderToken(tree, stream, lparen, indent, start_col, Space.None);
......@@ -598,7 +598,7 @@ fn renderExpression(
598598 const lbracket = tree.prevToken(index_expr.firstToken());
599599 const rbracket = tree.nextToken(index_expr.lastToken());
600600
601 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
601 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
602602 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
603603
604604 const starts_with_comment = tree.tokens.at(lbracket + 1).id == .LineComment;
......@@ -616,18 +616,18 @@ fn renderExpression(
616616 },
617617
618618 ast.Node.SuffixOp.Op.Deref => {
619 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
619 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
620620 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // .*
621621 },
622622
623623 ast.Node.SuffixOp.Op.UnwrapOptional => {
624 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
624 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
625625 try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // .
626626 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ?
627627 },
628628
629629 @TagType(ast.Node.SuffixOp.Op).Slice => |range| {
630 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
630 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
631631
632632 const lbracket = tree.prevToken(range.start.firstToken());
633633 const dotdot = tree.nextToken(range.start.lastToken());
......@@ -647,10 +647,16 @@ fn renderExpression(
647647 },
648648
649649 ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
650 const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
650 const lbrace = switch (suffix_op.lhs) {
651 .dot => |dot| tree.nextToken(dot),
652 .node => |node| tree.nextToken(node.lastToken()),
653 };
651654
652655 if (field_inits.len == 0) {
653 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
656 switch (suffix_op.lhs) {
657 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
658 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
659 }
654660 try renderToken(tree, stream, lbrace, indent + indent_delta, start_col, Space.None);
655661 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
656662 }
......@@ -691,7 +697,10 @@ fn renderExpression(
691697 break :blk;
692698 }
693699
694 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
700 switch (suffix_op.lhs) {
701 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
702 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
703 }
695704 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
696705 try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
697706 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
......@@ -699,7 +708,10 @@ fn renderExpression(
699708
700709 if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) {
701710 // render all on one line, no trailing comma
702 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
711 switch (suffix_op.lhs) {
712 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
713 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
714 }
703715 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
704716
705717 var it = field_inits.iterator(0);
......@@ -719,7 +731,10 @@ fn renderExpression(
719731
720732 const new_indent = indent + indent_delta;
721733
722 try renderExpression(allocator, stream, tree, new_indent, start_col, suffix_op.lhs, Space.None);
734 switch (suffix_op.lhs) {
735 .dot => |dot| try renderToken(tree, stream, dot, new_indent, start_col, Space.None),
736 .node => |node| try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.None),
737 }
723738 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
724739
725740 var it = field_inits.iterator(0);
......@@ -743,23 +758,35 @@ fn renderExpression(
743758 },
744759
745760 ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
746 const lbrace = tree.nextToken(suffix_op.lhs.lastToken());
761 const lbrace = switch (suffix_op.lhs) {
762 .dot => |dot| tree.nextToken(dot),
763 .node => |node| tree.nextToken(node.lastToken()),
764 };
747765
748766 if (exprs.len == 0) {
749 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
767 switch (suffix_op.lhs) {
768 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
769 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
770 }
750771 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
751772 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
752773 }
753774 if (exprs.len == 1 and tree.tokens.at(exprs.at(0).*.lastToken() + 1).id == .RBrace) {
754775 const expr = exprs.at(0).*;
755776
756 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
777 switch (suffix_op.lhs) {
778 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
779 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
780 }
757781 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
758782 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
759783 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
760784 }
761785
762 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);
786 switch (suffix_op.lhs) {
787 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
788 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
789 }
763790
764791 // scan to find row size
765792 const maybe_row_size: ?usize = blk: {