| ... | @@ -44,7 +44,6 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void { | ... | @@ -44,7 +44,6 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void { |
| 44 | /// Render all members in the given slice, keeping empty lines where appropriate | 44 | /// Render all members in the given slice, keeping empty lines where appropriate |
| 45 | fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void { | 45 | fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void { |
| 46 | if (members.len == 0) return; | 46 | if (members.len == 0) return; |
| 47 | //try renderExtraNewline(ais, tree, members[0]); | | |
| 48 | try renderMember(gpa, ais, tree, members[0], .newline); | 47 | try renderMember(gpa, ais, tree, members[0], .newline); |
| 49 | for (members[1..]) |member| { | 48 | for (members[1..]) |member| { |
| 50 | try renderExtraNewline(ais, tree, member); | 49 | try renderExtraNewline(ais, tree, member); |
| ... | @@ -202,10 +201,8 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I | ... | @@ -202,10 +201,8 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I |
| 202 | while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent(); | 201 | while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent(); |
| 203 | | 202 | |
| 204 | switch (space) { | 203 | switch (space) { |
| 205 | .none, .space, .newline => {}, | 204 | .none, .space, .newline, .skip => {}, |
| 206 | .newline_pop => ais.popIndent(), | | |
| 207 | .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline), | 205 | .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline), |
| 208 | .semicolon_pop => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline_pop), | | |
| 209 | .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline), | 206 | .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline), |
| 210 | .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space), | 207 | .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space), |
| 211 | } | 208 | } |
| ... | @@ -1147,15 +1144,11 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. | ... | @@ -1147,15 +1144,11 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. |
| 1147 | } else { | 1144 | } else { |
| 1148 | try renderToken(ais, tree, while_node.else_token, .newline); // else | 1145 | try renderToken(ais, tree, while_node.else_token, .newline); // else |
| 1149 | } | 1146 | } |
| 1150 | ais.pushIndent(); | 1147 | try renderExpressionIndented(gpa, ais, tree, while_node.ast.else_expr, space); |
| 1151 | try renderExpression(gpa, ais, tree, while_node.ast.else_expr, space); | | |
| 1152 | ais.popIndent(); | | |
| 1153 | return; | 1148 | return; |
| 1154 | } | 1149 | } |
| 1155 | } else { | 1150 | } else { |
| 1156 | ais.pushIndent(); | 1151 | try renderExpressionIndented(gpa, ais, tree, while_node.ast.then_expr, space); |
| 1157 | assert(space == .semicolon); | | |
| 1158 | try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .semicolon_pop); | | |
| 1159 | return; | 1152 | return; |
| 1160 | } | 1153 | } |
| 1161 | } | 1154 | } |
| ... | @@ -2168,6 +2161,64 @@ fn renderCall( | ... | @@ -2168,6 +2161,64 @@ fn renderCall( |
| 2168 | return renderToken(ais, tree, after_last_param_tok, space); // ) | 2161 | return renderToken(ais, tree, after_last_param_tok, space); // ) |
| 2169 | } | 2162 | } |
| 2170 | | 2163 | |
| | 2164 | /// Renders the given expression indented, popping the indent before rendering |
| | 2165 | /// any following line comments |
| | 2166 | fn renderExpressionIndented(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void { |
| | 2167 | const token_starts = tree.tokens.items(.start); |
| | 2168 | const token_tags = tree.tokens.items(.tag); |
| | 2169 | |
| | 2170 | ais.pushIndent(); |
| | 2171 | |
| | 2172 | var last_token = tree.lastToken(node); |
| | 2173 | const punctuation = switch (space) { |
| | 2174 | .none, .space, .newline, .skip => false, |
| | 2175 | .comma => true, |
| | 2176 | .comma_space => token_tags[last_token + 1] == .comma, |
| | 2177 | .semicolon => token_tags[last_token + 1] == .semicolon, |
| | 2178 | }; |
| | 2179 | |
| | 2180 | try renderExpression(gpa, ais, tree, node, if (punctuation) .none else .skip); |
| | 2181 | |
| | 2182 | switch (space) { |
| | 2183 | .none, .space, .newline, .skip => {}, |
| | 2184 | .comma => { |
| | 2185 | if (token_tags[last_token + 1] == .comma) { |
| | 2186 | try renderToken(ais, tree, last_token + 1, .skip); |
| | 2187 | last_token += 1; |
| | 2188 | } else { |
| | 2189 | try ais.writer().writeByte(','); |
| | 2190 | } |
| | 2191 | }, |
| | 2192 | .comma_space => if (token_tags[last_token + 1] == .comma) { |
| | 2193 | try renderToken(ais, tree, last_token + 1, .skip); |
| | 2194 | last_token += 1; |
| | 2195 | }, |
| | 2196 | .semicolon => if (token_tags[last_token + 1] == .semicolon) { |
| | 2197 | try renderToken(ais, tree, last_token + 1, .skip); |
| | 2198 | last_token += 1; |
| | 2199 | }, |
| | 2200 | } |
| | 2201 | |
| | 2202 | ais.popIndent(); |
| | 2203 | |
| | 2204 | if (space == .skip) return; |
| | 2205 | |
| | 2206 | const comment_start = token_starts[last_token] + tokenSliceForRender(tree, last_token).len; |
| | 2207 | const comment = try renderComments(ais, tree, comment_start, token_starts[last_token + 1]); |
| | 2208 | |
| | 2209 | if (!comment) switch (space) { |
| | 2210 | .none => {}, |
| | 2211 | .space, |
| | 2212 | .comma_space, |
| | 2213 | => try ais.writer().writeByte(' '), |
| | 2214 | .newline, |
| | 2215 | .comma, |
| | 2216 | .semicolon, |
| | 2217 | => try ais.insertNewline(), |
| | 2218 | .skip => unreachable, |
| | 2219 | }; |
| | 2220 | } |
| | 2221 | |
| 2171 | /// Render an expression, and the comma that follows it, if it is present in the source. | 2222 | /// Render an expression, and the comma that follows it, if it is present in the source. |
| 2172 | fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void { | 2223 | fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void { |
| 2173 | const token_tags = tree.tokens.items(.tag); | 2224 | const token_tags = tree.tokens.items(.tag); |
| ... | @@ -2198,9 +2249,6 @@ const Space = enum { | ... | @@ -2198,9 +2249,6 @@ const Space = enum { |
| 2198 | space, | 2249 | space, |
| 2199 | /// Output the token lexeme followed by a newline. | 2250 | /// Output the token lexeme followed by a newline. |
| 2200 | newline, | 2251 | newline, |
| 2201 | /// Same as newline, but pop an indent level before rendering the | | |
| 2202 | /// following comments if any. | | |
| 2203 | newline_pop, | | |
| 2204 | /// If the next token is a comma, render it as well. If not, insert one. | 2252 | /// If the next token is a comma, render it as well. If not, insert one. |
| 2205 | /// In either case, a newline will be inserted afterwards. | 2253 | /// In either case, a newline will be inserted afterwards. |
| 2206 | comma, | 2254 | comma, |
| ... | @@ -2210,9 +2258,9 @@ const Space = enum { | ... | @@ -2210,9 +2258,9 @@ const Space = enum { |
| 2210 | /// Additionally consume the next token if it is a semicolon. | 2258 | /// Additionally consume the next token if it is a semicolon. |
| 2211 | /// In either case, a newline will be inserted afterwards. | 2259 | /// In either case, a newline will be inserted afterwards. |
| 2212 | semicolon, | 2260 | semicolon, |
| 2213 | /// Same as semicolon, but pop an indent level before rendering the | 2261 | /// Skip rendering whitespace and comments. If this is used, the caller |
| 2214 | /// following comments if any. | 2262 | /// *must* handle handle whitespace and comments manually. |
| 2215 | semicolon_pop, | 2263 | skip, |
| 2216 | }; | 2264 | }; |
| 2217 | | 2265 | |
| 2218 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { | 2266 | fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void { |
| ... | @@ -2224,65 +2272,37 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp | ... | @@ -2224,65 +2272,37 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp |
| 2224 | | 2272 | |
| 2225 | try ais.writer().writeAll(lexeme); | 2273 | try ais.writer().writeAll(lexeme); |
| 2226 | | 2274 | |
| 2227 | const token_end = token_start + lexeme.len; | 2275 | if (space == .skip) return; |
| 2228 | const next_token_start = token_starts[token_index + 1]; | | |
| 2229 | switch (space) { | | |
| 2230 | .none => _ = try renderComments(ais, tree, token_end, next_token_start), | | |
| 2231 | | | |
| 2232 | .space => if (!try renderComments(ais, tree, token_end, next_token_start)) { | | |
| 2233 | try ais.writer().writeByte(' '); | | |
| 2234 | }, | | |
| 2235 | | 2276 | |
| 2236 | .newline => if (!try renderComments(ais, tree, token_end, next_token_start)) { | 2277 | if (space == .comma and token_tags[token_index + 1] != .comma) { |
| 2237 | try ais.insertNewline(); | 2278 | try ais.writer().writeByte(','); |
| 2238 | }, | 2279 | } |
| 2239 | | 2280 | |
| 2240 | .newline_pop => { | 2281 | const comment = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]); |
| 2241 | ais.popIndent(); | 2282 | switch (space) { |
| 2242 | if (!try renderComments(ais, tree, token_end, next_token_start)) { | 2283 | .none => {}, |
| 2243 | try ais.insertNewline(); | 2284 | .space => if (!comment) try ais.writer().writeByte(' '), |
| 2244 | } | 2285 | .newline => if (!comment) try ais.insertNewline(), |
| 2245 | }, | | |
| 2246 | | 2286 | |
| 2247 | .comma => if (token_tags[token_index + 1] == .comma) { | 2287 | .comma => if (token_tags[token_index + 1] == .comma) { |
| 2248 | _ = try renderComments(ais, tree, token_end, next_token_start); | | |
| 2249 | try renderToken(ais, tree, token_index + 1, .newline); | 2288 | try renderToken(ais, tree, token_index + 1, .newline); |
| 2250 | } else { | 2289 | } else if (!comment) { |
| 2251 | try ais.writer().writeByte(','); | 2290 | try ais.insertNewline(); |
| 2252 | if (!try renderComments(ais, tree, token_end, next_token_start)) { | | |
| 2253 | try ais.insertNewline(); | | |
| 2254 | } | | |
| 2255 | }, | 2291 | }, |
| 2256 | | 2292 | |
| 2257 | .comma_space => { | 2293 | .comma_space => if (token_tags[token_index + 1] == .comma) { |
| 2258 | const comment = try renderComments(ais, tree, token_end, next_token_start); | 2294 | try renderToken(ais, tree, token_index + 1, .space); |
| 2259 | if (token_tags[token_index + 1] == .comma) { | 2295 | } else if (!comment) { |
| 2260 | try renderToken(ais, tree, token_index + 1, .space); | 2296 | try ais.writer().writeByte(' '); |
| 2261 | } else if (!comment) { | | |
| 2262 | try ais.writer().writeByte(' '); | | |
| 2263 | } | | |
| 2264 | }, | 2297 | }, |
| 2265 | | 2298 | |
| 2266 | .semicolon => { | 2299 | .semicolon => if (token_tags[token_index + 1] == .semicolon) { |
| 2267 | const comment = try renderComments(ais, tree, token_end, next_token_start); | 2300 | try renderToken(ais, tree, token_index + 1, .newline); |
| 2268 | if (token_tags[token_index + 1] == .semicolon) { | 2301 | } else if (!comment) { |
| 2269 | try renderToken(ais, tree, token_index + 1, .newline); | 2302 | try ais.insertNewline(); |
| 2270 | } else if (!comment) { | | |
| 2271 | try ais.insertNewline(); | | |
| 2272 | } | | |
| 2273 | }, | 2303 | }, |
| 2274 | | 2304 | |
| 2275 | .semicolon_pop => { | 2305 | .skip => unreachable, |
| 2276 | if (token_tags[token_index + 1] == .semicolon) { | | |
| 2277 | _ = try renderComments(ais, tree, token_end, next_token_start); | | |
| 2278 | try renderToken(ais, tree, token_index + 1, .newline_pop); | | |
| 2279 | } else { | | |
| 2280 | ais.popIndent(); | | |
| 2281 | if (!try renderComments(ais, tree, token_end, next_token_start)) { | | |
| 2282 | try ais.insertNewline(); | | |
| 2283 | } | | |
| 2284 | } | | |
| 2285 | }, | | |
| 2286 | } | 2306 | } |
| 2287 | } | 2307 | } |
| 2288 | | 2308 | |