| ... | @@ -719,145 +719,16 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -719,145 +719,16 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 719 | // return renderToken(ais, tree, rtoken, space); | 719 | // return renderToken(ais, tree, rtoken, space); |
| 720 | //}, | 720 | //}, |
| 721 | | 721 | |
| 722 | .StructInitOne => unreachable, // TODO | 722 | .StructInitOne => { |
| 723 | .StructInitDotTwo => unreachable, // TODO | 723 | var fields: [1]ast.Node.Index = undefined; |
| 724 | .StructInitDot => unreachable, // TODO | 724 | return renderStructInit(ais, tree, tree.structInitOne(&fields, node), space); |
| 725 | .StructInit => unreachable, // TODO | 725 | }, |
| 726 | //.StructInitializer, .StructInitializerDot => { | 726 | .StructInitDotTwo, .StructInitDotTwoComma => { |
| 727 | // var rtoken: ast.TokenIndex = undefined; | 727 | var fields: [2]ast.Node.Index = undefined; |
| 728 | // var field_inits: []ast.Node.Index = undefined; | 728 | return renderStructInit(ais, tree, tree.structInitDotTwo(&fields, node), space); |
| 729 | // const lhs: union(enum) { dot: ast.TokenIndex, node: ast.Node.Index } = switch (base.tag) { | 729 | }, |
| 730 | // .StructInitializerDot => blk: { | 730 | .StructInitDot => return renderStructInit(ais, tree, tree.structInitDot(node), space), |
| 731 | // const casted = @fieldParentPtr(ast.Node.StructInitializerDot, "base", base); | 731 | .StructInit => return renderStructInit(ais, tree, tree.structInit(node), space), |
| 732 | // rtoken = casted.rtoken; | | |
| 733 | // field_inits = casted.list(); | | |
| 734 | // break :blk .{ .dot = casted.dot }; | | |
| 735 | // }, | | |
| 736 | // .StructInitializer => blk: { | | |
| 737 | // const casted = @fieldParentPtr(ast.Node.StructInitializer, "base", base); | | |
| 738 | // rtoken = casted.rtoken; | | |
| 739 | // field_inits = casted.list(); | | |
| 740 | // break :blk .{ .node = casted.lhs }; | | |
| 741 | // }, | | |
| 742 | // else => unreachable, | | |
| 743 | // }; | | |
| 744 | | | |
| 745 | // const lbrace = switch (lhs) { | | |
| 746 | // .dot => |dot| tree.nextToken(dot), | | |
| 747 | // .node => |node| tree.nextToken(node.lastToken()), | | |
| 748 | // }; | | |
| 749 | | | |
| 750 | // if (field_inits.len == 0) { | | |
| 751 | // switch (lhs) { | | |
| 752 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | | |
| 753 | // .node => |node| try renderExpression(ais, tree, node, Space.None), | | |
| 754 | // } | | |
| 755 | | | |
| 756 | // { | | |
| 757 | // ais.pushIndentNextLine(); | | |
| 758 | // defer ais.popIndent(); | | |
| 759 | // try renderToken(ais, tree, lbrace, Space.None); | | |
| 760 | // } | | |
| 761 | | | |
| 762 | // return renderToken(ais, tree, rtoken, space); | | |
| 763 | // } | | |
| 764 | | | |
| 765 | // const src_has_trailing_comma = blk: { | | |
| 766 | // const maybe_comma = tree.prevToken(rtoken); | | |
| 767 | // break :blk tree.token_tags[maybe_comma] == .Comma; | | |
| 768 | // }; | | |
| 769 | | | |
| 770 | // const src_same_line = blk: { | | |
| 771 | // const loc = tree.tokenLocation(tree.token_locs[lbrace].end, rtoken); | | |
| 772 | // break :blk loc.line == 0; | | |
| 773 | // }; | | |
| 774 | | | |
| 775 | // const expr_outputs_one_line = blk: { | | |
| 776 | // // render field expressions until a LF is found | | |
| 777 | // for (field_inits) |field_init| { | | |
| 778 | // var find_stream = std.io.findByteWriter('\n', std.io.null_writer); | | |
| 779 | // var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, find_stream.writer()); | | |
| 780 | | | |
| 781 | // try renderExpression(allocator, &auto_indenting_stream, tree, field_init, Space.None); | | |
| 782 | // if (find_stream.byte_found) break :blk false; | | |
| 783 | // } | | |
| 784 | // break :blk true; | | |
| 785 | // }; | | |
| 786 | | | |
| 787 | // if (field_inits.len == 1) blk: { | | |
| 788 | // if (field_inits[0].cast(ast.Node.FieldInitializer)) |field_init| { | | |
| 789 | // switch (field_init.expr.tag) { | | |
| 790 | // .StructInitializer, | | |
| 791 | // .StructInitializerDot, | | |
| 792 | // => break :blk, | | |
| 793 | // else => {}, | | |
| 794 | // } | | |
| 795 | // } | | |
| 796 | | | |
| 797 | // // if the expression outputs to multiline, make this struct multiline | | |
| 798 | // if (!expr_outputs_one_line or src_has_trailing_comma) { | | |
| 799 | // break :blk; | | |
| 800 | // } | | |
| 801 | | | |
| 802 | // switch (lhs) { | | |
| 803 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | | |
| 804 | // .node => |node| try renderExpression(ais, tree, node, Space.None), | | |
| 805 | // } | | |
| 806 | // try renderToken(ais, tree, lbrace, Space.Space); | | |
| 807 | // try renderExpression(ais, tree, field_inits[0], Space.Space); | | |
| 808 | // return renderToken(ais, tree, rtoken, space); | | |
| 809 | // } | | |
| 810 | | | |
| 811 | // if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) { | | |
| 812 | // // render all on one line, no trailing comma | | |
| 813 | // switch (lhs) { | | |
| 814 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | | |
| 815 | // .node => |node| try renderExpression(ais, tree, node, Space.None), | | |
| 816 | // } | | |
| 817 | // try renderToken(ais, tree, lbrace, Space.Space); | | |
| 818 | | | |
| 819 | // for (field_inits) |field_init, i| { | | |
| 820 | // if (i + 1 < field_inits.len) { | | |
| 821 | // try renderExpression(ais, tree, field_init, Space.None); | | |
| 822 | | | |
| 823 | // const comma = tree.nextToken(field_init.lastToken()); | | |
| 824 | // try renderToken(ais, tree, comma, Space.Space); | | |
| 825 | // } else { | | |
| 826 | // try renderExpression(ais, tree, field_init, Space.Space); | | |
| 827 | // } | | |
| 828 | // } | | |
| 829 | | | |
| 830 | // return renderToken(ais, tree, rtoken, space); | | |
| 831 | // } | | |
| 832 | | | |
| 833 | // { | | |
| 834 | // switch (lhs) { | | |
| 835 | // .dot => |dot| try renderToken(ais, tree, dot, Space.None), | | |
| 836 | // .node => |node| try renderExpression(ais, tree, node, Space.None), | | |
| 837 | // } | | |
| 838 | | | |
| 839 | // ais.pushIndentNextLine(); | | |
| 840 | // defer ais.popIndent(); | | |
| 841 | | | |
| 842 | // try renderToken(ais, tree, lbrace, Space.Newline); | | |
| 843 | | | |
| 844 | // for (field_inits) |field_init, i| { | | |
| 845 | // if (i + 1 < field_inits.len) { | | |
| 846 | // const next_field_init = field_inits[i + 1]; | | |
| 847 | // try renderExpression(ais, tree, field_init, Space.None); | | |
| 848 | | | |
| 849 | // const comma = tree.nextToken(field_init.lastToken()); | | |
| 850 | // try renderToken(ais, tree, comma, Space.Newline); | | |
| 851 | | | |
| 852 | // try renderExtraNewline(ais, tree, next_field_init); | | |
| 853 | // } else { | | |
| 854 | // try renderExpression(ais, tree, field_init, Space.Comma); | | |
| 855 | // } | | |
| 856 | // } | | |
| 857 | // } | | |
| 858 | | | |
| 859 | // return renderToken(ais, tree, rtoken, space); | | |
| 860 | //}, | | |
| 861 | | 732 | |
| 862 | .CallOne => unreachable, // TODO | 733 | .CallOne => unreachable, // TODO |
| 863 | .Call => { | 734 | .Call => { |
| ... | @@ -1078,9 +949,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1078,9 +949,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1078 | // { | 949 | // { |
| 1079 | // ais.pushIndentNextLine(); | 950 | // ais.pushIndentNextLine(); |
| 1080 | // defer ais.popIndent(); | 951 | // defer ais.popIndent(); |
| 1081 | // try renderToken(ais, tree, container_decl.lbrace_token, Space.None); // { | 952 | // try renderToken(ais, tree, container_decl.lbrace_token, Space.None); // lbrace |
| 1082 | // } | 953 | // } |
| 1083 | // return renderToken(ais, tree, container_decl.rbrace_token, space); // } | 954 | // return renderToken(ais, tree, container_decl.rbrace_token, space); // rbrace |
| 1084 | // } | 955 | // } |
| 1085 | | 956 | |
| 1086 | // const src_has_trailing_comma = blk: { | 957 | // const src_has_trailing_comma = blk: { |
| ... | @@ -1113,7 +984,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1113,7 +984,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1113 | // // One declaration per line | 984 | // // One declaration per line |
| 1114 | // ais.pushIndentNextLine(); | 985 | // ais.pushIndentNextLine(); |
| 1115 | // defer ais.popIndent(); | 986 | // defer ais.popIndent(); |
| 1116 | // try renderToken(ais, tree, container_decl.lbrace_token, .Newline); // { | 987 | // try renderToken(ais, tree, container_decl.lbrace_token, .Newline); // lbrace |
| 1117 | | 988 | |
| 1118 | // for (fields_and_decls) |decl, i| { | 989 | // for (fields_and_decls) |decl, i| { |
| 1119 | // try renderContainerDecl(allocator, ais, tree, decl, .Newline); | 990 | // try renderContainerDecl(allocator, ais, tree, decl, .Newline); |
| ... | @@ -1125,7 +996,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1125,7 +996,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1125 | // } else if (src_has_newline) { | 996 | // } else if (src_has_newline) { |
| 1126 | // // All the declarations on the same line, but place the items on | 997 | // // All the declarations on the same line, but place the items on |
| 1127 | // // their own line | 998 | // // their own line |
| 1128 | // try renderToken(ais, tree, container_decl.lbrace_token, .Newline); // { | 999 | // try renderToken(ais, tree, container_decl.lbrace_token, .Newline); // lbrace |
| 1129 | | 1000 | |
| 1130 | // ais.pushIndent(); | 1001 | // ais.pushIndent(); |
| 1131 | // defer ais.popIndent(); | 1002 | // defer ais.popIndent(); |
| ... | @@ -1136,14 +1007,14 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1136,14 +1007,14 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1136 | // } | 1007 | // } |
| 1137 | // } else { | 1008 | // } else { |
| 1138 | // // All the declarations on the same line | 1009 | // // All the declarations on the same line |
| 1139 | // try renderToken(ais, tree, container_decl.lbrace_token, .Space); // { | 1010 | // try renderToken(ais, tree, container_decl.lbrace_token, .Space); // lbrace |
| 1140 | | 1011 | |
| 1141 | // for (fields_and_decls) |decl| { | 1012 | // for (fields_and_decls) |decl| { |
| 1142 | // try renderContainerDecl(allocator, ais, tree, decl, .Space); | 1013 | // try renderContainerDecl(allocator, ais, tree, decl, .Space); |
| 1143 | // } | 1014 | // } |
| 1144 | // } | 1015 | // } |
| 1145 | | 1016 | |
| 1146 | // return renderToken(ais, tree, container_decl.rbrace_token, space); // } | 1017 | // return renderToken(ais, tree, container_decl.rbrace_token, space); // rbrace |
| 1147 | //}, | 1018 | //}, |
| 1148 | | 1019 | |
| 1149 | .ErrorSetDecl => unreachable, // TODO | 1020 | .ErrorSetDecl => unreachable, // TODO |
| ... | @@ -1170,9 +1041,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1170,9 +1041,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1170 | // } | 1041 | // } |
| 1171 | | 1042 | |
| 1172 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error | 1043 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error |
| 1173 | // try renderToken(ais, tree, lbrace, Space.None); // { | 1044 | // try renderToken(ais, tree, lbrace, Space.None); // lbrace |
| 1174 | // try renderExpression(ais, tree, node, Space.None); | 1045 | // try renderExpression(ais, tree, node, Space.None); |
| 1175 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // } | 1046 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace |
| 1176 | // } | 1047 | // } |
| 1177 | | 1048 | |
| 1178 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error | 1049 | // try renderToken(ais, tree, err_set_decl.error_token, Space.None); // error |
| ... | @@ -1187,7 +1058,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1187,7 +1058,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1187 | // ais.pushIndent(); | 1058 | // ais.pushIndent(); |
| 1188 | // defer ais.popIndent(); | 1059 | // defer ais.popIndent(); |
| 1189 | | 1060 | |
| 1190 | // try renderToken(ais, tree, lbrace, Space.Newline); // { | 1061 | // try renderToken(ais, tree, lbrace, Space.Newline); // lbrace |
| 1191 | // const decls = err_set_decl.decls(); | 1062 | // const decls = err_set_decl.decls(); |
| 1192 | // for (decls) |node, i| { | 1063 | // for (decls) |node, i| { |
| 1193 | // if (i + 1 < decls.len) { | 1064 | // if (i + 1 < decls.len) { |
| ... | @@ -1201,9 +1072,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1201,9 +1072,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1201 | // } | 1072 | // } |
| 1202 | // } | 1073 | // } |
| 1203 | | 1074 | |
| 1204 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // } | 1075 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace |
| 1205 | // } else { | 1076 | // } else { |
| 1206 | // try renderToken(ais, tree, lbrace, Space.Space); // { | 1077 | // try renderToken(ais, tree, lbrace, Space.Space); // lbrace |
| 1207 | | 1078 | |
| 1208 | // const decls = err_set_decl.decls(); | 1079 | // const decls = err_set_decl.decls(); |
| 1209 | // for (decls) |node, i| { | 1080 | // for (decls) |node, i| { |
| ... | @@ -1219,7 +1090,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1219,7 +1090,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1219 | // } | 1090 | // } |
| 1220 | // } | 1091 | // } |
| 1221 | | 1092 | |
| 1222 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // } | 1093 | // return renderToken(ais, tree, err_set_decl.rbrace_token, space); // rbrace |
| 1223 | // } | 1094 | // } |
| 1224 | //}, | 1095 | //}, |
| 1225 | | 1096 | |
| ... | @@ -1277,8 +1148,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1277,8 +1148,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1277 | // if (switch_node.cases_len == 0) { | 1148 | // if (switch_node.cases_len == 0) { |
| 1278 | // try renderExpression(ais, tree, switch_node.expr, Space.None); | 1149 | // try renderExpression(ais, tree, switch_node.expr, Space.None); |
| 1279 | // try renderToken(ais, tree, rparen, Space.Space); // ) | 1150 | // try renderToken(ais, tree, rparen, Space.Space); // ) |
| 1280 | // try renderToken(ais, tree, lbrace, Space.None); // { | 1151 | // try renderToken(ais, tree, lbrace, Space.None); // lbrace |
| 1281 | // return renderToken(ais, tree, switch_node.rbrace, space); // } | 1152 | // return renderToken(ais, tree, switch_node.rbrace, space); // rbrace |
| 1282 | // } | 1153 | // } |
| 1283 | | 1154 | |
| 1284 | // try renderExpression(ais, tree, switch_node.expr, Space.None); | 1155 | // try renderExpression(ais, tree, switch_node.expr, Space.None); |
| ... | @@ -1287,7 +1158,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1287,7 +1158,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1287 | // { | 1158 | // { |
| 1288 | // ais.pushIndentNextLine(); | 1159 | // ais.pushIndentNextLine(); |
| 1289 | // defer ais.popIndent(); | 1160 | // defer ais.popIndent(); |
| 1290 | // try renderToken(ais, tree, lbrace, Space.Newline); // { | 1161 | // try renderToken(ais, tree, lbrace, Space.Newline); // lbrace |
| 1291 | | 1162 | |
| 1292 | // const cases = switch_node.cases(); | 1163 | // const cases = switch_node.cases(); |
| 1293 | // for (cases) |node, i| { | 1164 | // for (cases) |node, i| { |
| ... | @@ -1299,7 +1170,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1299,7 +1170,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1299 | // } | 1170 | // } |
| 1300 | // } | 1171 | // } |
| 1301 | | 1172 | |
| 1302 | // return renderToken(ais, tree, switch_node.rbrace, space); // } | 1173 | // return renderToken(ais, tree, switch_node.rbrace, space); // rbrace |
| 1303 | //}, | 1174 | //}, |
| 1304 | | 1175 | |
| 1305 | .SwitchCaseOne => unreachable, // TODO | 1176 | .SwitchCaseOne => unreachable, // TODO |
| ... | @@ -1379,7 +1250,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac | ... | @@ -1379,7 +1250,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac |
| 1379 | | 1250 | |
| 1380 | // if (body_is_block) { | 1251 | // if (body_is_block) { |
| 1381 | // block_start_space = Space.BlockStart; | 1252 | // block_start_space = Space.BlockStart; |
| 1382 | // after_body_space = if (while_node.@"else" == null) space else Space.SpaceOrOutdent; | 1253 | // after_body_space = if (while_node.@"else" == null) space else Space.Space; |
| 1383 | // } else if (tree.tokensOnSameLine(cond_rparen, while_node.body.lastToken())) { | 1254 | // } else if (tree.tokensOnSameLine(cond_rparen, while_node.body.lastToken())) { |
| 1384 | // block_start_space = Space.Space; | 1255 | // block_start_space = Space.Space; |
| 1385 | // after_body_space = if (while_node.@"else" == null) space else Space.Space; | 1256 | // after_body_space = if (while_node.@"else" == null) space else Space.Space; |
| ... | @@ -1782,10 +1653,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!vo | ... | @@ -1782,10 +1653,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.Full.VarDecl) Error!vo |
| 1782 | ais.popIndent(); | 1653 | ais.popIndent(); |
| 1783 | } | 1654 | } |
| 1784 | ais.pushIndentOneShot(); | 1655 | ais.pushIndentOneShot(); |
| 1785 | try renderExpression(ais, tree, var_decl.ast.init_node, Space.None); | 1656 | try renderExpression(ais, tree, var_decl.ast.init_node, .Semicolon); |
| 1786 | | | |
| 1787 | const semicolon = tree.lastToken(var_decl.ast.init_node) + 1; | | |
| 1788 | return renderToken(ais, tree, semicolon, Space.Newline); | | |
| 1789 | } | 1657 | } |
| 1790 | | 1658 | |
| 1791 | fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error!void { | 1659 | fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error!void { |
| ... | @@ -1820,7 +1688,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error | ... | @@ -1820,7 +1688,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error |
| 1820 | try renderToken(ais, tree, rparen, .BlockStart); // ) | 1688 | try renderToken(ais, tree, rparen, .BlockStart); // ) |
| 1821 | } | 1689 | } |
| 1822 | if (if_node.ast.else_expr != 0) { | 1690 | if (if_node.ast.else_expr != 0) { |
| 1823 | try renderExpression(ais, tree, if_node.ast.then_expr, Space.SpaceOrOutdent); | 1691 | try renderExpression(ais, tree, if_node.ast.then_expr, Space.Space); |
| 1824 | try renderToken(ais, tree, if_node.else_token, .Space); // else | 1692 | try renderToken(ais, tree, if_node.else_token, .Space); // else |
| 1825 | if (if_node.error_token) |error_token| { | 1693 | if (if_node.error_token) |error_token| { |
| 1826 | try renderToken(ais, tree, error_token - 1, .None); // | | 1694 | try renderToken(ais, tree, error_token - 1, .None); // | |
| ... | @@ -2197,6 +2065,7 @@ fn renderBlock( | ... | @@ -2197,6 +2065,7 @@ fn renderBlock( |
| 2197 | ) Error!void { | 2065 | ) Error!void { |
| 2198 | const token_tags = tree.tokens.items(.tag); | 2066 | const token_tags = tree.tokens.items(.tag); |
| 2199 | const node_tags = tree.nodes.items(.tag); | 2067 | const node_tags = tree.nodes.items(.tag); |
| | 2068 | const nodes_data = tree.nodes.items(.data); |
| 2200 | | 2069 | |
| 2201 | if (token_tags[lbrace - 1] == .Colon and | 2070 | if (token_tags[lbrace - 1] == .Colon and |
| 2202 | token_tags[lbrace - 2] == .Identifier) | 2071 | token_tags[lbrace - 2] == .Identifier) |
| ... | @@ -2204,50 +2073,88 @@ fn renderBlock( | ... | @@ -2204,50 +2073,88 @@ fn renderBlock( |
| 2204 | try renderToken(ais, tree, lbrace - 2, .None); | 2073 | try renderToken(ais, tree, lbrace - 2, .None); |
| 2205 | try renderToken(ais, tree, lbrace - 1, .Space); | 2074 | try renderToken(ais, tree, lbrace - 1, .Space); |
| 2206 | } | 2075 | } |
| 2207 | const nodes_data = tree.nodes.items(.data); | | |
| 2208 | | 2076 | |
| 2209 | if (statements.len == 0) { | 2077 | if (statements.len == 0) { |
| 2210 | ais.pushIndentNextLine(); | | |
| 2211 | try renderToken(ais, tree, lbrace, .None); | 2078 | try renderToken(ais, tree, lbrace, .None); |
| 2212 | ais.popIndent(); | 2079 | return renderToken(ais, tree, lbrace + 1, space); // rbrace |
| 2213 | const rbrace = lbrace + 1; | 2080 | } |
| 2214 | return renderToken(ais, tree, rbrace, space); | 2081 | |
| | 2082 | ais.pushIndent(); |
| | 2083 | try renderToken(ais, tree, lbrace, .Newline); |
| | 2084 | for (statements) |stmt, i| { |
| | 2085 | switch (node_tags[stmt]) { |
| | 2086 | .GlobalVarDecl => try renderVarDecl(ais, tree, tree.globalVarDecl(stmt)), |
| | 2087 | .LocalVarDecl => try renderVarDecl(ais, tree, tree.localVarDecl(stmt)), |
| | 2088 | .SimpleVarDecl => try renderVarDecl(ais, tree, tree.simpleVarDecl(stmt)), |
| | 2089 | .AlignedVarDecl => try renderVarDecl(ais, tree, tree.alignedVarDecl(stmt)), |
| | 2090 | else => try renderExpression(ais, tree, stmt, .Semicolon), |
| | 2091 | } |
| | 2092 | if (i + 1 < statements.len) { |
| | 2093 | try renderExtraNewline(ais, tree, statements[i + 1]); |
| | 2094 | } |
| | 2095 | } |
| | 2096 | ais.popIndent(); |
| | 2097 | // The rbrace could be +1 or +2 from the last token of the last |
| | 2098 | // statement in the block because lastToken() does not count semicolons. |
| | 2099 | const maybe_rbrace = tree.lastToken(statements[statements.len - 1]) + 1; |
| | 2100 | if (token_tags[maybe_rbrace] == .RBrace) { |
| | 2101 | return renderToken(ais, tree, maybe_rbrace, space); |
| 2215 | } else { | 2102 | } else { |
| 2216 | ais.pushIndentNextLine(); | 2103 | assert(token_tags[maybe_rbrace + 1] == .RBrace); |
| 2217 | | 2104 | return renderToken(ais, tree, maybe_rbrace + 1, space); |
| 2218 | try renderToken(ais, tree, lbrace, .Newline); | 2105 | } |
| 2219 | | 2106 | } |
| 2220 | for (statements) |stmt, i| { | | |
| 2221 | switch (node_tags[stmt]) { | | |
| 2222 | .GlobalVarDecl => try renderVarDecl(ais, tree, tree.globalVarDecl(stmt)), | | |
| 2223 | .LocalVarDecl => try renderVarDecl(ais, tree, tree.localVarDecl(stmt)), | | |
| 2224 | .SimpleVarDecl => try renderVarDecl(ais, tree, tree.simpleVarDecl(stmt)), | | |
| 2225 | .AlignedVarDecl => try renderVarDecl(ais, tree, tree.alignedVarDecl(stmt)), | | |
| 2226 | else => { | | |
| 2227 | const semicolon = tree.lastToken(stmt) + 1; | | |
| 2228 | if (token_tags[semicolon] == .Semicolon) { | | |
| 2229 | try renderExpression(ais, tree, stmt, .None); | | |
| 2230 | try renderToken(ais, tree, semicolon, .Newline); | | |
| 2231 | } else { | | |
| 2232 | try renderExpression(ais, tree, stmt, .Newline); | | |
| 2233 | } | | |
| 2234 | }, | | |
| 2235 | } | | |
| 2236 | | 2107 | |
| 2237 | if (i + 1 < statements.len) { | 2108 | fn renderStructInit( |
| 2238 | try renderExtraNewline(ais, tree, statements[i + 1]); | 2109 | ais: *Ais, |
| 2239 | } | 2110 | tree: ast.Tree, |
| | 2111 | struct_init: ast.Full.StructInit, |
| | 2112 | space: Space, |
| | 2113 | ) Error!void { |
| | 2114 | const token_tags = tree.tokens.items(.tag); |
| | 2115 | if (struct_init.ast.type_expr == 0) { |
| | 2116 | try renderToken(ais, tree, struct_init.ast.lbrace - 1, .None); // . |
| | 2117 | } else { |
| | 2118 | try renderExpression(ais, tree, struct_init.ast.type_expr, .None); // T |
| | 2119 | } |
| | 2120 | if (struct_init.ast.fields.len == 0) { |
| | 2121 | try renderToken(ais, tree, struct_init.ast.lbrace, .None); // lbrace |
| | 2122 | return renderToken(ais, tree, struct_init.ast.lbrace + 1, space); // rbrace |
| | 2123 | } |
| | 2124 | const last_field = struct_init.ast.fields[struct_init.ast.fields.len - 1]; |
| | 2125 | const last_field_token = tree.lastToken(last_field); |
| | 2126 | if (token_tags[last_field_token + 1] == .Comma) { |
| | 2127 | // Render one field init per line. |
| | 2128 | ais.pushIndent(); |
| | 2129 | try renderToken(ais, tree, struct_init.ast.lbrace, .Newline); |
| | 2130 | |
| | 2131 | try renderToken(ais, tree, struct_init.ast.lbrace + 1, .None); // . |
| | 2132 | try renderToken(ais, tree, struct_init.ast.lbrace + 2, .Space); // name |
| | 2133 | try renderToken(ais, tree, struct_init.ast.lbrace + 3, .Space); // = |
| | 2134 | try renderExpression(ais, tree, struct_init.ast.fields[0], .Comma); |
| | 2135 | |
| | 2136 | for (struct_init.ast.fields[1..]) |field_init| { |
| | 2137 | const init_token = tree.firstToken(field_init); |
| | 2138 | try renderToken(ais, tree, init_token - 3, .None); // . |
| | 2139 | try renderToken(ais, tree, init_token - 2, .Space); // name |
| | 2140 | try renderToken(ais, tree, init_token - 1, .Space); // = |
| | 2141 | try renderExpressionNewlined(ais, tree, field_init, .Comma); |
| 2240 | } | 2142 | } |
| 2241 | ais.popIndent(); | 2143 | ais.popIndent(); |
| 2242 | // The rbrace could be +1 or +2 from the last token of the last | 2144 | return renderToken(ais, tree, last_field_token + 2, space); // rbrace |
| 2243 | // statement in the block because lastToken() does not count semicolons. | 2145 | } else { |
| 2244 | const maybe_rbrace = tree.lastToken(statements[statements.len - 1]) + 1; | 2146 | // Render all on one line, no trailing comma. |
| 2245 | if (token_tags[maybe_rbrace] == .RBrace) { | 2147 | try renderToken(ais, tree, struct_init.ast.lbrace, .Space); |
| 2246 | return renderToken(ais, tree, maybe_rbrace, space); | 2148 | |
| 2247 | } else { | 2149 | for (struct_init.ast.fields) |field_init| { |
| 2248 | assert(token_tags[maybe_rbrace + 1] == .RBrace); | 2150 | const init_token = tree.firstToken(field_init); |
| 2249 | return renderToken(ais, tree, maybe_rbrace + 1, space); | 2151 | try renderToken(ais, tree, init_token - 3, .None); // . |
| | 2152 | try renderToken(ais, tree, init_token - 2, .Space); // name |
| | 2153 | try renderToken(ais, tree, init_token - 1, .Space); // = |
| | 2154 | try renderExpression(ais, tree, field_init, .CommaSpace); |
| 2250 | } | 2155 | } |
| | 2156 | |
| | 2157 | return renderToken(ais, tree, last_field_token + 1, space); // rbrace |
| 2251 | } | 2158 | } |
| 2252 | } | 2159 | } |
| 2253 | | 2160 | |
| ... | @@ -2263,6 +2170,22 @@ fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: | ... | @@ -2263,6 +2170,22 @@ fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: |
| 2263 | } | 2170 | } |
| 2264 | } | 2171 | } |
| 2265 | | 2172 | |
| | 2173 | /// Render an expression, but first insert an extra newline if the previous token is 2 or |
| | 2174 | /// more lines away. |
| | 2175 | fn renderExpressionNewlined( |
| | 2176 | ais: *Ais, |
| | 2177 | tree: ast.Tree, |
| | 2178 | node: ast.Node.Index, |
| | 2179 | space: Space, |
| | 2180 | ) Error!void { |
| | 2181 | const token_starts = tree.tokens.items(.start); |
| | 2182 | const first_token = tree.firstToken(node); |
| | 2183 | if (tree.tokenLocation(token_starts[first_token - 1], first_token).line >= 2) { |
| | 2184 | try ais.insertNewline(); |
| | 2185 | } |
| | 2186 | return renderExpression(ais, tree, node, space); |
| | 2187 | } |
| | 2188 | |
| 2266 | fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Space) Error!void { | 2189 | fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Space) Error!void { |
| 2267 | const token_tags = tree.tokens.items(.tag); | 2190 | const token_tags = tree.tokens.items(.tag); |
| 2268 | const maybe_comma = token + 1; | 2191 | const maybe_comma = token + 1; |
| ... | @@ -2275,22 +2198,32 @@ fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Spa | ... | @@ -2275,22 +2198,32 @@ fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Spa |
| 2275 | } | 2198 | } |
| 2276 | | 2199 | |
| 2277 | const Space = enum { | 2200 | const Space = enum { |
| | 2201 | /// Output the token lexeme only. |
| 2278 | None, | 2202 | None, |
| | 2203 | /// Output the token lexeme followed by a single space. |
| | 2204 | Space, |
| | 2205 | /// Output the token lexeme followed by a newline. |
| 2279 | Newline, | 2206 | Newline, |
| 2280 | /// `renderToken` will additionally consume the next token if it is a comma. | 2207 | /// Additionally consume the next token if it is a comma. |
| | 2208 | /// In either case, a newline will be inserted afterwards. |
| 2281 | Comma, | 2209 | Comma, |
| 2282 | Space, | 2210 | /// Additionally consume the next token if it is a comma. |
| 2283 | SpaceOrOutdent, | 2211 | /// In either case, a space will be inserted afterwards. |
| 2284 | NoNewline, | 2212 | CommaSpace, |
| | 2213 | /// Additionally consume the next token if it is a semicolon. |
| | 2214 | /// In either case, a newline will be inserted afterwards. |
| | 2215 | Semicolon, |
| 2285 | /// Skips writing the possible line comment after the token. | 2216 | /// Skips writing the possible line comment after the token. |
| 2286 | NoComment, | 2217 | NoComment, |
| | 2218 | /// Intended when rendering lbrace tokens. Depending on whether the line is |
| | 2219 | /// "over indented", will output a newline or a single space afterwards. |
| | 2220 | /// See `std.io.AutoIndentingStream` for the definition of "over indented". |
| 2287 | BlockStart, | 2221 | BlockStart, |
| 2288 | }; | 2222 | }; |
| 2289 | | 2223 | |
| 2290 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { | 2224 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { |
| 2291 | if (space == Space.BlockStart) { | 2225 | if (space == Space.BlockStart) { |
| 2292 | // If placing the lbrace on the current line would cause an ugly gap then put the lbrace on the next line. | 2226 | const new_space: Space = if (ais.isLineOverIndented()) .Newline else .Space; |
| 2293 | const new_space = if (ais.isLineOverIndented()) Space.Newline else Space.Space; | | |
| 2294 | return renderToken(ais, tree, token_index, new_space); | 2227 | return renderToken(ais, tree, token_index, new_space); |
| 2295 | } | 2228 | } |
| 2296 | | 2229 | |
| ... | @@ -2313,7 +2246,6 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp | ... | @@ -2313,7 +2246,6 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp |
| 2313 | | 2246 | |
| 2314 | switch (space) { | 2247 | switch (space) { |
| 2315 | .NoComment => {}, | 2248 | .NoComment => {}, |
| 2316 | .NoNewline => {}, | | |
| 2317 | .None => {}, | 2249 | .None => {}, |
| 2318 | .Comma => { | 2250 | .Comma => { |
| 2319 | const count = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ", "); | 2251 | const count = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ", "); |
| ... | @@ -2326,10 +2258,25 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp | ... | @@ -2326,10 +2258,25 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp |
| 2326 | try ais.insertNewline(); | 2258 | try ais.insertNewline(); |
| 2327 | } | 2259 | } |
| 2328 | }, | 2260 | }, |
| 2329 | .SpaceOrOutdent => @panic("what does this even do"), | 2261 | .CommaSpace => { |
| | 2262 | _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ""); |
| | 2263 | if (token_tags[token_index + 1] == .Comma) { |
| | 2264 | return renderToken(ais, tree, token_index + 1, .Space); |
| | 2265 | } else { |
| | 2266 | return ais.writer().writeByte(' '); |
| | 2267 | } |
| | 2268 | }, |
| | 2269 | .Semicolon => { |
| | 2270 | _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ""); |
| | 2271 | if (token_tags[token_index + 1] == .Semicolon) { |
| | 2272 | return renderToken(ais, tree, token_index + 1, .Newline); |
| | 2273 | } else { |
| | 2274 | return ais.insertNewline(); |
| | 2275 | } |
| | 2276 | }, |
| 2330 | .Space => { | 2277 | .Space => { |
| 2331 | _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ""); | 2278 | _ = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1], ""); |
| 2332 | try ais.writer().writeByte(' '); | 2279 | return ais.writer().writeByte(' '); |
| 2333 | }, | 2280 | }, |
| 2334 | .Newline => { | 2281 | .Newline => { |
| 2335 | if (token_tags[token_index + 1] != .MultilineStringLiteralLine) { | 2282 | if (token_tags[token_index + 1] != .MultilineStringLiteralLine) { |
| ... | @@ -2437,10 +2384,11 @@ fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool { | ... | @@ -2437,10 +2384,11 @@ fn nodeCausesSliceOpSpace(base: ast.Node.Index) bool { |
| 2437 | } | 2384 | } |
| 2438 | | 2385 | |
| 2439 | fn copyFixingWhitespace(ais: *Ais, slice: []const u8) @TypeOf(ais.*).Error!void { | 2386 | fn copyFixingWhitespace(ais: *Ais, slice: []const u8) @TypeOf(ais.*).Error!void { |
| | 2387 | const writer = ais.writer(); |
| 2440 | for (slice) |byte| switch (byte) { | 2388 | for (slice) |byte| switch (byte) { |
| 2441 | '\t' => try ais.writer().writeAll(" "), | 2389 | '\t' => try writer.writeAll(" "), |
| 2442 | '\r' => {}, | 2390 | '\r' => {}, |
| 2443 | else => try ais.writer().writeByte(byte), | 2391 | else => try writer.writeByte(byte), |
| 2444 | }; | 2392 | }; |
| 2445 | } | 2393 | } |
| 2446 | | 2394 | |