| ... | @@ -1018,170 +1018,95 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. | ... | @@ -1018,170 +1018,95 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. |
| 1018 | try renderToken(ais, tree, inline_token, .space); // inline | 1018 | try renderToken(ais, tree, inline_token, .space); // inline |
| 1019 | } | 1019 | } |
| 1020 | | 1020 | |
| 1021 | try renderToken(ais, tree, while_node.ast.while_token, .space); // if | 1021 | try renderToken(ais, tree, while_node.ast.while_token, .space); // if/for/while |
| 1022 | try renderToken(ais, tree, while_node.ast.while_token + 1, .none); // lparen | 1022 | try renderToken(ais, tree, while_node.ast.while_token + 1, .none); // lparen |
| 1023 | try renderExpression(gpa, ais, tree, while_node.ast.cond_expr, .none); // condition | 1023 | try renderExpression(gpa, ais, tree, while_node.ast.cond_expr, .none); // condition |
| 1024 | | 1024 | |
| 1025 | const then_tag = node_tags[while_node.ast.then_expr]; | 1025 | var last_prefix_token = tree.lastToken(while_node.ast.cond_expr) + 1; // rparen |
| 1026 | if (nodeIsBlock(then_tag) and !nodeIsIf(then_tag)) { | | |
| 1027 | if (while_node.payload_token) |payload_token| { | | |
| 1028 | const brace_space = if (while_node.ast.cont_expr == 0 and ais.isLineOverIndented()) | | |
| 1029 | Space.newline | | |
| 1030 | else | | |
| 1031 | Space.space; | | |
| 1032 | try renderWhilePayload(gpa, ais, tree, payload_token, brace_space); | | |
| 1033 | } else { | | |
| 1034 | const rparen = tree.lastToken(while_node.ast.cond_expr) + 1; | | |
| 1035 | const brace_space = if (while_node.ast.cont_expr == 0 and ais.isLineOverIndented()) | | |
| 1036 | Space.newline | | |
| 1037 | else | | |
| 1038 | Space.space; | | |
| 1039 | try renderToken(ais, tree, rparen, brace_space); // rparen | | |
| 1040 | } | | |
| 1041 | if (while_node.ast.cont_expr != 0) { | | |
| 1042 | const rparen = tree.lastToken(while_node.ast.cont_expr) + 1; | | |
| 1043 | const lparen = tree.firstToken(while_node.ast.cont_expr) - 1; | | |
| 1044 | try renderToken(ais, tree, lparen - 1, .space); // : | | |
| 1045 | try renderToken(ais, tree, lparen, .none); // lparen | | |
| 1046 | try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none); | | |
| 1047 | const brace_space: Space = if (ais.isLineOverIndented()) .newline else .space; | | |
| 1048 | try renderToken(ais, tree, rparen, brace_space); // rparen | | |
| 1049 | } | | |
| 1050 | if (while_node.ast.else_expr != 0) { | | |
| 1051 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, Space.space); | | |
| 1052 | try renderToken(ais, tree, while_node.else_token, .space); // else | | |
| 1053 | if (while_node.error_token) |error_token| { | | |
| 1054 | try renderToken(ais, tree, error_token - 1, .none); // | | | |
| 1055 | try renderToken(ais, tree, error_token, .none); // identifier | | |
| 1056 | try renderToken(ais, tree, error_token + 1, .space); // | | | |
| 1057 | } | | |
| 1058 | return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space); | | |
| 1059 | } else { | | |
| 1060 | return renderExpression(gpa, ais, tree, while_node.ast.then_expr, space); | | |
| 1061 | } | | |
| 1062 | } | | |
| 1063 | | | |
| 1064 | const rparen = tree.lastToken(while_node.ast.cond_expr) + 1; | | |
| 1065 | const first_then_token = tree.firstToken(while_node.ast.then_expr); | | |
| 1066 | const last_then_token = tree.lastToken(while_node.ast.then_expr); | | |
| 1067 | const src_has_newline = !tree.tokensOnSameLine(rparen, last_then_token); | | |
| 1068 | | 1026 | |
| 1069 | if (src_has_newline) { | 1027 | if (while_node.payload_token) |payload_token| { |
| 1070 | const newline_before_then_token = !tree.tokensOnSameLine(rparen, first_then_token); | 1028 | try renderToken(ais, tree, last_prefix_token, .space); |
| 1071 | const space_before_then_token: Space = if (newline_before_then_token) .newline else .space; | 1029 | try renderToken(ais, tree, payload_token - 1, .none); // | |
| 1072 | const indent_expression = !nodeIsIf(then_tag) or newline_before_then_token; | 1030 | const ident = blk: { |
| 1073 | | 1031 | if (token_tags[payload_token] == .asterisk) { |
| 1074 | if (while_node.payload_token) |payload_token| { | 1032 | try renderToken(ais, tree, payload_token, .none); // * |
| 1075 | const after_space: Space = if (while_node.ast.cont_expr != 0) .space else space_before_then_token; | 1033 | break :blk payload_token + 1; |
| 1076 | try renderWhilePayload(gpa, ais, tree, payload_token, after_space); | | |
| 1077 | } else { | | |
| 1078 | if (indent_expression) ais.pushIndent(); | | |
| 1079 | const after_space: Space = if (while_node.ast.cont_expr != 0) .space else space_before_then_token; | | |
| 1080 | try renderToken(ais, tree, rparen, after_space); // rparen | | |
| 1081 | if (indent_expression) ais.popIndent(); | | |
| 1082 | } | | |
| 1083 | if (while_node.ast.cont_expr != 0) { | | |
| 1084 | const cont_rparen = tree.lastToken(while_node.ast.cont_expr) + 1; | | |
| 1085 | const cont_lparen = tree.firstToken(while_node.ast.cont_expr) - 1; | | |
| 1086 | try renderToken(ais, tree, cont_lparen - 1, .space); // : | | |
| 1087 | try renderToken(ais, tree, cont_lparen, .none); // lparen | | |
| 1088 | try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none); | | |
| 1089 | try renderToken(ais, tree, cont_rparen, space_before_then_token); // rparen | | |
| 1090 | } | | |
| 1091 | if (while_node.ast.else_expr != 0) { | | |
| 1092 | if (indent_expression) ais.pushIndent(); | | |
| 1093 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .newline); | | |
| 1094 | if (indent_expression) ais.popIndent(); | | |
| 1095 | const else_is_block = nodeIsBlock(node_tags[while_node.ast.else_expr]); | | |
| 1096 | if (else_is_block) { | | |
| 1097 | try renderToken(ais, tree, while_node.else_token, .space); // else | | |
| 1098 | if (while_node.error_token) |error_token| { | | |
| 1099 | try renderToken(ais, tree, error_token - 1, .none); // | | | |
| 1100 | try renderToken(ais, tree, error_token, .none); // identifier | | |
| 1101 | try renderToken(ais, tree, error_token + 1, .space); // | | | |
| 1102 | } | | |
| 1103 | return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space); | | |
| 1104 | } else { | 1034 | } else { |
| 1105 | if (while_node.error_token) |error_token| { | 1035 | break :blk payload_token; |
| 1106 | try renderToken(ais, tree, while_node.else_token, .space); // else | | |
| 1107 | try renderToken(ais, tree, error_token - 1, .none); // | | | |
| 1108 | try renderToken(ais, tree, error_token, .none); // identifier | | |
| 1109 | try renderToken(ais, tree, error_token + 1, .space); // | | | |
| 1110 | } else { | | |
| 1111 | try renderToken(ais, tree, while_node.else_token, .newline); // else | | |
| 1112 | } | | |
| 1113 | if (indent_expression) { | | |
| 1114 | return renderExpressionIndented(gpa, ais, tree, while_node.ast.else_expr, space); | | |
| 1115 | } else { | | |
| 1116 | return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space); | | |
| 1117 | } | | |
| 1118 | } | 1036 | } |
| 1119 | } else { | 1037 | }; |
| 1120 | if (indent_expression) { | 1038 | try renderToken(ais, tree, ident, .none); // identifier |
| 1121 | return renderExpressionIndented(gpa, ais, tree, while_node.ast.then_expr, space); | 1039 | const pipe = blk: { |
| | 1040 | if (token_tags[ident + 1] == .comma) { |
| | 1041 | try renderToken(ais, tree, ident + 1, .space); // , |
| | 1042 | try renderToken(ais, tree, ident + 2, .none); // index |
| | 1043 | break :blk ident + 3; |
| 1122 | } else { | 1044 | } else { |
| 1123 | return renderExpression(gpa, ais, tree, while_node.ast.then_expr, space); | 1045 | break :blk ident + 1; |
| 1124 | } | 1046 | } |
| 1125 | } | 1047 | }; |
| 1126 | } | 1048 | last_prefix_token = pipe; |
| 1127 | | | |
| 1128 | // Render everything on a single line. | | |
| 1129 | | | |
| 1130 | if (while_node.payload_token) |payload_token| { | | |
| 1131 | assert(payload_token - 2 == rparen); | | |
| 1132 | try renderWhilePayload(gpa, ais, tree, payload_token, .space); | | |
| 1133 | } else { | | |
| 1134 | try renderToken(ais, tree, rparen, .space); // ) | | |
| 1135 | } | 1049 | } |
| 1136 | | 1050 | |
| 1137 | if (while_node.ast.cont_expr != 0) { | 1051 | if (while_node.ast.cont_expr != 0) { |
| 1138 | const cont_rparen = tree.lastToken(while_node.ast.cont_expr) + 1; | 1052 | try renderToken(ais, tree, last_prefix_token, .space); |
| 1139 | const cont_lparen = tree.firstToken(while_node.ast.cont_expr) - 1; | 1053 | const lparen = tree.firstToken(while_node.ast.cont_expr) - 1; |
| 1140 | try renderToken(ais, tree, cont_lparen - 1, .space); // : | 1054 | try renderToken(ais, tree, lparen - 1, .space); // : |
| 1141 | try renderToken(ais, tree, cont_lparen, .none); // lparen | 1055 | try renderToken(ais, tree, lparen, .none); // lparen |
| 1142 | try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none); | 1056 | try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none); |
| 1143 | try renderToken(ais, tree, cont_rparen, .space); // rparen | 1057 | last_prefix_token = tree.lastToken(while_node.ast.cont_expr) + 1; // rparen |
| | 1058 | } |
| | 1059 | |
| | 1060 | const then_expr_is_block = nodeIsBlock(node_tags[while_node.ast.then_expr]); |
| | 1061 | const indent_then_expr = !then_expr_is_block and |
| | 1062 | !tree.tokensOnSameLine(last_prefix_token, tree.firstToken(while_node.ast.then_expr)); |
| | 1063 | if (indent_then_expr or (then_expr_is_block and ais.isLineOverIndented())) { |
| | 1064 | ais.pushIndentNextLine(); |
| | 1065 | try renderToken(ais, tree, last_prefix_token, .newline); |
| | 1066 | ais.popIndent(); |
| | 1067 | } else { |
| | 1068 | try renderToken(ais, tree, last_prefix_token, .space); |
| 1144 | } | 1069 | } |
| 1145 | | 1070 | |
| 1146 | if (while_node.ast.else_expr != 0) { | 1071 | if (while_node.ast.else_expr != 0) { |
| 1147 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .space); | 1072 | const first_else_expr_tok = tree.firstToken(while_node.ast.else_expr); |
| 1148 | try renderToken(ais, tree, while_node.else_token, .space); // else | 1073 | |
| | 1074 | if (indent_then_expr) { |
| | 1075 | ais.pushIndent(); |
| | 1076 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .newline); |
| | 1077 | ais.popIndent(); |
| | 1078 | } else { |
| | 1079 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .space); |
| | 1080 | } |
| | 1081 | |
| | 1082 | var last_else_token = while_node.else_token; |
| 1149 | | 1083 | |
| 1150 | if (while_node.error_token) |error_token| { | 1084 | if (while_node.error_token) |error_token| { |
| | 1085 | try renderToken(ais, tree, while_node.else_token, .space); // else |
| 1151 | try renderToken(ais, tree, error_token - 1, .none); // | | 1086 | try renderToken(ais, tree, error_token - 1, .none); // | |
| 1152 | try renderToken(ais, tree, error_token, .none); // identifier | 1087 | try renderToken(ais, tree, error_token, .none); // identifier |
| 1153 | try renderToken(ais, tree, error_token + 1, .space); // | | 1088 | last_else_token = error_token + 1; // | |
| 1154 | } | 1089 | } |
| 1155 | | 1090 | |
| 1156 | return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space); | 1091 | const indent_else_expr = indent_then_expr and |
| 1157 | } else { | 1092 | !nodeIsBlock(node_tags[while_node.ast.else_expr]) and |
| 1158 | return renderExpression(gpa, ais, tree, while_node.ast.then_expr, space); | 1093 | !nodeIsIfForWhileSwitch(node_tags[while_node.ast.else_expr]); |
| 1159 | } | 1094 | if (indent_else_expr) { |
| 1160 | } | 1095 | ais.pushIndentNextLine(); |
| 1161 | | 1096 | try renderToken(ais, tree, last_else_token, .newline); |
| 1162 | fn renderWhilePayload(gpa: *Allocator, ais: *Ais, tree: ast.Tree, payload_token: ast.TokenIndex, space: Space) Error!void { | 1097 | ais.popIndent(); |
| 1163 | const token_tags = tree.tokens.items(.tag); | 1098 | try renderExpressionIndented(gpa, ais, tree, while_node.ast.else_expr, space); |
| 1164 | try renderToken(ais, tree, payload_token - 2, .space); // rparen | | |
| 1165 | try renderToken(ais, tree, payload_token - 1, .none); // | | | |
| 1166 | const ident = blk: { | | |
| 1167 | if (token_tags[payload_token] == .asterisk) { | | |
| 1168 | try renderToken(ais, tree, payload_token, .none); // * | | |
| 1169 | break :blk payload_token + 1; | | |
| 1170 | } else { | 1099 | } else { |
| 1171 | break :blk payload_token; | 1100 | try renderToken(ais, tree, last_else_token, .space); |
| | 1101 | try renderExpression(gpa, ais, tree, while_node.ast.else_expr, space); |
| 1172 | } | 1102 | } |
| 1173 | }; | 1103 | } else { |
| 1174 | try renderToken(ais, tree, ident, .none); // identifier | 1104 | if (indent_then_expr) { |
| 1175 | const pipe = blk: { | 1105 | try renderExpressionIndented(gpa, ais, tree, while_node.ast.then_expr, space); |
| 1176 | if (token_tags[ident + 1] == .comma) { | | |
| 1177 | try renderToken(ais, tree, ident + 1, .space); // , | | |
| 1178 | try renderToken(ais, tree, ident + 2, .none); // index | | |
| 1179 | break :blk ident + 3; | | |
| 1180 | } else { | 1106 | } else { |
| 1181 | break :blk ident + 1; | 1107 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, space); |
| 1182 | } | 1108 | } |
| 1183 | }; | 1109 | } |
| 1184 | try renderToken(ais, tree, pipe, space); // | | | |
| 1185 | } | 1110 | } |
| 1186 | | 1111 | |
| 1187 | fn renderContainerField( | 1112 | fn renderContainerField( |
| ... | @@ -2469,6 +2394,21 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool { | ... | @@ -2469,6 +2394,21 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool { |
| 2469 | .block_semicolon, | 2394 | .block_semicolon, |
| 2470 | .block_two, | 2395 | .block_two, |
| 2471 | .block_two_semicolon, | 2396 | .block_two_semicolon, |
| | 2397 | .struct_init_dot, |
| | 2398 | .struct_init_dot_comma, |
| | 2399 | .struct_init_dot_two, |
| | 2400 | .struct_init_dot_two_comma, |
| | 2401 | .array_init_dot, |
| | 2402 | .array_init_dot_comma, |
| | 2403 | .array_init_dot_two, |
| | 2404 | .array_init_dot_two_comma, |
| | 2405 | => true, |
| | 2406 | else => false, |
| | 2407 | }; |
| | 2408 | } |
| | 2409 | |
| | 2410 | fn nodeIsIfForWhileSwitch(tag: ast.Node.Tag) bool { |
| | 2411 | return switch (tag) { |
| 2472 | .@"if", | 2412 | .@"if", |
| 2473 | .if_simple, | 2413 | .if_simple, |
| 2474 | .@"for", | 2414 | .@"for", |
| ... | @@ -2483,13 +2423,6 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool { | ... | @@ -2483,13 +2423,6 @@ fn nodeIsBlock(tag: ast.Node.Tag) bool { |
| 2483 | }; | 2423 | }; |
| 2484 | } | 2424 | } |
| 2485 | | 2425 | |
| 2486 | fn nodeIsIf(tag: ast.Node.Tag) bool { | | |
| 2487 | return switch (tag) { | | |
| 2488 | .@"if", .if_simple => true, | | |
| 2489 | else => false, | | |
| 2490 | }; | | |
| 2491 | } | | |
| 2492 | | | |
| 2493 | fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool { | 2426 | fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool { |
| 2494 | return switch (tag) { | 2427 | return switch (tag) { |
| 2495 | .@"catch", | 2428 | .@"catch", |