| ... | ... | @@ -498,18 +498,17 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 498 | 498 | } |
| 499 | 499 | }, |
| 500 | 500 | |
| 501 | | .Continue => unreachable, // TODO |
| 502 | | //.Continue => { |
| 503 | | // const flow_expr = base.castTag(.Continue).?; |
| 504 | | // if (flow_expr.getLabel()) |label| { |
| 505 | | // try renderToken(ais, tree, flow_expr.ltoken, Space.Space); // continue |
| 506 | | // const colon = tree.nextToken(flow_expr.ltoken); |
| 507 | | // try renderToken(ais, tree, colon, Space.None); // : |
| 508 | | // return renderToken(ais, tree, label, space); // label |
| 509 | | // } else { |
| 510 | | // return renderToken(ais, tree, flow_expr.ltoken, space); // continue |
| 511 | | // } |
| 512 | | //}, |
| 501 | .Continue => { |
| 502 | const main_token = main_tokens[node]; |
| 503 | const label = datas[node].lhs; |
| 504 | if (label != 0) { |
| 505 | try renderToken(ais, tree, main_token, .Space); // continue |
| 506 | try renderToken(ais, tree, label - 1, .None); // : |
| 507 | return renderToken(ais, tree, label, space); // label |
| 508 | } else { |
| 509 | return renderToken(ais, tree, main_token, space); // continue |
| 510 | } |
| 511 | }, |
| 513 | 512 | |
| 514 | 513 | .Return => { |
| 515 | 514 | if (datas[node].lhs != 0) { |
| ... | ... | @@ -664,17 +663,16 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 664 | 663 | if (cases.len == 0) { |
| 665 | 664 | try renderToken(ais, tree, rparen + 1, .None); // lbrace |
| 666 | 665 | return renderToken(ais, tree, rparen + 2, space); // rbrace |
| 667 | | } else { |
| 668 | | try renderToken(ais, tree, rparen + 1, .Newline); // lbrace |
| 669 | | ais.pushIndent(); |
| 670 | | try renderExpression(ais, tree, cases[0], .Comma); |
| 671 | | for (cases[1..]) |case| { |
| 672 | | try renderExtraNewline(ais, tree, case); |
| 673 | | try renderExpression(ais, tree, case, .Comma); |
| 674 | | } |
| 675 | | ais.popIndent(); |
| 676 | | return renderToken(ais, tree, tree.lastToken(node), space); // rbrace |
| 677 | 666 | } |
| 667 | try renderToken(ais, tree, rparen + 1, .Newline); // lbrace |
| 668 | ais.pushIndent(); |
| 669 | try renderExpression(ais, tree, cases[0], .Comma); |
| 670 | for (cases[1..]) |case| { |
| 671 | try renderExtraNewline(ais, tree, case); |
| 672 | try renderExpression(ais, tree, case, .Comma); |
| 673 | } |
| 674 | ais.popIndent(); |
| 675 | return renderToken(ais, tree, tree.lastToken(node), space); // rbrace |
| 678 | 676 | }, |
| 679 | 677 | |
| 680 | 678 | .SwitchCaseOne => return renderSwitchCase(ais, tree, tree.switchCaseOne(node), space), |
| ... | ... | @@ -683,59 +681,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 683 | 681 | .WhileSimple => return renderWhile(ais, tree, tree.whileSimple(node), space), |
| 684 | 682 | .WhileCont => return renderWhile(ais, tree, tree.whileCont(node), space), |
| 685 | 683 | .While => return renderWhile(ais, tree, tree.whileFull(node), space), |
| 686 | | |
| 687 | | .ForSimple => unreachable, // TODO |
| 688 | | .For => unreachable, // TODO |
| 689 | | //.For => { |
| 690 | | // const for_node = @fieldParentPtr(ast.Node.For, "base", base); |
| 691 | | |
| 692 | | // if (for_node.label) |label| { |
| 693 | | // try renderToken(ais, tree, label, Space.None); // label |
| 694 | | // try renderToken(ais, tree, tree.nextToken(label), Space.Space); // : |
| 695 | | // } |
| 696 | | |
| 697 | | // if (for_node.inline_token) |inline_token| { |
| 698 | | // try renderToken(ais, tree, inline_token, Space.Space); // inline |
| 699 | | // } |
| 700 | | |
| 701 | | // try renderToken(ais, tree, for_node.for_token, Space.Space); // for |
| 702 | | // try renderToken(ais, tree, tree.nextToken(for_node.for_token), Space.None); // ( |
| 703 | | // try renderExpression(ais, tree, for_node.array_expr, Space.None); |
| 704 | | |
| 705 | | // const rparen = tree.nextToken(for_node.array_expr.lastToken()); |
| 706 | | |
| 707 | | // const body_is_block = for_node.body.tag.isBlock(); |
| 708 | | // const src_one_line_to_body = !body_is_block and tree.tokensOnSameLine(rparen, for_node.body.firstToken()); |
| 709 | | // const body_on_same_line = body_is_block or src_one_line_to_body; |
| 710 | | |
| 711 | | // try renderToken(ais, tree, rparen, Space.Space); // ) |
| 712 | | |
| 713 | | // const space_after_payload = if (body_on_same_line) Space.Space else Space.Newline; |
| 714 | | // try renderExpression(ais, tree, for_node.payload, space_after_payload); // |x| |
| 715 | | |
| 716 | | // const space_after_body = blk: { |
| 717 | | // if (for_node.@"else") |@"else"| { |
| 718 | | // const src_one_line_to_else = tree.tokensOnSameLine(rparen, @"else".firstToken()); |
| 719 | | // if (body_is_block or src_one_line_to_else) { |
| 720 | | // break :blk Space.Space; |
| 721 | | // } else { |
| 722 | | // break :blk Space.Newline; |
| 723 | | // } |
| 724 | | // } else { |
| 725 | | // break :blk space; |
| 726 | | // } |
| 727 | | // }; |
| 728 | | |
| 729 | | // { |
| 730 | | // if (!body_on_same_line) ais.pushIndent(); |
| 731 | | // defer if (!body_on_same_line) ais.popIndent(); |
| 732 | | // try renderExpression(ais, tree, for_node.body, space_after_body); // { body } |
| 733 | | // } |
| 734 | | |
| 735 | | // if (for_node.@"else") |@"else"| { |
| 736 | | // return renderExpression(ais, tree, &@"else".base, space); // else |
| 737 | | // } |
| 738 | | //}, |
| 684 | .ForSimple => return renderWhile(ais, tree, tree.forSimple(node), space), |
| 685 | .For => return renderWhile(ais, tree, tree.forFull(node), space), |
| 739 | 686 | |
| 740 | 687 | .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space), |
| 741 | 688 | .If => return renderIf(ais, tree, tree.ifFull(node), space), |
| ... | ... | @@ -1041,7 +988,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error |
| 1041 | 988 | }, space); |
| 1042 | 989 | } |
| 1043 | 990 | |
| 1044 | | /// Note that this function is additionally used to render if expressions, with |
| 991 | /// Note that this function is additionally used to render if and for expressions, with |
| 1045 | 992 | /// respective values set to null. |
| 1046 | 993 | fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void { |
| 1047 | 994 | const node_tags = tree.nodes.items(.tag); |
| ... | ... | @@ -1061,21 +1008,31 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa |
| 1061 | 1008 | try renderExpression(ais, tree, while_node.ast.cond_expr, .None); // condition |
| 1062 | 1009 | |
| 1063 | 1010 | if (nodeIsBlock(node_tags[while_node.ast.then_expr])) { |
| 1064 | | const payload_space: Space = if (while_node.ast.cont_expr != 0) .Space else .BlockStart; |
| 1065 | 1011 | if (while_node.payload_token) |payload_token| { |
| 1066 | 1012 | try renderToken(ais, tree, payload_token - 2, .Space); // ) |
| 1067 | 1013 | try renderToken(ais, tree, payload_token - 1, .None); // | |
| 1068 | | if (token_tags[payload_token] == .Asterisk) { |
| 1069 | | try renderToken(ais, tree, payload_token, .None); // * |
| 1070 | | try renderToken(ais, tree, payload_token + 1, .None); // identifier |
| 1071 | | try renderToken(ais, tree, payload_token + 2, payload_space); // | |
| 1072 | | } else { |
| 1073 | | try renderToken(ais, tree, payload_token, .None); // identifier |
| 1074 | | try renderToken(ais, tree, payload_token + 1, payload_space); // | |
| 1075 | | } |
| 1014 | const ident = blk: { |
| 1015 | if (token_tags[payload_token] == .Asterisk) { |
| 1016 | try renderToken(ais, tree, payload_token, .None); // * |
| 1017 | break :blk payload_token + 1; |
| 1018 | } else { |
| 1019 | break :blk payload_token; |
| 1020 | } |
| 1021 | }; |
| 1022 | try renderToken(ais, tree, ident, .None); // identifier |
| 1023 | const pipe = blk: { |
| 1024 | if (token_tags[ident + 1] == .Comma) { |
| 1025 | try renderToken(ais, tree, ident + 1, .Space); // , |
| 1026 | try renderToken(ais, tree, ident + 2, .None); // index |
| 1027 | break :blk payload_token + 3; |
| 1028 | } else { |
| 1029 | break :blk ident + 1; |
| 1030 | } |
| 1031 | }; |
| 1032 | try renderToken(ais, tree, pipe, .Space); // | |
| 1076 | 1033 | } else { |
| 1077 | 1034 | const rparen = tree.lastToken(while_node.ast.cond_expr) + 1; |
| 1078 | | try renderToken(ais, tree, rparen, payload_space); // ) |
| 1035 | try renderToken(ais, tree, rparen, .Space); // ) |
| 1079 | 1036 | } |
| 1080 | 1037 | if (while_node.ast.cont_expr != 0) { |
| 1081 | 1038 | const rparen = tree.lastToken(while_node.ast.cont_expr) + 1; |
| ... | ... | @@ -1083,7 +1040,7 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa |
| 1083 | 1040 | try renderToken(ais, tree, lparen - 1, .Space); // : |
| 1084 | 1041 | try renderToken(ais, tree, lparen, .None); // lparen |
| 1085 | 1042 | try renderExpression(ais, tree, while_node.ast.cont_expr, .None); |
| 1086 | | try renderToken(ais, tree, rparen, .BlockStart); // rparen |
| 1043 | try renderToken(ais, tree, rparen, .Space); // rparen |
| 1087 | 1044 | } |
| 1088 | 1045 | if (while_node.ast.else_expr != 0) { |
| 1089 | 1046 | try renderExpression(ais, tree, while_node.ast.then_expr, Space.Space); |
| ... | ... | @@ -1104,15 +1061,31 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa |
| 1104 | 1061 | const src_has_newline = !tree.tokensOnSameLine(rparen, last_then_token); |
| 1105 | 1062 | |
| 1106 | 1063 | if (src_has_newline) { |
| 1107 | | const payload_space: Space = if (while_node.ast.cont_expr != 0) .Space else .Newline; |
| 1108 | 1064 | if (while_node.payload_token) |payload_token| { |
| 1109 | 1065 | try renderToken(ais, tree, payload_token - 2, .Space); // ) |
| 1110 | 1066 | try renderToken(ais, tree, payload_token - 1, .None); // | |
| 1111 | | try renderToken(ais, tree, payload_token, .None); // identifier |
| 1112 | | try renderToken(ais, tree, payload_token + 1, payload_space); // | |
| 1067 | const ident = blk: { |
| 1068 | if (token_tags[payload_token] == .Asterisk) { |
| 1069 | try renderToken(ais, tree, payload_token, .None); // * |
| 1070 | break :blk payload_token + 1; |
| 1071 | } else { |
| 1072 | break :blk payload_token; |
| 1073 | } |
| 1074 | }; |
| 1075 | try renderToken(ais, tree, ident, .None); // identifier |
| 1076 | const pipe = blk: { |
| 1077 | if (token_tags[ident + 1] == .Comma) { |
| 1078 | try renderToken(ais, tree, ident + 1, .Space); // , |
| 1079 | try renderToken(ais, tree, ident + 2, .None); // index |
| 1080 | break :blk payload_token + 3; |
| 1081 | } else { |
| 1082 | break :blk ident + 1; |
| 1083 | } |
| 1084 | }; |
| 1085 | try renderToken(ais, tree, pipe, .Newline); // | |
| 1113 | 1086 | } else { |
| 1114 | 1087 | ais.pushIndent(); |
| 1115 | | try renderToken(ais, tree, rparen, payload_space); // ) |
| 1088 | try renderToken(ais, tree, rparen, .Newline); // ) |
| 1116 | 1089 | ais.popIndent(); |
| 1117 | 1090 | } |
| 1118 | 1091 | if (while_node.ast.cont_expr != 0) { |
| ... | ... | @@ -1164,14 +1137,25 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa |
| 1164 | 1137 | assert(payload_token - 2 == rparen); |
| 1165 | 1138 | try renderToken(ais, tree, payload_token - 2, .Space); // ) |
| 1166 | 1139 | try renderToken(ais, tree, payload_token - 1, .None); // | |
| 1167 | | if (token_tags[payload_token] == .Asterisk) { |
| 1168 | | try renderToken(ais, tree, payload_token, .None); // * |
| 1169 | | try renderToken(ais, tree, payload_token + 1, .None); // identifier |
| 1170 | | try renderToken(ais, tree, payload_token + 2, .Space); // | |
| 1171 | | } else { |
| 1172 | | try renderToken(ais, tree, payload_token, .None); // identifier |
| 1173 | | try renderToken(ais, tree, payload_token + 1, .Space); // | |
| 1174 | | } |
| 1140 | const ident = blk: { |
| 1141 | if (token_tags[payload_token] == .Asterisk) { |
| 1142 | try renderToken(ais, tree, payload_token, .None); // * |
| 1143 | break :blk payload_token + 1; |
| 1144 | } else { |
| 1145 | break :blk payload_token; |
| 1146 | } |
| 1147 | }; |
| 1148 | try renderToken(ais, tree, ident, .None); // identifier |
| 1149 | const pipe = blk: { |
| 1150 | if (token_tags[ident + 1] == .Comma) { |
| 1151 | try renderToken(ais, tree, ident + 1, .Space); // , |
| 1152 | try renderToken(ais, tree, ident + 2, .None); // index |
| 1153 | break :blk payload_token + 3; |
| 1154 | } else { |
| 1155 | break :blk ident + 1; |
| 1156 | } |
| 1157 | }; |
| 1158 | try renderToken(ais, tree, pipe, .Space); // | |
| 1175 | 1159 | } else { |
| 1176 | 1160 | try renderToken(ais, tree, rparen, .Space); // ) |
| 1177 | 1161 | } |
| ... | ... | @@ -1952,18 +1936,9 @@ const Space = enum { |
| 1952 | 1936 | Semicolon, |
| 1953 | 1937 | /// Skips writing the possible line comment after the token. |
| 1954 | 1938 | NoComment, |
| 1955 | | /// Intended when rendering lbrace tokens. Depending on whether the line is |
| 1956 | | /// "over indented", will output a newline or a single space afterwards. |
| 1957 | | /// See `std.io.AutoIndentingStream` for the definition of "over indented". |
| 1958 | | BlockStart, |
| 1959 | 1939 | }; |
| 1960 | 1940 | |
| 1961 | 1941 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { |
| 1962 | | if (space == Space.BlockStart) { |
| 1963 | | const new_space: Space = if (ais.isLineOverIndented()) .Newline else .Space; |
| 1964 | | return renderToken(ais, tree, token_index, new_space); |
| 1965 | | } |
| 1966 | | |
| 1967 | 1942 | const token_tags = tree.tokens.items(.tag); |
| 1968 | 1943 | const token_starts = tree.tokens.items(.start); |
| 1969 | 1944 | |
| ... | ... | @@ -2020,7 +1995,6 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp |
| 2020 | 1995 | try ais.insertNewline(); |
| 2021 | 1996 | } |
| 2022 | 1997 | }, |
| 2023 | | .BlockStart => unreachable, |
| 2024 | 1998 | } |
| 2025 | 1999 | } |
| 2026 | 2000 | |
| ... | ... | @@ -2069,6 +2043,7 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool { |
| 2069 | 2043 | .WhileSimple, |
| 2070 | 2044 | .WhileCont, |
| 2071 | 2045 | .Switch, |
| 2046 | .SwitchComma, |
| 2072 | 2047 | => true, |
| 2073 | 2048 | else => false, |
| 2074 | 2049 | }; |