| author | |
| committer | |
| log | d4e6a6d5e27df845d47b254aab9d14f44d68d620 |
| tree | b133bdcf05533b2c43a7b726ff047c676e90a17f |
| parent | 725b6ee634f01355da4a6badc5675751b85f0bf0 |
| signature |
4 files changed, 108 insertions(+), 39 deletions(-)
lib/std/zig/ast.zig+17-4| ... | @@ -1648,10 +1648,15 @@ pub const Node = struct { | ... | @@ -1648,10 +1648,15 @@ pub const Node = struct { |
| 1648 | 1648 | ||
| 1649 | pub const SuffixOp = struct { | 1649 | pub const SuffixOp = struct { |
| 1650 | base: Node, | 1650 | base: Node, |
| 1651 | lhs: *Node, | 1651 | lhs: Lhs, |
| 1652 | op: Op, | 1652 | op: Op, |
| 1653 | rtoken: TokenIndex, | 1653 | rtoken: TokenIndex, |
| 1654 | 1654 | ||
| 1655 | pub const Lhs = union(enum) { | ||
| 1656 | node: *Node, | ||
| 1657 | dot: TokenIndex, | ||
| 1658 | }; | ||
| 1659 | |||
| 1655 | pub const Op = union(enum) { | 1660 | pub const Op = union(enum) { |
| 1656 | Call: Call, | 1661 | Call: Call, |
| 1657 | ArrayAccess: *Node, | 1662 | ArrayAccess: *Node, |
| ... | @@ -1679,8 +1684,13 @@ pub const Node = struct { | ... | @@ -1679,8 +1684,13 @@ pub const Node = struct { |
| 1679 | pub fn iterate(self: *SuffixOp, index: usize) ?*Node { | 1684 | pub fn iterate(self: *SuffixOp, index: usize) ?*Node { |
| 1680 | var i = index; | 1685 | var i = index; |
| 1681 | 1686 | ||
| 1682 | if (i < 1) return self.lhs; | 1687 | switch (self.lhs) { |
| 1683 | i -= 1; | 1688 | .node => |node| { |
| 1689 | if (i == 0) return node; | ||
| 1690 | i -= 1; | ||
| 1691 | }, | ||
| 1692 | .dot => {}, | ||
| 1693 | } | ||
| 1684 | 1694 | ||
| 1685 | switch (self.op) { | 1695 | switch (self.op) { |
| 1686 | .Call => |*call_info| { | 1696 | .Call => |*call_info| { |
| ... | @@ -1721,7 +1731,10 @@ pub const Node = struct { | ... | @@ -1721,7 +1731,10 @@ pub const Node = struct { |
| 1721 | .Call => |*call_info| if (call_info.async_token) |async_token| return async_token, | 1731 | .Call => |*call_info| if (call_info.async_token) |async_token| return async_token, |
| 1722 | else => {}, | 1732 | else => {}, |
| 1723 | } | 1733 | } |
| 1724 | return self.lhs.firstToken(); | 1734 | switch (self.lhs) { |
| 1735 | .node => |node| return node.firstToken(), | ||
| 1736 | .dot => |dot| return dot, | ||
| 1737 | } | ||
| 1725 | } | 1738 | } |
| 1726 | 1739 | ||
| 1727 | pub fn lastToken(self: *const SuffixOp) TokenIndex { | 1740 | 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 { | ... | @@ -1026,16 +1026,16 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1026 | /// CurlySuffixExpr <- TypeExpr InitList? | 1026 | /// CurlySuffixExpr <- TypeExpr InitList? |
| 1027 | fn parseCurlySuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 1027 | fn parseCurlySuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1028 | const type_expr = (try parseTypeExpr(arena, it, tree)) orelse return null; | 1028 | const type_expr = (try parseTypeExpr(arena, it, tree)) orelse return null; |
| 1029 | const init_list = (try parseInitList(arena, it, tree)) orelse return type_expr; | 1029 | const suffix_op = (try parseInitList(arena, it, tree)) orelse return type_expr; |
| 1030 | init_list.cast(Node.SuffixOp).?.lhs = type_expr; | 1030 | suffix_op.lhs.node = type_expr; |
| 1031 | return init_list; | 1031 | return &suffix_op.base; |
| 1032 | } | 1032 | } |
| 1033 | 1033 | ||
| 1034 | /// InitList | 1034 | /// InitList |
| 1035 | /// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE | 1035 | /// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE |
| 1036 | /// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE | 1036 | /// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE |
| 1037 | /// / LBRACE RBRACE | 1037 | /// / LBRACE RBRACE |
| 1038 | fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 1038 | fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.SuffixOp { |
| 1039 | const lbrace = eatToken(it, .LBrace) orelse return null; | 1039 | const lbrace = eatToken(it, .LBrace) orelse return null; |
| 1040 | var init_list = Node.SuffixOp.Op.InitList.init(arena); | 1040 | var init_list = Node.SuffixOp.Op.InitList.init(arena); |
| 1041 | 1041 | ||
| ... | @@ -1064,11 +1064,11 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1064,11 +1064,11 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1064 | const node = try arena.create(Node.SuffixOp); | 1064 | const node = try arena.create(Node.SuffixOp); |
| 1065 | node.* = Node.SuffixOp{ | 1065 | node.* = Node.SuffixOp{ |
| 1066 | .base = Node{ .id = .SuffixOp }, | 1066 | .base = Node{ .id = .SuffixOp }, |
| 1067 | .lhs = undefined, // set by caller | 1067 | .lhs = .{.node = undefined}, // set by caller |
| 1068 | .op = op, | 1068 | .op = op, |
| 1069 | .rtoken = try expectToken(it, tree, .RBrace), | 1069 | .rtoken = try expectToken(it, tree, .RBrace), |
| 1070 | }; | 1070 | }; |
| 1071 | return &node.base; | 1071 | return node; |
| 1072 | } | 1072 | } |
| 1073 | 1073 | ||
| 1074 | /// TypeExpr <- PrefixTypeOp* ErrorUnionExpr | 1074 | /// TypeExpr <- PrefixTypeOp* ErrorUnionExpr |
| ... | @@ -1117,7 +1117,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1117,7 +1117,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1117 | 1117 | ||
| 1118 | while (try parseSuffixOp(arena, it, tree)) |node| { | 1118 | while (try parseSuffixOp(arena, it, tree)) |node| { |
| 1119 | switch (node.id) { | 1119 | switch (node.id) { |
| 1120 | .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res, | 1120 | .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res}, |
| 1121 | .InfixOp => node.cast(Node.InfixOp).?.lhs = res, | 1121 | .InfixOp => node.cast(Node.InfixOp).?.lhs = res, |
| 1122 | else => unreachable, | 1122 | else => unreachable, |
| 1123 | } | 1123 | } |
| ... | @@ -1133,7 +1133,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1133,7 +1133,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1133 | const node = try arena.create(Node.SuffixOp); | 1133 | const node = try arena.create(Node.SuffixOp); |
| 1134 | node.* = Node.SuffixOp{ | 1134 | node.* = Node.SuffixOp{ |
| 1135 | .base = Node{ .id = .SuffixOp }, | 1135 | .base = Node{ .id = .SuffixOp }, |
| 1136 | .lhs = res, | 1136 | .lhs = .{.node = res}, |
| 1137 | .op = Node.SuffixOp.Op{ | 1137 | .op = Node.SuffixOp.Op{ |
| 1138 | .Call = Node.SuffixOp.Op.Call{ | 1138 | .Call = Node.SuffixOp.Op.Call{ |
| 1139 | .params = params.list, | 1139 | .params = params.list, |
| ... | @@ -1150,7 +1150,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1150,7 +1150,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1150 | while (true) { | 1150 | while (true) { |
| 1151 | if (try parseSuffixOp(arena, it, tree)) |node| { | 1151 | if (try parseSuffixOp(arena, it, tree)) |node| { |
| 1152 | switch (node.id) { | 1152 | switch (node.id) { |
| 1153 | .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res, | 1153 | .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res}, |
| 1154 | .InfixOp => node.cast(Node.InfixOp).?.lhs = res, | 1154 | .InfixOp => node.cast(Node.InfixOp).?.lhs = res, |
| 1155 | else => unreachable, | 1155 | else => unreachable, |
| 1156 | } | 1156 | } |
| ... | @@ -1161,7 +1161,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1161,7 +1161,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1161 | const call = try arena.create(Node.SuffixOp); | 1161 | const call = try arena.create(Node.SuffixOp); |
| 1162 | call.* = Node.SuffixOp{ | 1162 | call.* = Node.SuffixOp{ |
| 1163 | .base = Node{ .id = .SuffixOp }, | 1163 | .base = Node{ .id = .SuffixOp }, |
| 1164 | .lhs = res, | 1164 | .lhs = .{.node = res}, |
| 1165 | .op = Node.SuffixOp.Op{ | 1165 | .op = Node.SuffixOp.Op{ |
| 1166 | .Call = Node.SuffixOp.Op.Call{ | 1166 | .Call = Node.SuffixOp.Op.Call{ |
| 1167 | .params = params.list, | 1167 | .params = params.list, |
| ... | @@ -1215,7 +1215,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N | ... | @@ -1215,7 +1215,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N |
| 1215 | return &node.base; | 1215 | return &node.base; |
| 1216 | } | 1216 | } |
| 1217 | if (try parseContainerDecl(arena, it, tree)) |node| return node; | 1217 | 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; |
| 1219 | if (try parseErrorSetDecl(arena, it, tree)) |node| return node; | 1219 | if (try parseErrorSetDecl(arena, it, tree)) |node| return node; |
| 1220 | if (try parseFloatLiteral(arena, it, tree)) |node| return node; | 1220 | if (try parseFloatLiteral(arena, it, tree)) |node| return node; |
| 1221 | if (try parseFnProto(arena, it, tree)) |node| return node; | 1221 | if (try parseFnProto(arena, it, tree)) |node| return node; |
| ... | @@ -1494,16 +1494,28 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | ... | @@ -1494,16 +1494,28 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1494 | } | 1494 | } |
| 1495 | 1495 | ||
| 1496 | /// DOT IDENTIFIER | 1496 | /// DOT IDENTIFIER |
| 1497 | fn parseEnumLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | 1497 | fn parseAnonLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 1498 | const dot = eatToken(it, .Period) orelse return null; | 1498 | const dot = eatToken(it, .Period) orelse return null; |
| 1499 | const name = try expectToken(it, tree, .Identifier); | 1499 | |
| 1500 | const node = try arena.create(Node.EnumLiteral); | 1500 | // anon enum literal |
| 1501 | node.* = Node.EnumLiteral{ | 1501 | if (eatToken(it, .Identifier)) |name| { |
| 1502 | .base = Node{ .id = .EnumLiteral }, | 1502 | const node = try arena.create(Node.EnumLiteral); |
| 1503 | .dot = dot, | 1503 | node.* = Node.EnumLiteral{ |
| 1504 | .name = name, | 1504 | .base = Node{ .id = .EnumLiteral }, |
| 1505 | }; | 1505 | .dot = dot, |
| 1506 | return &node.base; | 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; | ||
| 1507 | } | 1519 | } |
| 1508 | 1520 | ||
| 1509 | /// AsmOutput <- COLON AsmOutputList AsmInput? | 1521 | /// AsmOutput <- COLON AsmOutputList AsmInput? |
lib/std/zig/parser_test.zig+17| ... | @@ -1,3 +1,20 @@ | ... | @@ -1,3 +1,20 @@ |
| 1 | test "zig fmt: anon struct literal syntax" { | ||
| 2 | try testCanonical( | ||
| 3 | \\const x = .{ | ||
| 4 | \\ .a = b, | ||
| 5 | \\ .c = d, | ||
| 6 | \\}; | ||
| 7 | \\ | ||
| 8 | ); | ||
| 9 | } | ||
| 10 | |||
| 11 | test "zig fmt: anon list literal syntax" { | ||
| 12 | try testCanonical( | ||
| 13 | \\const x = .{ a, b, c }; | ||
| 14 | \\ | ||
| 15 | ); | ||
| 16 | } | ||
| 17 | |||
| 1 | test "zig fmt: async function" { | 18 | test "zig fmt: async function" { |
| 2 | try testCanonical( | 19 | try testCanonical( |
| 3 | \\pub const Server = struct { | 20 | \\pub const Server = struct { |
lib/std/zig/render.zig+42-15| ... | @@ -538,9 +538,9 @@ fn renderExpression( | ... | @@ -538,9 +538,9 @@ fn renderExpression( |
| 538 | try renderToken(tree, stream, async_token, indent, start_col, Space.Space); | 538 | try renderToken(tree, stream, async_token, indent, start_col, Space.Space); |
| 539 | } | 539 | } |
| 540 | 540 | ||
| 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); |
| 542 | 542 | ||
| 543 | const lparen = tree.nextToken(suffix_op.lhs.lastToken()); | 543 | const lparen = tree.nextToken(suffix_op.lhs.node.lastToken()); |
| 544 | 544 | ||
| 545 | if (call_info.params.len == 0) { | 545 | if (call_info.params.len == 0) { |
| 546 | try renderToken(tree, stream, lparen, indent, start_col, Space.None); | 546 | try renderToken(tree, stream, lparen, indent, start_col, Space.None); |
| ... | @@ -598,7 +598,7 @@ fn renderExpression( | ... | @@ -598,7 +598,7 @@ fn renderExpression( |
| 598 | const lbracket = tree.prevToken(index_expr.firstToken()); | 598 | const lbracket = tree.prevToken(index_expr.firstToken()); |
| 599 | const rbracket = tree.nextToken(index_expr.lastToken()); | 599 | const rbracket = tree.nextToken(index_expr.lastToken()); |
| 600 | 600 | ||
| 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); |
| 602 | try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [ | 602 | try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [ |
| 603 | 603 | ||
| 604 | const starts_with_comment = tree.tokens.at(lbracket + 1).id == .LineComment; | 604 | const starts_with_comment = tree.tokens.at(lbracket + 1).id == .LineComment; |
| ... | @@ -616,18 +616,18 @@ fn renderExpression( | ... | @@ -616,18 +616,18 @@ fn renderExpression( |
| 616 | }, | 616 | }, |
| 617 | 617 | ||
| 618 | ast.Node.SuffixOp.Op.Deref => { | 618 | 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); |
| 620 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // .* | 620 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // .* |
| 621 | }, | 621 | }, |
| 622 | 622 | ||
| 623 | ast.Node.SuffixOp.Op.UnwrapOptional => { | 623 | 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); |
| 625 | try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // . | 625 | try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // . |
| 626 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ? | 626 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ? |
| 627 | }, | 627 | }, |
| 628 | 628 | ||
| 629 | @TagType(ast.Node.SuffixOp.Op).Slice => |range| { | 629 | @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); |
| 631 | 631 | ||
| 632 | const lbracket = tree.prevToken(range.start.firstToken()); | 632 | const lbracket = tree.prevToken(range.start.firstToken()); |
| 633 | const dotdot = tree.nextToken(range.start.lastToken()); | 633 | const dotdot = tree.nextToken(range.start.lastToken()); |
| ... | @@ -647,10 +647,16 @@ fn renderExpression( | ... | @@ -647,10 +647,16 @@ fn renderExpression( |
| 647 | }, | 647 | }, |
| 648 | 648 | ||
| 649 | ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| { | 649 | 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 | }; | ||
| 651 | 654 | ||
| 652 | if (field_inits.len == 0) { | 655 | 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 | } | ||
| 654 | try renderToken(tree, stream, lbrace, indent + indent_delta, start_col, Space.None); | 660 | try renderToken(tree, stream, lbrace, indent + indent_delta, start_col, Space.None); |
| 655 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); | 661 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); |
| 656 | } | 662 | } |
| ... | @@ -691,7 +697,10 @@ fn renderExpression( | ... | @@ -691,7 +697,10 @@ fn renderExpression( |
| 691 | break :blk; | 697 | break :blk; |
| 692 | } | 698 | } |
| 693 | 699 | ||
| 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 | } | ||
| 695 | try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); | 704 | try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); |
| 696 | try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space); | 705 | try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space); |
| 697 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); | 706 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); |
| ... | @@ -699,7 +708,10 @@ fn renderExpression( | ... | @@ -699,7 +708,10 @@ fn renderExpression( |
| 699 | 708 | ||
| 700 | if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) { | 709 | if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) { |
| 701 | // render all on one line, no trailing comma | 710 | // 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 | } | ||
| 703 | try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); | 715 | try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); |
| 704 | 716 | ||
| 705 | var it = field_inits.iterator(0); | 717 | var it = field_inits.iterator(0); |
| ... | @@ -719,7 +731,10 @@ fn renderExpression( | ... | @@ -719,7 +731,10 @@ fn renderExpression( |
| 719 | 731 | ||
| 720 | const new_indent = indent + indent_delta; | 732 | const new_indent = indent + indent_delta; |
| 721 | 733 | ||
| 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 | } | ||
| 723 | try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); | 738 | try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); |
| 724 | 739 | ||
| 725 | var it = field_inits.iterator(0); | 740 | var it = field_inits.iterator(0); |
| ... | @@ -743,23 +758,35 @@ fn renderExpression( | ... | @@ -743,23 +758,35 @@ fn renderExpression( |
| 743 | }, | 758 | }, |
| 744 | 759 | ||
| 745 | ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| { | 760 | 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 | }; | ||
| 747 | 765 | ||
| 748 | if (exprs.len == 0) { | 766 | 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 | } | ||
| 750 | try renderToken(tree, stream, lbrace, indent, start_col, Space.None); | 771 | try renderToken(tree, stream, lbrace, indent, start_col, Space.None); |
| 751 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); | 772 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); |
| 752 | } | 773 | } |
| 753 | if (exprs.len == 1 and tree.tokens.at(exprs.at(0).*.lastToken() + 1).id == .RBrace) { | 774 | if (exprs.len == 1 and tree.tokens.at(exprs.at(0).*.lastToken() + 1).id == .RBrace) { |
| 754 | const expr = exprs.at(0).*; | 775 | const expr = exprs.at(0).*; |
| 755 | 776 | ||
| 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 | } | ||
| 757 | try renderToken(tree, stream, lbrace, indent, start_col, Space.None); | 781 | try renderToken(tree, stream, lbrace, indent, start_col, Space.None); |
| 758 | try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None); | 782 | try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None); |
| 759 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); | 783 | return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); |
| 760 | } | 784 | } |
| 761 | 785 | ||
| 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 | } | ||
| 763 | 790 | ||
| 764 | // scan to find row size | 791 | // scan to find row size |
| 765 | const maybe_row_size: ?usize = blk: { | 792 | const maybe_row_size: ?usize = blk: { |