| author | |
| committer | |
| log | d869133a9fb96fb27a07c1e42c12c5270eae5940 |
| tree | 6ea7c15c277ae03fa3d2c60a89a90288adce7532 |
| parent | 837cd748a8607a6ac9f1a5bfc6d625512bacb906 |
4 files changed, 249 insertions(+), 262 deletions(-)
lib/std/zig/ast.zig+88-13| ... | ... | @@ -213,6 +213,7 @@ pub const Tree = struct { |
| 213 | 213 | .Await, |
| 214 | 214 | .OptionalType, |
| 215 | 215 | .Switch, |
| 216 | .SwitchComma, | |
| 216 | 217 | .IfSimple, |
| 217 | 218 | .If, |
| 218 | 219 | .Suspend, |
| ... | ... | @@ -313,7 +314,6 @@ pub const Tree = struct { |
| 313 | 314 | .StructInit, |
| 314 | 315 | .CallOne, |
| 315 | 316 | .Call, |
| 316 | .SwitchCaseOne, | |
| 317 | 317 | .SwitchRange, |
| 318 | 318 | .FnDecl, |
| 319 | 319 | .ErrorUnion, |
| ... | ... | @@ -406,7 +406,19 @@ pub const Tree = struct { |
| 406 | 406 | }; |
| 407 | 407 | }, |
| 408 | 408 | |
| 409 | .SwitchCaseMulti => unreachable, // TODO | |
| 409 | .SwitchCaseOne => { | |
| 410 | if (datas[n].lhs == 0) { | |
| 411 | return main_tokens[n] - 1; // else token | |
| 412 | } else { | |
| 413 | n = datas[n].lhs; | |
| 414 | } | |
| 415 | }, | |
| 416 | .SwitchCase => { | |
| 417 | const extra = tree.extraData(datas[n].lhs, Node.SubRange); | |
| 418 | assert(extra.end - extra.start > 0); | |
| 419 | n = extra.start; | |
| 420 | }, | |
| 421 | ||
| 410 | 422 | .WhileSimple => unreachable, // TODO |
| 411 | 423 | .WhileCont => unreachable, // TODO |
| 412 | 424 | .While => unreachable, // TODO |
| ... | ... | @@ -494,6 +506,8 @@ pub const Tree = struct { |
| 494 | 506 | .PtrTypeSentinel, |
| 495 | 507 | .PtrType, |
| 496 | 508 | .PtrTypeBitRange, |
| 509 | .SwitchCaseOne, | |
| 510 | .SwitchCase, | |
| 497 | 511 | => n = datas[n].rhs, |
| 498 | 512 | |
| 499 | 513 | .FieldAccess, |
| ... | ... | @@ -532,6 +546,16 @@ pub const Tree = struct { |
| 532 | 546 | } |
| 533 | 547 | n = tree.extra_data[params.end - 1]; // last parameter |
| 534 | 548 | }, |
| 549 | .Switch => { | |
| 550 | const cases = tree.extraData(datas[n].rhs, Node.SubRange); | |
| 551 | if (cases.end - cases.start == 0) { | |
| 552 | end_offset += 3; // rparen, lbrace, rbrace | |
| 553 | n = datas[n].lhs; // condition expression | |
| 554 | } else { | |
| 555 | end_offset += 1; // for the rbrace | |
| 556 | n = tree.extra_data[cases.end - 1]; // last case | |
| 557 | } | |
| 558 | }, | |
| 535 | 559 | .ContainerDeclArg => { |
| 536 | 560 | const members = tree.extraData(datas[n].rhs, Node.SubRange); |
| 537 | 561 | if (members.end - members.start == 0) { |
| ... | ... | @@ -542,7 +566,9 @@ pub const Tree = struct { |
| 542 | 566 | n = tree.extra_data[members.end - 1]; // last parameter |
| 543 | 567 | } |
| 544 | 568 | }, |
| 545 | .ContainerDeclArgComma => { | |
| 569 | .ContainerDeclArgComma, | |
| 570 | .SwitchComma, | |
| 571 | => { | |
| 546 | 572 | const members = tree.extraData(datas[n].rhs, Node.SubRange); |
| 547 | 573 | assert(members.end - members.start > 0); |
| 548 | 574 | end_offset += 2; // for the comma + rbrace |
| ... | ... | @@ -737,16 +763,13 @@ pub const Tree = struct { |
| 737 | 763 | |
| 738 | 764 | .TaggedUnionEnumTag => unreachable, // TODO |
| 739 | 765 | .TaggedUnionEnumTagComma => unreachable, // TODO |
| 740 | .Switch => unreachable, // TODO | |
| 741 | 766 | .If => unreachable, // TODO |
| 742 | 767 | .Continue => unreachable, // TODO |
| 743 | 768 | .AsmSimple => unreachable, // TODO |
| 744 | 769 | .Asm => unreachable, // TODO |
| 745 | .SwitchCaseOne => unreachable, // TODO | |
| 746 | 770 | .SwitchRange => unreachable, // TODO |
| 747 | 771 | .ArrayType => unreachable, // TODO |
| 748 | 772 | .ArrayTypeSentinel => unreachable, // TODO |
| 749 | .SwitchCaseMulti => unreachable, // TODO | |
| 750 | 773 | .WhileCont => unreachable, // TODO |
| 751 | 774 | .While => unreachable, // TODO |
| 752 | 775 | .ForSimple => unreachable, // TODO |
| ... | ... | @@ -1202,7 +1225,8 @@ pub const Tree = struct { |
| 1202 | 1225 | } |
| 1203 | 1226 | |
| 1204 | 1227 | pub fn containerDeclArg(tree: Tree, node: Node.Index) Full.ContainerDecl { |
| 1205 | assert(tree.nodes.items(.tag)[node] == .ContainerDeclArg); | |
| 1228 | assert(tree.nodes.items(.tag)[node] == .ContainerDeclArg or | |
| 1229 | tree.nodes.items(.tag)[node] == .ContainerDeclArgComma); | |
| 1206 | 1230 | const data = tree.nodes.items(.data)[node]; |
| 1207 | 1231 | const members_range = tree.extraData(data.rhs, Node.SubRange); |
| 1208 | 1232 | return tree.fullContainerDecl(.{ |
| ... | ... | @@ -1214,7 +1238,8 @@ pub const Tree = struct { |
| 1214 | 1238 | } |
| 1215 | 1239 | |
| 1216 | 1240 | pub fn taggedUnionTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl { |
| 1217 | assert(tree.nodes.items(.tag)[node] == .TaggedUnionTwo); | |
| 1241 | assert(tree.nodes.items(.tag)[node] == .TaggedUnionTwo or | |
| 1242 | tree.nodes.items(.tag)[node] == .TaggedUnionTwoComma); | |
| 1218 | 1243 | const data = tree.nodes.items(.data)[node]; |
| 1219 | 1244 | buffer.* = .{ data.lhs, data.rhs }; |
| 1220 | 1245 | const members = if (data.rhs != 0) |
| ... | ... | @@ -1233,7 +1258,8 @@ pub const Tree = struct { |
| 1233 | 1258 | } |
| 1234 | 1259 | |
| 1235 | 1260 | pub fn taggedUnion(tree: Tree, node: Node.Index) Full.ContainerDecl { |
| 1236 | assert(tree.nodes.items(.tag)[node] == .TaggedUnion); | |
| 1261 | assert(tree.nodes.items(.tag)[node] == .TaggedUnion or | |
| 1262 | tree.nodes.items(.tag)[node] == .TaggedUnionComma); | |
| 1237 | 1263 | const data = tree.nodes.items(.data)[node]; |
| 1238 | 1264 | const main_token = tree.nodes.items(.main_token)[node]; |
| 1239 | 1265 | return tree.fullContainerDecl(.{ |
| ... | ... | @@ -1245,7 +1271,8 @@ pub const Tree = struct { |
| 1245 | 1271 | } |
| 1246 | 1272 | |
| 1247 | 1273 | pub fn taggedUnionEnumTag(tree: Tree, node: Node.Index) Full.ContainerDecl { |
| 1248 | assert(tree.nodes.items(.tag)[node] == .TaggedUnionEnumTag); | |
| 1274 | assert(tree.nodes.items(.tag)[node] == .TaggedUnionEnumTag or | |
| 1275 | tree.nodes.items(.tag)[node] == .TaggedUnionEnumTagComma); | |
| 1249 | 1276 | const data = tree.nodes.items(.data)[node]; |
| 1250 | 1277 | const members_range = tree.extraData(data.rhs, Node.SubRange); |
| 1251 | 1278 | const main_token = tree.nodes.items(.main_token)[node]; |
| ... | ... | @@ -1257,6 +1284,25 @@ pub const Tree = struct { |
| 1257 | 1284 | }); |
| 1258 | 1285 | } |
| 1259 | 1286 | |
| 1287 | pub fn switchCaseOne(tree: Tree, node: Node.Index) Full.SwitchCase { | |
| 1288 | const data = &tree.nodes.items(.data)[node]; | |
| 1289 | return tree.fullSwitchCase(.{ | |
| 1290 | .values = if (data.lhs == 0) &.{} else @ptrCast([*]Node.Index, &data.lhs)[0..1], | |
| 1291 | .arrow_token = tree.nodes.items(.main_token)[node], | |
| 1292 | .target_expr = data.rhs, | |
| 1293 | }); | |
| 1294 | } | |
| 1295 | ||
| 1296 | pub fn switchCase(tree: Tree, node: Node.Index) Full.SwitchCase { | |
| 1297 | const data = tree.nodes.items(.data)[node]; | |
| 1298 | const extra = tree.extraData(data.lhs, Node.SubRange); | |
| 1299 | return tree.fullSwitchCase(.{ | |
| 1300 | .values = tree.extra_data[extra.start..extra.end], | |
| 1301 | .arrow_token = tree.nodes.items(.main_token)[node], | |
| 1302 | .target_expr = data.rhs, | |
| 1303 | }); | |
| 1304 | } | |
| 1305 | ||
| 1260 | 1306 | fn fullVarDecl(tree: Tree, info: Full.VarDecl.Ast) Full.VarDecl { |
| 1261 | 1307 | const token_tags = tree.tokens.items(.tag); |
| 1262 | 1308 | var result: Full.VarDecl = .{ |
| ... | ... | @@ -1407,6 +1453,18 @@ pub const Tree = struct { |
| 1407 | 1453 | } |
| 1408 | 1454 | return result; |
| 1409 | 1455 | } |
| 1456 | ||
| 1457 | fn fullSwitchCase(tree: Tree, info: Full.SwitchCase.Ast) Full.SwitchCase { | |
| 1458 | const token_tags = tree.tokens.items(.tag); | |
| 1459 | var result: Full.SwitchCase = .{ | |
| 1460 | .ast = info, | |
| 1461 | .payload_token = null, | |
| 1462 | }; | |
| 1463 | if (token_tags[info.arrow_token + 1] == .Pipe) { | |
| 1464 | result.payload_token = info.arrow_token + 2; | |
| 1465 | } | |
| 1466 | return result; | |
| 1467 | } | |
| 1410 | 1468 | }; |
| 1411 | 1469 | |
| 1412 | 1470 | /// Fully assembled AST node information. |
| ... | ... | @@ -1552,6 +1610,20 @@ pub const Full = struct { |
| 1552 | 1610 | arg: Node.Index, |
| 1553 | 1611 | }; |
| 1554 | 1612 | }; |
| 1613 | ||
| 1614 | pub const SwitchCase = struct { | |
| 1615 | /// Points to the first token after the `|`. Will either be an identifier or | |
| 1616 | /// a `*` (with an identifier immediately after it). | |
| 1617 | payload_token: ?TokenIndex, | |
| 1618 | ast: Ast, | |
| 1619 | ||
| 1620 | pub const Ast = struct { | |
| 1621 | /// If empty, this is an else case | |
| 1622 | values: []const Node.Index, | |
| 1623 | arrow_token: TokenIndex, | |
| 1624 | target_expr: Node.Index, | |
| 1625 | }; | |
| 1626 | }; | |
| 1555 | 1627 | }; |
| 1556 | 1628 | |
| 1557 | 1629 | pub const Error = union(enum) { |
| ... | ... | @@ -1996,13 +2068,16 @@ pub const Node = struct { |
| 1996 | 2068 | /// `lhs(a, b, c)`. `sub_range_list[rhs]`. |
| 1997 | 2069 | /// main_token is the `(`. |
| 1998 | 2070 | Call, |
| 1999 | /// `switch(lhs) {}`. `sub_range_list[rhs]`. | |
| 2071 | /// `switch(lhs) {}`. `SubRange[rhs]`. | |
| 2000 | 2072 | Switch, |
| 2073 | /// Same as Switch except there is known to be a trailing comma | |
| 2074 | /// before the final rbrace | |
| 2075 | SwitchComma, | |
| 2001 | 2076 | /// `lhs => rhs`. If lhs is omitted it means `else`. |
| 2002 | 2077 | /// main_token is the `=>` |
| 2003 | 2078 | SwitchCaseOne, |
| 2004 | /// `a, b, c => rhs`. `sub_range_list[lhs]`. | |
| 2005 | SwitchCaseMulti, | |
| 2079 | /// `a, b, c => rhs`. `SubRange[lhs]`. | |
| 2080 | SwitchCase, | |
| 2006 | 2081 | /// `lhs...rhs`. |
| 2007 | 2082 | SwitchRange, |
| 2008 | 2083 | /// `while (lhs) rhs`. |
lib/std/zig/parse.zig+3-2| ... | ... | @@ -2887,10 +2887,11 @@ const Parser = struct { |
| 2887 | 2887 | _ = try p.expectToken(.RParen); |
| 2888 | 2888 | _ = try p.expectToken(.LBrace); |
| 2889 | 2889 | const cases = try p.parseSwitchProngList(); |
| 2890 | const trailing_comma = p.token_tags[p.tok_i - 1] == .Comma; | |
| 2890 | 2891 | _ = try p.expectToken(.RBrace); |
| 2891 | 2892 | |
| 2892 | 2893 | return p.addNode(.{ |
| 2893 | .tag = .Switch, | |
| 2894 | .tag = if (trailing_comma) .SwitchComma else .Switch, | |
| 2894 | 2895 | .main_token = switch_token, |
| 2895 | 2896 | .data = .{ |
| 2896 | 2897 | .lhs = expr_node, |
| ... | ... | @@ -3208,7 +3209,7 @@ const Parser = struct { |
| 3208 | 3209 | const arrow_token = try p.expectToken(.EqualAngleBracketRight); |
| 3209 | 3210 | _ = try p.parsePtrPayload(); |
| 3210 | 3211 | return p.addNode(.{ |
| 3211 | .tag = .SwitchCaseMulti, | |
| 3212 | .tag = .SwitchCase, | |
| 3212 | 3213 | .main_token = arrow_token, |
| 3213 | 3214 | .data = .{ |
| 3214 | 3215 | .lhs = try p.addExtra(Node.SubRange{ |
lib/std/zig/parser_test.zig+72-72| ... | ... | @@ -1671,32 +1671,32 @@ test "zig fmt: block in slice expression" { |
| 1671 | 1671 | // \\ |
| 1672 | 1672 | // ); |
| 1673 | 1673 | //} |
| 1674 | // | |
| 1675 | //test "zig fmt: switch cases trailing comma" { | |
| 1676 | // try testTransform( | |
| 1677 | // \\fn switch_cases(x: i32) void { | |
| 1678 | // \\ switch (x) { | |
| 1679 | // \\ 1,2,3 => {}, | |
| 1680 | // \\ 4,5, => {}, | |
| 1681 | // \\ 6... 8, => {}, | |
| 1682 | // \\ else => {}, | |
| 1683 | // \\ } | |
| 1684 | // \\} | |
| 1685 | // , | |
| 1686 | // \\fn switch_cases(x: i32) void { | |
| 1687 | // \\ switch (x) { | |
| 1688 | // \\ 1, 2, 3 => {}, | |
| 1689 | // \\ 4, | |
| 1690 | // \\ 5, | |
| 1691 | // \\ => {}, | |
| 1692 | // \\ 6...8 => {}, | |
| 1693 | // \\ else => {}, | |
| 1694 | // \\ } | |
| 1695 | // \\} | |
| 1696 | // \\ | |
| 1697 | // ); | |
| 1698 | //} | |
| 1699 | // | |
| 1674 | ||
| 1675 | test "zig fmt: switch cases trailing comma" { | |
| 1676 | try testTransform( | |
| 1677 | \\test "switch cases trailing comma"{ | |
| 1678 | \\ switch (x) { | |
| 1679 | \\ 1,2,3 => {}, | |
| 1680 | \\ 4,5, => {}, | |
| 1681 | \\ 6... 8, => {}, | |
| 1682 | \\ else => {}, | |
| 1683 | \\ } | |
| 1684 | \\} | |
| 1685 | , | |
| 1686 | \\test "switch cases trailing comma" { | |
| 1687 | \\ switch (x) { | |
| 1688 | \\ 1, 2, 3 => {}, | |
| 1689 | \\ 4, | |
| 1690 | \\ 5, | |
| 1691 | \\ => {}, | |
| 1692 | \\ 6...8 => {}, | |
| 1693 | \\ else => {}, | |
| 1694 | \\ } | |
| 1695 | \\} | |
| 1696 | \\ | |
| 1697 | ); | |
| 1698 | } | |
| 1699 | ||
| 1700 | 1700 | //test "zig fmt: slice align" { |
| 1701 | 1701 | // try testCanonical( |
| 1702 | 1702 | // \\const A = struct { |
| ... | ... | @@ -1996,16 +1996,16 @@ test "zig fmt: ptr deref operator and unwrap optional operator" { |
| 1996 | 1996 | // \\ |
| 1997 | 1997 | // ); |
| 1998 | 1998 | //} |
| 1999 | // | |
| 2000 | //test "zig fmt: switch with empty body" { | |
| 2001 | // try testCanonical( | |
| 2002 | // \\test "" { | |
| 2003 | // \\ foo() catch |err| switch (err) {}; | |
| 2004 | // \\} | |
| 2005 | // \\ | |
| 2006 | // ); | |
| 2007 | //} | |
| 2008 | // | |
| 1999 | ||
| 2000 | test "zig fmt: switch with empty body" { | |
| 2001 | try testCanonical( | |
| 2002 | \\test "" { | |
| 2003 | \\ foo() catch |err| switch (err) {}; | |
| 2004 | \\} | |
| 2005 | \\ | |
| 2006 | ); | |
| 2007 | } | |
| 2008 | ||
| 2009 | 2009 | //test "zig fmt: line comments in struct initializer" { |
| 2010 | 2010 | // try testCanonical( |
| 2011 | 2011 | // \\fn foo() void { |
| ... | ... | @@ -2725,42 +2725,42 @@ test "zig fmt: blocks" { |
| 2725 | 2725 | ); |
| 2726 | 2726 | } |
| 2727 | 2727 | |
| 2728 | //test "zig fmt: switch" { | |
| 2729 | // try testCanonical( | |
| 2730 | // \\test "switch" { | |
| 2731 | // \\ switch (0) { | |
| 2732 | // \\ 0 => {}, | |
| 2733 | // \\ 1 => unreachable, | |
| 2734 | // \\ 2, 3 => {}, | |
| 2735 | // \\ 4...7 => {}, | |
| 2736 | // \\ 1 + 4 * 3 + 22 => {}, | |
| 2737 | // \\ else => { | |
| 2738 | // \\ const a = 1; | |
| 2739 | // \\ const b = a; | |
| 2740 | // \\ }, | |
| 2741 | // \\ } | |
| 2742 | // \\ | |
| 2743 | // \\ const res = switch (0) { | |
| 2744 | // \\ 0 => 0, | |
| 2745 | // \\ 1 => 2, | |
| 2746 | // \\ 1 => a = 4, | |
| 2747 | // \\ else => 4, | |
| 2748 | // \\ }; | |
| 2749 | // \\ | |
| 2750 | // \\ const Union = union(enum) { | |
| 2751 | // \\ Int: i64, | |
| 2752 | // \\ Float: f64, | |
| 2753 | // \\ }; | |
| 2754 | // \\ | |
| 2755 | // \\ switch (u) { | |
| 2756 | // \\ Union.Int => |int| {}, | |
| 2757 | // \\ Union.Float => |*float| unreachable, | |
| 2758 | // \\ } | |
| 2759 | // \\} | |
| 2760 | // \\ | |
| 2761 | // ); | |
| 2762 | //} | |
| 2763 | // | |
| 2728 | test "zig fmt: switch" { | |
| 2729 | try testCanonical( | |
| 2730 | \\test "switch" { | |
| 2731 | \\ switch (0) { | |
| 2732 | \\ 0 => {}, | |
| 2733 | \\ 1 => unreachable, | |
| 2734 | \\ 2, 3 => {}, | |
| 2735 | \\ 4...7 => {}, | |
| 2736 | \\ 1 + 4 * 3 + 22 => {}, | |
| 2737 | \\ else => { | |
| 2738 | \\ const a = 1; | |
| 2739 | \\ const b = a; | |
| 2740 | \\ }, | |
| 2741 | \\ } | |
| 2742 | \\ | |
| 2743 | \\ const res = switch (0) { | |
| 2744 | \\ 0 => 0, | |
| 2745 | \\ 1 => 2, | |
| 2746 | \\ 1 => a = 4, | |
| 2747 | \\ else => 4, | |
| 2748 | \\ }; | |
| 2749 | \\ | |
| 2750 | \\ const Union = union(enum) { | |
| 2751 | \\ Int: i64, | |
| 2752 | \\ Float: f64, | |
| 2753 | \\ }; | |
| 2754 | \\ | |
| 2755 | \\ switch (u) { | |
| 2756 | \\ Union.Int => |int| {}, | |
| 2757 | \\ Union.Float => |*float| unreachable, | |
| 2758 | \\ } | |
| 2759 | \\} | |
| 2760 | \\ | |
| 2761 | ); | |
| 2762 | } | |
| 2763 | ||
| 2764 | 2764 | //test "zig fmt: while" { |
| 2765 | 2765 | // try testCanonical( |
| 2766 | 2766 | // \\test "while" { |
lib/std/zig/render.zig+86-175| ... | ... | @@ -207,19 +207,18 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 207 | 207 | => { |
| 208 | 208 | const statements = [2]ast.Node.Index{ datas[node].lhs, datas[node].rhs }; |
| 209 | 209 | if (datas[node].lhs == 0) { |
| 210 | return renderBlock(ais, tree, main_tokens[node], statements[0..0], space); | |
| 210 | return renderBlock(ais, tree, node, statements[0..0], space); | |
| 211 | 211 | } else if (datas[node].rhs == 0) { |
| 212 | return renderBlock(ais, tree, main_tokens[node], statements[0..1], space); | |
| 212 | return renderBlock(ais, tree, node, statements[0..1], space); | |
| 213 | 213 | } else { |
| 214 | return renderBlock(ais, tree, main_tokens[node], statements[0..2], space); | |
| 214 | return renderBlock(ais, tree, node, statements[0..2], space); | |
| 215 | 215 | } |
| 216 | 216 | }, |
| 217 | 217 | .Block, |
| 218 | 218 | .BlockSemicolon, |
| 219 | 219 | => { |
| 220 | const lbrace = main_tokens[node]; | |
| 221 | 220 | const statements = tree.extra_data[datas[node].lhs..datas[node].rhs]; |
| 222 | return renderBlock(ais, tree, main_tokens[node], statements, space); | |
| 221 | return renderBlock(ais, tree, node, statements, space); | |
| 223 | 222 | }, |
| 224 | 223 | |
| 225 | 224 | .ErrDefer => { |
| ... | ... | @@ -615,81 +614,6 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 615 | 614 | try renderToken(ais, tree, rbrace, space); |
| 616 | 615 | } |
| 617 | 616 | }, |
| 618 | //.ErrorSetDecl => { | |
| 619 | // const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base); | |
| 620 | ||
| 621 | // const lbrace = tree.nextToken(err_set_decl.error_token); | |
| 622 | ||
| 623 | // if (err_set_decl.decls_len == 0) { | |
| 624 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); | |
| 625 | // try renderToken(ais, tree, lbrace, Space.None); | |
| 626 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); | |
| 627 | // } | |
| 628 | ||
| 629 | // if (err_set_decl.decls_len == 1) blk: { | |
| 630 | // const node = err_set_decl.decls()[0]; | |
| 631 | ||
| 632 | // // if there are any doc comments or same line comments | |
| 633 | // // don't try to put it all on one line | |
| 634 | // if (node.cast(ast.Node.ErrorTag)) |tag| { | |
| 635 | // if (tag.doc_comments != null) break :blk; | |
| 636 | // } else { | |
| 637 | // break :blk; | |
| 638 | // } | |
| 639 | ||
| 640 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error | |
| 641 | // try renderToken(ais, tree, lbrace, Space.None); // lbrace | |
| 642 | // try renderExpression(ais, tree, node, Space.None); | |
| 643 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace | |
| 644 | // } | |
| 645 | ||
| 646 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error | |
| 647 | ||
| 648 | // const src_has_trailing_comma = blk: { | |
| 649 | // const maybe_comma = tree.prevToken(err_set_decl.rbrace_token); | |
| 650 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 651 | // }; | |
| 652 | ||
| 653 | // if (src_has_trailing_comma) { | |
| 654 | // { | |
| 655 | // ais.pushIndent(); | |
| 656 | // defer ais.popIndent(); | |
| 657 | ||
| 658 | // try renderToken(ais, tree, lbrace, Space.Newline); // lbrace | |
| 659 | // const decls = err_set_decl.decls(); | |
| 660 | // for (decls) |node, i| { | |
| 661 | // if (i + 1 < decls.len) { | |
| 662 | // try renderExpression(ais, tree, node, Space.None); | |
| 663 | // try renderToken(ais, tree, tree.nextToken(node.lastToken()), Space.Newline); // , | |
| 664 | ||
| 665 | // try renderExtraNewline(ais, tree, decls[i + 1]); | |
| 666 | // } else { | |
| 667 | // try renderExpression(ais, tree, node, Space.Comma); | |
| 668 | // } | |
| 669 | // } | |
| 670 | // } | |
| 671 | ||
| 672 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace | |
| 673 | // } else { | |
| 674 | // try renderToken(ais, tree, lbrace, Space.Space); // lbrace | |
| 675 | ||
| 676 | // const decls = err_set_decl.decls(); | |
| 677 | // for (decls) |node, i| { | |
| 678 | // if (i + 1 < decls.len) { | |
| 679 | // try renderExpression(ais, tree, node, Space.None); | |
| 680 | ||
| 681 | // const comma_token = tree.nextToken(node.lastToken()); | |
| 682 | // assert(tree.token_tags[comma_token] == .Comma); | |
| 683 | // try renderToken(ais, tree, comma_token, Space.Space); // , | |
| 684 | // try renderExtraNewline(ais, tree, decls[i + 1]); | |
| 685 | // } else { | |
| 686 | // try renderExpression(ais, tree, node, Space.Space); | |
| 687 | // } | |
| 688 | // } | |
| 689 | ||
| 690 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace | |
| 691 | // } | |
| 692 | //}, | |
| 693 | 617 | |
| 694 | 618 | .BuiltinCallTwo, .BuiltinCallTwoComma => { |
| 695 | 619 | if (datas[node].lhs == 0) { |
| ... | ... | @@ -732,92 +656,38 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 732 | 656 | // } |
| 733 | 657 | //}, |
| 734 | 658 | |
| 735 | .Switch => unreachable, // TODO | |
| 736 | //.Switch => { | |
| 737 | // const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base); | |
| 738 | ||
| 739 | // try renderToken(ais, tree, switch_node.switch_token, Space.Space); // switch | |
| 740 | // try renderToken(ais, tree, tree.nextToken(switch_node.switch_token), Space.None); // ( | |
| 741 | ||
| 742 | // const rparen = tree.nextToken(switch_node.expr.lastToken()); | |
| 743 | // const lbrace = tree.nextToken(rparen); | |
| 744 | ||
| 745 | // if (switch_node.cases_len == 0) { | |
| 746 | // try renderExpression(ais, tree, switch_node.expr, Space.None); | |
| 747 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 748 | // try renderToken(ais, tree, lbrace, Space.None); // lbrace | |
| 749 | // return renderToken(ais, tree, switch_node.rbrace, space); // rbrace | |
| 750 | // } | |
| 751 | ||
| 752 | // try renderExpression(ais, tree, switch_node.expr, Space.None); | |
| 753 | // try renderToken(ais, tree, rparen, Space.Space); // ) | |
| 754 | ||
| 755 | // { | |
| 756 | // ais.pushIndentNextLine(); | |
| 757 | // defer ais.popIndent(); | |
| 758 | // try renderToken(ais, tree, lbrace, Space.Newline); // lbrace | |
| 759 | ||
| 760 | // const cases = switch_node.cases(); | |
| 761 | // for (cases) |node, i| { | |
| 762 | // try renderExpression(ais, tree, node, Space.Comma); | |
| 763 | ||
| 764 | // if (i + 1 < cases.len) { | |
| 765 | // try renderExtraNewline(ais, tree, cases[i + 1]); | |
| 766 | // } | |
| 767 | // } | |
| 768 | // } | |
| 769 | ||
| 770 | // return renderToken(ais, tree, switch_node.rbrace, space); // rbrace | |
| 771 | //}, | |
| 772 | ||
| 773 | .SwitchCaseOne => unreachable, // TODO | |
| 774 | .SwitchCaseMulti => unreachable, // TODO | |
| 775 | //.SwitchCase => { | |
| 776 | // const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base); | |
| 777 | ||
| 778 | // assert(switch_case.items_len != 0); | |
| 779 | // const src_has_trailing_comma = blk: { | |
| 780 | // const last_node = switch_case.items()[switch_case.items_len - 1]; | |
| 781 | // const maybe_comma = tree.nextToken(last_node.lastToken()); | |
| 782 | // break :blk tree.token_tags[maybe_comma] == .Comma; | |
| 783 | // }; | |
| 784 | ||
| 785 | // if (switch_case.items_len == 1 or !src_has_trailing_comma) { | |
| 786 | // const items = switch_case.items(); | |
| 787 | // for (items) |node, i| { | |
| 788 | // if (i + 1 < items.len) { | |
| 789 | // try renderExpression(ais, tree, node, Space.None); | |
| 790 | ||
| 791 | // const comma_token = tree.nextToken(node.lastToken()); | |
| 792 | // try renderToken(ais, tree, comma_token, Space.Space); // , | |
| 793 | // try renderExtraNewline(ais, tree, items[i + 1]); | |
| 794 | // } else { | |
| 795 | // try renderExpression(ais, tree, node, Space.Space); | |
| 796 | // } | |
| 797 | // } | |
| 798 | // } else { | |
| 799 | // const items = switch_case.items(); | |
| 800 | // for (items) |node, i| { | |
| 801 | // if (i + 1 < items.len) { | |
| 802 | // try renderExpression(ais, tree, node, Space.None); | |
| 803 | ||
| 804 | // const comma_token = tree.nextToken(node.lastToken()); | |
| 805 | // try renderToken(ais, tree, comma_token, Space.Newline); // , | |
| 806 | // try renderExtraNewline(ais, tree, items[i + 1]); | |
| 807 | // } else { | |
| 808 | // try renderExpression(ais, tree, node, Space.Comma); | |
| 809 | // } | |
| 810 | // } | |
| 811 | // } | |
| 812 | ||
| 813 | // try renderToken(ais, tree, switch_case.arrow_token, Space.Space); // => | |
| 814 | ||
| 815 | // if (switch_case.payload) |payload| { | |
| 816 | // try renderExpression(ais, tree, payload, Space.Space); | |
| 817 | // } | |
| 659 | .Switch, | |
| 660 | .SwitchComma, | |
| 661 | => { | |
| 662 | const switch_token = main_tokens[node]; | |
| 663 | const condition = datas[node].lhs; | |
| 664 | const extra = tree.extraData(datas[node].rhs, ast.Node.SubRange); | |
| 665 | const cases = tree.extra_data[extra.start..extra.end]; | |
| 666 | const rparen = tree.lastToken(condition) + 1; | |
| 667 | ||
| 668 | try renderToken(ais, tree, switch_token, .Space); // switch keyword | |
| 669 | try renderToken(ais, tree, switch_token + 1, .None); // lparen | |
| 670 | try renderExpression(ais, tree, condition, .None); // condtion expression | |
| 671 | try renderToken(ais, tree, rparen, .Space); // rparen | |
| 672 | ||
| 673 | if (cases.len == 0) { | |
| 674 | try renderToken(ais, tree, rparen + 1, .None); // lbrace | |
| 675 | try renderToken(ais, tree, rparen + 2, space); // rbrace | |
| 676 | } else { | |
| 677 | try renderToken(ais, tree, rparen + 1, .Newline); // lbrace | |
| 678 | ais.pushIndent(); | |
| 679 | try renderExpression(ais, tree, cases[0], .Comma); | |
| 680 | for (cases[1..]) |case| { | |
| 681 | try renderExtraNewline(ais, tree, case); | |
| 682 | try renderExpression(ais, tree, case, .Comma); | |
| 683 | } | |
| 684 | ais.popIndent(); | |
| 685 | try renderToken(ais, tree, tree.lastToken(node), space); // rbrace | |
| 686 | } | |
| 687 | }, | |
| 818 | 688 | |
| 819 | // return renderExpression(ais, tree, switch_case.expr, space); | |
| 820 | //}, | |
| 689 | .SwitchCaseOne => try renderSwitchCase(ais, tree, tree.switchCaseOne(node), space), | |
| 690 | .SwitchCase => try renderSwitchCase(ais, tree, tree.switchCase(node), space), | |
| 821 | 691 | |
| 822 | 692 | .WhileSimple => unreachable, // TODO |
| 823 | 693 | .WhileCont => unreachable, // TODO |
| ... | ... | @@ -1745,16 +1615,64 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.Full.FnProto, space: S |
| 1745 | 1615 | return renderExpression(ais, tree, fn_proto.ast.return_type, space); |
| 1746 | 1616 | } |
| 1747 | 1617 | |
| 1618 | fn renderSwitchCase( | |
| 1619 | ais: *Ais, | |
| 1620 | tree: ast.Tree, | |
| 1621 | switch_case: ast.Full.SwitchCase, | |
| 1622 | space: Space, | |
| 1623 | ) Error!void { | |
| 1624 | const token_tags = tree.tokens.items(.tag); | |
| 1625 | const trailing_comma = token_tags[switch_case.ast.arrow_token - 1] == .Comma; | |
| 1626 | ||
| 1627 | // Render everything before the arrow | |
| 1628 | if (switch_case.ast.values.len == 0) { | |
| 1629 | try renderToken(ais, tree, switch_case.ast.arrow_token - 1, .Space); // else keyword | |
| 1630 | } else if (switch_case.ast.values.len == 1) { | |
| 1631 | // render on one line and drop the trailing comma if any | |
| 1632 | try renderExpression(ais, tree, switch_case.ast.values[0], .Space); | |
| 1633 | } else if (trailing_comma) { | |
| 1634 | // Render each value on a new line | |
| 1635 | try renderExpression(ais, tree, switch_case.ast.values[0], .Comma); | |
| 1636 | for (switch_case.ast.values[1..]) |value_expr| { | |
| 1637 | try renderExtraNewline(ais, tree, value_expr); | |
| 1638 | try renderExpression(ais, tree, value_expr, .Comma); | |
| 1639 | } | |
| 1640 | } else { | |
| 1641 | // Render on one line | |
| 1642 | for (switch_case.ast.values) |value_expr| { | |
| 1643 | try renderExpression(ais, tree, value_expr, .CommaSpace); | |
| 1644 | } | |
| 1645 | } | |
| 1646 | ||
| 1647 | // Render the arrow and everything after it | |
| 1648 | try renderToken(ais, tree, switch_case.ast.arrow_token, .Space); | |
| 1649 | ||
| 1650 | if (switch_case.payload_token) |payload_token| { | |
| 1651 | try renderToken(ais, tree, payload_token - 1, .None); // pipe | |
| 1652 | if (token_tags[payload_token] == .Asterisk) { | |
| 1653 | try renderToken(ais, tree, payload_token, .None); // asterisk | |
| 1654 | try renderToken(ais, tree, payload_token + 1, .None); // identifier | |
| 1655 | try renderToken(ais, tree, payload_token + 2, .Space); // pipe | |
| 1656 | } else { | |
| 1657 | try renderToken(ais, tree, payload_token, .None); // identifier | |
| 1658 | try renderToken(ais, tree, payload_token + 1, .Space); // pipe | |
| 1659 | } | |
| 1660 | } | |
| 1661 | ||
| 1662 | try renderExpression(ais, tree, switch_case.ast.target_expr, space); | |
| 1663 | } | |
| 1664 | ||
| 1748 | 1665 | fn renderBlock( |
| 1749 | 1666 | ais: *Ais, |
| 1750 | 1667 | tree: ast.Tree, |
| 1751 | lbrace: ast.TokenIndex, | |
| 1668 | block_node: ast.Node.Index, | |
| 1752 | 1669 | statements: []const ast.Node.Index, |
| 1753 | 1670 | space: Space, |
| 1754 | 1671 | ) Error!void { |
| 1755 | 1672 | const token_tags = tree.tokens.items(.tag); |
| 1756 | 1673 | const node_tags = tree.nodes.items(.tag); |
| 1757 | 1674 | const nodes_data = tree.nodes.items(.data); |
| 1675 | const lbrace = tree.nodes.items(.main_token)[block_node]; | |
| 1758 | 1676 | |
| 1759 | 1677 | if (token_tags[lbrace - 1] == .Colon and |
| 1760 | 1678 | token_tags[lbrace - 2] == .Identifier) |
| ... | ... | @@ -1783,15 +1701,8 @@ fn renderBlock( |
| 1783 | 1701 | } |
| 1784 | 1702 | } |
| 1785 | 1703 | ais.popIndent(); |
| 1786 | // The rbrace could be +1 or +2 from the last token of the last | |
| 1787 | // statement in the block because lastToken() does not count semicolons. | |
| 1788 | const maybe_rbrace = tree.lastToken(statements[statements.len - 1]) + 1; | |
| 1789 | if (token_tags[maybe_rbrace] == .RBrace) { | |
| 1790 | return renderToken(ais, tree, maybe_rbrace, space); | |
| 1791 | } else { | |
| 1792 | assert(token_tags[maybe_rbrace + 1] == .RBrace); | |
| 1793 | return renderToken(ais, tree, maybe_rbrace + 1, space); | |
| 1794 | } | |
| 1704 | ||
| 1705 | try renderToken(ais, tree, tree.lastToken(block_node), space); // rbrace | |
| 1795 | 1706 | } |
| 1796 | 1707 | |
| 1797 | 1708 | // TODO: handle comments between fields |