authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-22 21:04:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-22 21:04:22-07:00
log8379fff80455f89f9673638642cf506cb73c4241
treed75907250d996f6f679d98799931dd8888baea35
parenta6038f03753a967082487020a0b834c1c4305503

zig fmt: alignment in anonymous literal


2 files changed, 395 insertions(+), 211 deletions(-)

lib/std/zig/parser_test.zig+17-17
......@@ -540,23 +540,23 @@ test "zig fmt: anon literal in array" {
540540 );
541541}
542542
543//test "zig fmt: alignment in anonymous literal" {
544// try testTransform(
545// \\const a = .{
546// \\ "U", "L", "F",
547// \\ "U'",
548// \\ "L'",
549// \\ "F'",
550// \\};
551// \\
552// ,
553// \\const a = .{
554// \\ "U", "L", "F",
555// \\ "U'", "L'", "F'",
556// \\};
557// \\
558// );
559//}
543test "zig fmt: alignment in anonymous literal" {
544 try testTransform(
545 \\const a = .{
546 \\ "U", "L", "F",
547 \\ "U'",
548 \\ "L'",
549 \\ "F'",
550 \\};
551 \\
552 ,
553 \\const a = .{
554 \\ "U", "L", "F",
555 \\ "U'", "L'", "F'",
556 \\};
557 \\
558 );
559}
560560
561561test "zig fmt: anon struct literal 0 element" {
562562 try testCanonical(
lib/std/zig/render.zig+378-194
......@@ -6,6 +6,7 @@
66const std = @import("../std.zig");
77const assert = std.debug.assert;
88const mem = std.mem;
9const Allocator = std.mem.Allocator;
910const meta = std.meta;
1011const ast = std.zig.ast;
1112const Token = std.zig.Token;
......@@ -29,7 +30,7 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {
2930 const comment_end_loc = tree.tokens.items(.start)[0];
3031 _ = try renderComments(ais, tree, 0, comment_end_loc);
3132
32 try renderMembers(ais, tree, tree.rootDecls());
33 try renderMembers(buffer.allocator, ais, tree, tree.rootDecls());
3334
3435 if (ais.disabled_offset) |disabled_offset| {
3536 try writeFixingWhitespace(ais.underlying_writer, tree.source[disabled_offset..]);
......@@ -37,17 +38,17 @@ pub fn renderTree(buffer: *std.ArrayList(u8), tree: ast.Tree) Error!void {
3738}
3839
3940/// Render all members in the given slice, keeping empty lines where appropriate
40fn renderMembers(ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void {
41fn renderMembers(gpa: *Allocator, ais: *Ais, tree: ast.Tree, members: []const ast.Node.Index) Error!void {
4142 if (members.len == 0) return;
4243 //try renderExtraNewline(ais, tree, members[0]);
43 try renderMember(ais, tree, members[0], .newline);
44 try renderMember(gpa, ais, tree, members[0], .newline);
4445 for (members[1..]) |member| {
4546 try renderExtraNewline(ais, tree, member);
46 try renderMember(ais, tree, member, .newline);
47 try renderMember(gpa, ais, tree, member, .newline);
4748 }
4849}
4950
50fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void {
51fn renderMember(gpa: *Allocator, ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) Error!void {
5152 const token_tags = tree.tokens.items(.tag);
5253 const main_tokens = tree.nodes.items(.main_token);
5354 const datas = tree.nodes.items(.data);
......@@ -87,8 +88,8 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
8788 try renderToken(ais, tree, i, .space);
8889 }
8990 assert(datas[decl].rhs != 0);
90 try renderExpression(ais, tree, fn_proto, .space);
91 return renderExpression(ais, tree, datas[decl].rhs, space);
91 try renderExpression(gpa, ais, tree, fn_proto, .space);
92 return renderExpression(gpa, ais, tree, datas[decl].rhs, space);
9293 },
9394 .fn_proto_simple,
9495 .fn_proto_multi,
......@@ -119,7 +120,7 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
119120 while (i < fn_token) : (i += 1) {
120121 try renderToken(ais, tree, i, .space);
121122 }
122 try renderExpression(ais, tree, decl, .none);
123 try renderExpression(gpa, ais, tree, decl, .none);
123124 return renderToken(ais, tree, tree.lastToken(decl) + 1, space); // semicolon
124125 },
125126
......@@ -130,14 +131,14 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
130131 try renderToken(ais, tree, main_token - 1, .space); // pub
131132 }
132133 try renderToken(ais, tree, main_token, .space); // usingnamespace
133 try renderExpression(ais, tree, expr, .none);
134 try renderExpression(gpa, ais, tree, expr, .none);
134135 return renderToken(ais, tree, tree.lastToken(expr) + 1, space); // ;
135136 },
136137
137 .global_var_decl => return renderVarDecl(ais, tree, tree.globalVarDecl(decl)),
138 .local_var_decl => return renderVarDecl(ais, tree, tree.localVarDecl(decl)),
139 .simple_var_decl => return renderVarDecl(ais, tree, tree.simpleVarDecl(decl)),
140 .aligned_var_decl => return renderVarDecl(ais, tree, tree.alignedVarDecl(decl)),
138 .global_var_decl => return renderVarDecl(gpa, ais, tree, tree.globalVarDecl(decl)),
139 .local_var_decl => return renderVarDecl(gpa, ais, tree, tree.localVarDecl(decl)),
140 .simple_var_decl => return renderVarDecl(gpa, ais, tree, tree.simpleVarDecl(decl)),
141 .aligned_var_decl => return renderVarDecl(gpa, ais, tree, tree.alignedVarDecl(decl)),
141142
142143 .test_decl => {
143144 const test_token = main_tokens[decl];
......@@ -145,13 +146,13 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
145146 if (token_tags[test_token + 1] == .string_literal) {
146147 try renderToken(ais, tree, test_token + 1, .space);
147148 }
148 try renderExpression(ais, tree, datas[decl].rhs, space);
149 try renderExpression(gpa, ais, tree, datas[decl].rhs, space);
149150 },
150151
151 .container_field_init => return renderContainerField(ais, tree, tree.containerFieldInit(decl), space),
152 .container_field_align => return renderContainerField(ais, tree, tree.containerFieldAlign(decl), space),
153 .container_field => return renderContainerField(ais, tree, tree.containerField(decl), space),
154 .@"comptime" => return renderExpression(ais, tree, decl, space),
152 .container_field_init => return renderContainerField(gpa, ais, tree, tree.containerFieldInit(decl), space),
153 .container_field_align => return renderContainerField(gpa, ais, tree, tree.containerFieldAlign(decl), space),
154 .container_field => return renderContainerField(gpa, ais, tree, tree.containerField(decl), space),
155 .@"comptime" => return renderExpression(gpa, ais, tree, decl, space),
155156
156157 .root => unreachable,
157158 else => unreachable,
......@@ -159,16 +160,16 @@ fn renderMember(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: Space) E
159160}
160161
161162/// Render all expressions in the slice, keeping empty lines where appropriate
162fn renderExpressions(ais: *Ais, tree: ast.Tree, expressions: []const ast.Node.Index, space: Space) Error!void {
163fn renderExpressions(gpa: *Allocator, ais: *Ais, tree: ast.Tree, expressions: []const ast.Node.Index, space: Space) Error!void {
163164 if (expressions.len == 0) return;
164 try renderExpression(ais, tree, expressions[0], space);
165 try renderExpression(gpa, ais, tree, expressions[0], space);
165166 for (expressions[1..]) |expression| {
166167 try renderExtraNewline(ais, tree, expression);
167 try renderExpression(ais, tree, expression, space);
168 try renderExpression(gpa, ais, tree, expression, space);
168169 }
169170}
170171
171fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
172fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
172173 const token_tags = tree.tokens.items(.tag);
173174 const main_tokens = tree.nodes.items(.main_token);
174175 const node_tags = tree.nodes.items(.tag);
......@@ -217,18 +218,18 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
217218 => {
218219 const statements = [2]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
219220 if (datas[node].lhs == 0) {
220 return renderBlock(ais, tree, node, statements[0..0], space);
221 return renderBlock(gpa, ais, tree, node, statements[0..0], space);
221222 } else if (datas[node].rhs == 0) {
222 return renderBlock(ais, tree, node, statements[0..1], space);
223 return renderBlock(gpa, ais, tree, node, statements[0..1], space);
223224 } else {
224 return renderBlock(ais, tree, node, statements[0..2], space);
225 return renderBlock(gpa, ais, tree, node, statements[0..2], space);
225226 }
226227 },
227228 .block,
228229 .block_semicolon,
229230 => {
230231 const statements = tree.extra_data[datas[node].lhs..datas[node].rhs];
231 return renderBlock(ais, tree, node, statements, space);
232 return renderBlock(gpa, ais, tree, node, statements, space);
232233 },
233234
234235 .@"errdefer" => {
......@@ -242,20 +243,20 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
242243 try renderToken(ais, tree, payload_token, .none); // identifier
243244 try renderToken(ais, tree, payload_token + 1, .space); // |
244245 }
245 return renderExpression(ais, tree, expr, space);
246 return renderExpression(gpa, ais, tree, expr, space);
246247 },
247248
248249 .@"defer" => {
249250 const defer_token = main_tokens[node];
250251 const expr = datas[node].rhs;
251252 try renderToken(ais, tree, defer_token, .space);
252 return renderExpression(ais, tree, expr, space);
253 return renderExpression(gpa, ais, tree, expr, space);
253254 },
254255 .@"comptime", .@"nosuspend" => {
255256 const comptime_token = main_tokens[node];
256257 const block = datas[node].lhs;
257258 try renderToken(ais, tree, comptime_token, .space);
258 return renderExpression(ais, tree, block, space);
259 return renderExpression(gpa, ais, tree, block, space);
259260 },
260261
261262 .@"suspend" => {
......@@ -263,7 +264,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
263264 const body = datas[node].lhs;
264265 if (body != 0) {
265266 try renderToken(ais, tree, suspend_token, .space);
266 return renderExpression(ais, tree, body, space);
267 return renderExpression(gpa, ais, tree, body, space);
267268 } else {
268269 return renderToken(ais, tree, suspend_token, space);
269270 }
......@@ -276,7 +277,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
276277 const same_line = tree.tokensOnSameLine(main_token, fallback_first);
277278 const after_op_space = if (same_line) Space.space else Space.newline;
278279
279 try renderExpression(ais, tree, datas[node].lhs, .space); // target
280 try renderExpression(gpa, ais, tree, datas[node].lhs, .space); // target
280281
281282 if (token_tags[fallback_first - 1] == .pipe) {
282283 try renderToken(ais, tree, main_token, .space); // catch keyword
......@@ -289,12 +290,12 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
289290 }
290291
291292 ais.pushIndentOneShot();
292 try renderExpression(ais, tree, datas[node].rhs, space); // fallback
293 try renderExpression(gpa, ais, tree, datas[node].rhs, space); // fallback
293294 },
294295
295296 .field_access => {
296297 const field_access = datas[node];
297 try renderExpression(ais, tree, field_access.lhs, .none);
298 try renderExpression(gpa, ais, tree, field_access.lhs, .none);
298299 try renderToken(ais, tree, main_tokens[node], .none);
299300 return renderToken(ais, tree, field_access.rhs, space);
300301 },
......@@ -303,9 +304,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
303304 .switch_range,
304305 => {
305306 const infix = datas[node];
306 try renderExpression(ais, tree, infix.lhs, .none);
307 try renderExpression(gpa, ais, tree, infix.lhs, .none);
307308 try renderToken(ais, tree, main_tokens[node], .none);
308 return renderExpression(ais, tree, infix.rhs, space);
309 return renderExpression(gpa, ais, tree, infix.rhs, space);
309310 },
310311
311312 .add,
......@@ -349,7 +350,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
349350 .@"orelse",
350351 => {
351352 const infix = datas[node];
352 try renderExpression(ais, tree, infix.lhs, .space);
353 try renderExpression(gpa, ais, tree, infix.lhs, .space);
353354 const op_token = main_tokens[node];
354355 if (tree.tokensOnSameLine(op_token, op_token + 1)) {
355356 try renderToken(ais, tree, op_token, .space);
......@@ -359,7 +360,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
359360 ais.popIndent();
360361 }
361362 ais.pushIndentOneShot();
362 return renderExpression(ais, tree, infix.rhs, space);
363 return renderExpression(gpa, ais, tree, infix.rhs, space);
363364 },
364365
365366 .bit_not,
......@@ -370,7 +371,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
370371 .address_of,
371372 => {
372373 try renderToken(ais, tree, main_tokens[node], .none);
373 return renderExpression(ais, tree, datas[node].lhs, space);
374 return renderExpression(gpa, ais, tree, datas[node].lhs, space);
374375 },
375376
376377 .@"try",
......@@ -378,79 +379,79 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
378379 .@"await",
379380 => {
380381 try renderToken(ais, tree, main_tokens[node], .space);
381 return renderExpression(ais, tree, datas[node].lhs, space);
382 return renderExpression(gpa, ais, tree, datas[node].lhs, space);
382383 },
383384
384 .array_type => return renderArrayType(ais, tree, tree.arrayType(node), space),
385 .array_type_sentinel => return renderArrayType(ais, tree, tree.arrayTypeSentinel(node), space),
385 .array_type => return renderArrayType(gpa, ais, tree, tree.arrayType(node), space),
386 .array_type_sentinel => return renderArrayType(gpa, ais, tree, tree.arrayTypeSentinel(node), space),
386387
387 .ptr_type_aligned => return renderPtrType(ais, tree, tree.ptrTypeAligned(node), space),
388 .ptr_type_sentinel => return renderPtrType(ais, tree, tree.ptrTypeSentinel(node), space),
389 .ptr_type => return renderPtrType(ais, tree, tree.ptrType(node), space),
390 .ptr_type_bit_range => return renderPtrType(ais, tree, tree.ptrTypeBitRange(node), space),
388 .ptr_type_aligned => return renderPtrType(gpa, ais, tree, tree.ptrTypeAligned(node), space),
389 .ptr_type_sentinel => return renderPtrType(gpa, ais, tree, tree.ptrTypeSentinel(node), space),
390 .ptr_type => return renderPtrType(gpa, ais, tree, tree.ptrType(node), space),
391 .ptr_type_bit_range => return renderPtrType(gpa, ais, tree, tree.ptrTypeBitRange(node), space),
391392
392393 .array_init_one, .array_init_one_comma => {
393394 var elements: [1]ast.Node.Index = undefined;
394 return renderArrayInit(ais, tree, tree.arrayInitOne(&elements, node), space);
395 return renderArrayInit(gpa, ais, tree, tree.arrayInitOne(&elements, node), space);
395396 },
396397 .array_init_dot_two, .array_init_dot_two_comma => {
397398 var elements: [2]ast.Node.Index = undefined;
398 return renderArrayInit(ais, tree, tree.arrayInitDotTwo(&elements, node), space);
399 return renderArrayInit(gpa, ais, tree, tree.arrayInitDotTwo(&elements, node), space);
399400 },
400401 .array_init_dot,
401402 .array_init_dot_comma,
402 => return renderArrayInit(ais, tree, tree.arrayInitDot(node), space),
403 => return renderArrayInit(gpa, ais, tree, tree.arrayInitDot(node), space),
403404 .array_init,
404405 .array_init_comma,
405 => return renderArrayInit(ais, tree, tree.arrayInit(node), space),
406 => return renderArrayInit(gpa, ais, tree, tree.arrayInit(node), space),
406407
407408 .struct_init_one, .struct_init_one_comma => {
408409 var fields: [1]ast.Node.Index = undefined;
409 return renderStructInit(ais, tree, tree.structInitOne(&fields, node), space);
410 return renderStructInit(gpa, ais, tree, tree.structInitOne(&fields, node), space);
410411 },
411412 .struct_init_dot_two, .struct_init_dot_two_comma => {
412413 var fields: [2]ast.Node.Index = undefined;
413 return renderStructInit(ais, tree, tree.structInitDotTwo(&fields, node), space);
414 return renderStructInit(gpa, ais, tree, tree.structInitDotTwo(&fields, node), space);
414415 },
415416 .struct_init_dot,
416417 .struct_init_dot_comma,
417 => return renderStructInit(ais, tree, tree.structInitDot(node), space),
418 => return renderStructInit(gpa, ais, tree, tree.structInitDot(node), space),
418419 .struct_init,
419420 .struct_init_comma,
420 => return renderStructInit(ais, tree, tree.structInit(node), space),
421 => return renderStructInit(gpa, ais, tree, tree.structInit(node), space),
421422
422423 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => {
423424 var params: [1]ast.Node.Index = undefined;
424 return renderCall(ais, tree, tree.callOne(&params, node), space);
425 return renderCall(gpa, ais, tree, tree.callOne(&params, node), space);
425426 },
426427
427428 .call,
428429 .call_comma,
429430 .async_call,
430431 .async_call_comma,
431 => return renderCall(ais, tree, tree.callFull(node), space),
432 => return renderCall(gpa, ais, tree, tree.callFull(node), space),
432433
433434 .array_access => {
434435 const suffix = datas[node];
435436 const lbracket = tree.firstToken(suffix.rhs) - 1;
436437 const rbracket = tree.lastToken(suffix.rhs) + 1;
437 try renderExpression(ais, tree, suffix.lhs, .none);
438 try renderExpression(gpa, ais, tree, suffix.lhs, .none);
438439 try renderToken(ais, tree, lbracket, .none); // [
439 try renderExpression(ais, tree, suffix.rhs, .none);
440 try renderExpression(gpa, ais, tree, suffix.rhs, .none);
440441 return renderToken(ais, tree, rbracket, space); // ]
441442 },
442443
443 .slice_open => return renderSlice(ais, tree, tree.sliceOpen(node), space),
444 .slice => return renderSlice(ais, tree, tree.slice(node), space),
445 .slice_sentinel => return renderSlice(ais, tree, tree.sliceSentinel(node), space),
444 .slice_open => return renderSlice(gpa, ais, tree, tree.sliceOpen(node), space),
445 .slice => return renderSlice(gpa, ais, tree, tree.slice(node), space),
446 .slice_sentinel => return renderSlice(gpa, ais, tree, tree.sliceSentinel(node), space),
446447
447448 .deref => {
448 try renderExpression(ais, tree, datas[node].lhs, .none);
449 try renderExpression(gpa, ais, tree, datas[node].lhs, .none);
449450 return renderToken(ais, tree, main_tokens[node], space);
450451 },
451452
452453 .unwrap_optional => {
453 try renderExpression(ais, tree, datas[node].lhs, .none);
454 try renderExpression(gpa, ais, tree, datas[node].lhs, .none);
454455 try renderToken(ais, tree, main_tokens[node], .none);
455456 return renderToken(ais, tree, datas[node].rhs, space);
456457 },
......@@ -463,7 +464,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
463464 try renderToken(ais, tree, main_token, space); // break keyword
464465 } else if (label_token == 0 and target != 0) {
465466 try renderToken(ais, tree, main_token, .space); // break keyword
466 try renderExpression(ais, tree, target, space);
467 try renderExpression(gpa, ais, tree, target, space);
467468 } else if (label_token != 0 and target == 0) {
468469 try renderToken(ais, tree, main_token, .space); // break keyword
469470 try renderToken(ais, tree, label_token - 1, .none); // colon
......@@ -472,7 +473,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
472473 try renderToken(ais, tree, main_token, .space); // break keyword
473474 try renderToken(ais, tree, label_token - 1, .none); // colon
474475 try renderToken(ais, tree, label_token, .space); // identifier
475 try renderExpression(ais, tree, target, space);
476 try renderExpression(gpa, ais, tree, target, space);
476477 }
477478 },
478479
......@@ -491,7 +492,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
491492 .@"return" => {
492493 if (datas[node].lhs != 0) {
493494 try renderToken(ais, tree, main_tokens[node], .space);
494 try renderExpression(ais, tree, datas[node].lhs, space);
495 try renderExpression(gpa, ais, tree, datas[node].lhs, space);
495496 } else {
496497 try renderToken(ais, tree, main_tokens[node], space);
497498 }
......@@ -500,33 +501,33 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
500501 .grouped_expression => {
501502 try renderToken(ais, tree, main_tokens[node], .none); // lparen
502503 ais.pushIndentOneShot();
503 try renderExpression(ais, tree, datas[node].lhs, .none);
504 try renderExpression(gpa, ais, tree, datas[node].lhs, .none);
504505 return renderToken(ais, tree, datas[node].rhs, space); // rparen
505506 },
506507
507508 .container_decl,
508509 .container_decl_comma,
509 => return renderContainerDecl(ais, tree, tree.containerDecl(node), space),
510 => return renderContainerDecl(gpa, ais, tree, tree.containerDecl(node), space),
510511
511512 .container_decl_two, .container_decl_two_comma => {
512513 var buffer: [2]ast.Node.Index = undefined;
513 return renderContainerDecl(ais, tree, tree.containerDeclTwo(&buffer, node), space);
514 return renderContainerDecl(gpa, ais, tree, tree.containerDeclTwo(&buffer, node), space);
514515 },
515516 .container_decl_arg,
516517 .container_decl_arg_comma,
517 => return renderContainerDecl(ais, tree, tree.containerDeclArg(node), space),
518 => return renderContainerDecl(gpa, ais, tree, tree.containerDeclArg(node), space),
518519
519520 .tagged_union,
520521 .tagged_union_comma,
521 => return renderContainerDecl(ais, tree, tree.taggedUnion(node), space),
522 => return renderContainerDecl(gpa, ais, tree, tree.taggedUnion(node), space),
522523
523524 .tagged_union_two, .tagged_union_two_comma => {
524525 var buffer: [2]ast.Node.Index = undefined;
525 return renderContainerDecl(ais, tree, tree.taggedUnionTwo(&buffer, node), space);
526 return renderContainerDecl(gpa, ais, tree, tree.taggedUnionTwo(&buffer, node), space);
526527 },
527528 .tagged_union_enum_tag,
528529 .tagged_union_enum_tag_comma,
529 => return renderContainerDecl(ais, tree, tree.taggedUnionEnumTag(node), space),
530 => return renderContainerDecl(gpa, ais, tree, tree.taggedUnionEnumTag(node), space),
530531
531532 .error_set_decl => {
532533 const error_token = main_tokens[node];
......@@ -579,35 +580,35 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
579580
580581 .builtin_call_two, .builtin_call_two_comma => {
581582 if (datas[node].lhs == 0) {
582 return renderBuiltinCall(ais, tree, main_tokens[node], &.{}, space);
583 return renderBuiltinCall(gpa, ais, tree, main_tokens[node], &.{}, space);
583584 } else if (datas[node].rhs == 0) {
584 return renderBuiltinCall(ais, tree, main_tokens[node], &.{datas[node].lhs}, space);
585 return renderBuiltinCall(gpa, ais, tree, main_tokens[node], &.{datas[node].lhs}, space);
585586 } else {
586 return renderBuiltinCall(ais, tree, main_tokens[node], &.{ datas[node].lhs, datas[node].rhs }, space);
587 return renderBuiltinCall(gpa, ais, tree, main_tokens[node], &.{ datas[node].lhs, datas[node].rhs }, space);
587588 }
588589 },
589590 .builtin_call, .builtin_call_comma => {
590591 const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
591 return renderBuiltinCall(ais, tree, main_tokens[node], params, space);
592 return renderBuiltinCall(gpa, ais, tree, main_tokens[node], params, space);
592593 },
593594
594595 .fn_proto_simple => {
595596 var params: [1]ast.Node.Index = undefined;
596 return renderFnProto(ais, tree, tree.fnProtoSimple(&params, node), space);
597 return renderFnProto(gpa, ais, tree, tree.fnProtoSimple(&params, node), space);
597598 },
598 .fn_proto_multi => return renderFnProto(ais, tree, tree.fnProtoMulti(node), space),
599 .fn_proto_multi => return renderFnProto(gpa, ais, tree, tree.fnProtoMulti(node), space),
599600 .fn_proto_one => {
600601 var params: [1]ast.Node.Index = undefined;
601 return renderFnProto(ais, tree, tree.fnProtoOne(&params, node), space);
602 return renderFnProto(gpa, ais, tree, tree.fnProtoOne(&params, node), space);
602603 },
603 .fn_proto => return renderFnProto(ais, tree, tree.fnProto(node), space),
604 .fn_proto => return renderFnProto(gpa, ais, tree, tree.fnProto(node), space),
604605
605606 .anyframe_type => {
606607 const main_token = main_tokens[node];
607608 if (datas[node].rhs != 0) {
608609 try renderToken(ais, tree, main_token, .none); // anyframe
609610 try renderToken(ais, tree, main_token + 1, .none); // ->
610 return renderExpression(ais, tree, datas[node].rhs, space);
611 return renderExpression(gpa, ais, tree, datas[node].rhs, space);
611612 } else {
612613 return renderToken(ais, tree, main_token, space); // anyframe
613614 }
......@@ -624,7 +625,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
624625
625626 try renderToken(ais, tree, switch_token, .space); // switch keyword
626627 try renderToken(ais, tree, switch_token + 1, .none); // lparen
627 try renderExpression(ais, tree, condition, .none); // condtion expression
628 try renderExpression(gpa, ais, tree, condition, .none); // condtion expression
628629 try renderToken(ais, tree, rparen, .space); // rparen
629630
630631 ais.pushIndentNextLine();
......@@ -632,26 +633,26 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
632633 try renderToken(ais, tree, rparen + 1, .none); // lbrace
633634 } else {
634635 try renderToken(ais, tree, rparen + 1, .newline); // lbrace
635 try renderExpressions(ais, tree, cases, .comma);
636 try renderExpressions(gpa, ais, tree, cases, .comma);
636637 }
637638 ais.popIndent();
638639 return renderToken(ais, tree, tree.lastToken(node), space); // rbrace
639640 },
640641
641 .switch_case_one => return renderSwitchCase(ais, tree, tree.switchCaseOne(node), space),
642 .switch_case => return renderSwitchCase(ais, tree, tree.switchCase(node), space),
642 .switch_case_one => return renderSwitchCase(gpa, ais, tree, tree.switchCaseOne(node), space),
643 .switch_case => return renderSwitchCase(gpa, ais, tree, tree.switchCase(node), space),
643644
644 .while_simple => return renderWhile(ais, tree, tree.whileSimple(node), space),
645 .while_cont => return renderWhile(ais, tree, tree.whileCont(node), space),
646 .@"while" => return renderWhile(ais, tree, tree.whileFull(node), space),
647 .for_simple => return renderWhile(ais, tree, tree.forSimple(node), space),
648 .@"for" => return renderWhile(ais, tree, tree.forFull(node), space),
645 .while_simple => return renderWhile(gpa, ais, tree, tree.whileSimple(node), space),
646 .while_cont => return renderWhile(gpa, ais, tree, tree.whileCont(node), space),
647 .@"while" => return renderWhile(gpa, ais, tree, tree.whileFull(node), space),
648 .for_simple => return renderWhile(gpa, ais, tree, tree.forSimple(node), space),
649 .@"for" => return renderWhile(gpa, ais, tree, tree.forFull(node), space),
649650
650 .if_simple => return renderIf(ais, tree, tree.ifSimple(node), space),
651 .@"if" => return renderIf(ais, tree, tree.ifFull(node), space),
651 .if_simple => return renderIf(gpa, ais, tree, tree.ifSimple(node), space),
652 .@"if" => return renderIf(gpa, ais, tree, tree.ifFull(node), space),
652653
653 .asm_simple => return renderAsm(ais, tree, tree.asmSimple(node), space),
654 .@"asm" => return renderAsm(ais, tree, tree.asmFull(node), space),
654 .asm_simple => return renderAsm(gpa, ais, tree, tree.asmSimple(node), space),
655 .@"asm" => return renderAsm(gpa, ais, tree, tree.asmFull(node), space),
655656
656657 .enum_literal => {
657658 try renderToken(ais, tree, main_tokens[node] - 1, .none); // .
......@@ -676,22 +677,24 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
676677
677678// TODO: handle comments inside the brackets
678679fn renderArrayType(
680 gpa: *Allocator,
679681 ais: *Ais,
680682 tree: ast.Tree,
681683 array_type: ast.full.ArrayType,
682684 space: Space,
683685) Error!void {
684686 try renderToken(ais, tree, array_type.ast.lbracket, .none); // lbracket
685 try renderExpression(ais, tree, array_type.ast.elem_count, .none);
687 try renderExpression(gpa, ais, tree, array_type.ast.elem_count, .none);
686688 if (array_type.ast.sentinel) |sentinel| {
687689 try renderToken(ais, tree, tree.firstToken(sentinel) - 1, .none); // colon
688 try renderExpression(ais, tree, sentinel, .none);
690 try renderExpression(gpa, ais, tree, sentinel, .none);
689691 }
690692 try renderToken(ais, tree, tree.firstToken(array_type.ast.elem_type) - 1, .none); // rbracket
691 return renderExpression(ais, tree, array_type.ast.elem_type, space);
693 return renderExpression(gpa, ais, tree, array_type.ast.elem_type, space);
692694}
693695
694696fn renderPtrType(
697 gpa: *Allocator,
695698 ais: *Ais,
696699 tree: ast.Tree,
697700 ptr_type: ast.full.PtrType,
......@@ -707,7 +710,7 @@ fn renderPtrType(
707710 if (tree.tokens.items(.tag)[ptr_type.ast.main_token] == .asterisk_asterisk and
708711 ptr_type.ast.main_token == tree.nodes.items(.main_token)[ptr_type.ast.child_type])
709712 {
710 return renderExpression(ais, tree, ptr_type.ast.child_type, space);
713 return renderExpression(gpa, ais, tree, ptr_type.ast.child_type, space);
711714 }
712715 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
713716 },
......@@ -720,7 +723,7 @@ fn renderPtrType(
720723 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
721724 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
722725 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
723 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
726 try renderExpression(gpa, ais, tree, ptr_type.ast.sentinel, .none);
724727 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
725728 }
726729 },
......@@ -737,7 +740,7 @@ fn renderPtrType(
737740 } else {
738741 try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
739742 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
740 try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
743 try renderExpression(gpa, ais, tree, ptr_type.ast.sentinel, .none);
741744 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
742745 }
743746 },
......@@ -751,13 +754,13 @@ fn renderPtrType(
751754 const align_first = tree.firstToken(ptr_type.ast.align_node);
752755 try renderToken(ais, tree, align_first - 2, .none); // align
753756 try renderToken(ais, tree, align_first - 1, .none); // lparen
754 try renderExpression(ais, tree, ptr_type.ast.align_node, .none);
757 try renderExpression(gpa, ais, tree, ptr_type.ast.align_node, .none);
755758 if (ptr_type.ast.bit_range_start != 0) {
756759 assert(ptr_type.ast.bit_range_end != 0);
757760 try renderToken(ais, tree, tree.firstToken(ptr_type.ast.bit_range_start) - 1, .none); // colon
758 try renderExpression(ais, tree, ptr_type.ast.bit_range_start, .none);
761 try renderExpression(gpa, ais, tree, ptr_type.ast.bit_range_start, .none);
759762 try renderToken(ais, tree, tree.firstToken(ptr_type.ast.bit_range_end) - 1, .none); // colon
760 try renderExpression(ais, tree, ptr_type.ast.bit_range_end, .none);
763 try renderExpression(gpa, ais, tree, ptr_type.ast.bit_range_end, .none);
761764 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.bit_range_end) + 1, .space); // rparen
762765 } else {
763766 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.align_node) + 1, .space); // rparen
......@@ -772,10 +775,11 @@ fn renderPtrType(
772775 try renderToken(ais, tree, volatile_token, .space);
773776 }
774777
775 try renderExpression(ais, tree, ptr_type.ast.child_type, space);
778 try renderExpression(gpa, ais, tree, ptr_type.ast.child_type, space);
776779}
777780
778781fn renderSlice(
782 gpa: *Allocator,
779783 ais: *Ais,
780784 tree: ast.Tree,
781785 slice: ast.full.Slice,
......@@ -787,11 +791,11 @@ fn renderSlice(
787791 const after_start_space = if (after_start_space_bool) Space.space else Space.none;
788792 const after_dots_space = if (slice.ast.end != 0) after_start_space else Space.none;
789793
790 try renderExpression(ais, tree, slice.ast.sliced, .none);
794 try renderExpression(gpa, ais, tree, slice.ast.sliced, .none);
791795 try renderToken(ais, tree, slice.ast.lbracket, .none); // lbracket
792796
793797 const start_last = tree.lastToken(slice.ast.start);
794 try renderExpression(ais, tree, slice.ast.start, after_start_space);
798 try renderExpression(gpa, ais, tree, slice.ast.start, after_start_space);
795799 try renderToken(ais, tree, start_last + 1, after_dots_space); // ellipsis2 ("..")
796800 if (slice.ast.end == 0) {
797801 return renderToken(ais, tree, start_last + 2, space); // rbracket
......@@ -799,17 +803,18 @@ fn renderSlice(
799803
800804 const end_last = tree.lastToken(slice.ast.end);
801805 const after_end_space = if (slice.ast.sentinel != 0) Space.space else Space.none;
802 try renderExpression(ais, tree, slice.ast.end, after_end_space);
806 try renderExpression(gpa, ais, tree, slice.ast.end, after_end_space);
803807 if (slice.ast.sentinel == 0) {
804808 return renderToken(ais, tree, end_last + 1, space); // rbracket
805809 }
806810
807811 try renderToken(ais, tree, end_last + 1, .none); // colon
808 try renderExpression(ais, tree, slice.ast.sentinel, .none);
812 try renderExpression(gpa, ais, tree, slice.ast.sentinel, .none);
809813 try renderToken(ais, tree, tree.lastToken(slice.ast.sentinel) + 1, space); // rbracket
810814}
811815
812816fn renderAsmOutput(
817 gpa: *Allocator,
813818 ais: *Ais,
814819 tree: ast.Tree,
815820 asm_output: ast.Node.Index,
......@@ -830,7 +835,7 @@ fn renderAsmOutput(
830835
831836 if (token_tags[symbolic_name + 4] == .arrow) {
832837 try renderToken(ais, tree, symbolic_name + 4, .space); // ->
833 try renderExpression(ais, tree, datas[asm_output].lhs, Space.none);
838 try renderExpression(gpa, ais, tree, datas[asm_output].lhs, Space.none);
834839 return renderToken(ais, tree, datas[asm_output].rhs, space); // rparen
835840 } else {
836841 try renderToken(ais, tree, symbolic_name + 4, .none); // ident
......@@ -839,6 +844,7 @@ fn renderAsmOutput(
839844}
840845
841846fn renderAsmInput(
847 gpa: *Allocator,
842848 ais: *Ais,
843849 tree: ast.Tree,
844850 asm_input: ast.Node.Index,
......@@ -855,11 +861,11 @@ fn renderAsmInput(
855861 try renderToken(ais, tree, symbolic_name + 1, .space); // rbracket
856862 try renderToken(ais, tree, symbolic_name + 2, .space); // "constraint"
857863 try renderToken(ais, tree, symbolic_name + 3, .none); // lparen
858 try renderExpression(ais, tree, datas[asm_input].lhs, Space.none);
864 try renderExpression(gpa, ais, tree, datas[asm_input].lhs, Space.none);
859865 return renderToken(ais, tree, datas[asm_input].rhs, space); // rparen
860866}
861867
862fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!void {
868fn renderVarDecl(gpa: *Allocator, ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!void {
863869 if (var_decl.visib_token) |visib_token| {
864870 try renderToken(ais, tree, visib_token, Space.space); // pub
865871 }
......@@ -896,9 +902,9 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!vo
896902 if (var_decl.ast.align_node != 0 or var_decl.ast.section_node != 0 or
897903 var_decl.ast.init_node != 0)
898904 {
899 try renderExpression(ais, tree, var_decl.ast.type_node, .space);
905 try renderExpression(gpa, ais, tree, var_decl.ast.type_node, .space);
900906 } else {
901 try renderExpression(ais, tree, var_decl.ast.type_node, .none);
907 try renderExpression(gpa, ais, tree, var_decl.ast.type_node, .none);
902908 const semicolon = tree.lastToken(var_decl.ast.type_node) + 1;
903909 return renderToken(ais, tree, semicolon, Space.newline); // ;
904910 }
......@@ -910,7 +916,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!vo
910916 const rparen = tree.lastToken(var_decl.ast.align_node) + 1;
911917 try renderToken(ais, tree, align_kw, Space.none); // align
912918 try renderToken(ais, tree, lparen, Space.none); // (
913 try renderExpression(ais, tree, var_decl.ast.align_node, Space.none);
919 try renderExpression(gpa, ais, tree, var_decl.ast.align_node, Space.none);
914920 if (var_decl.ast.section_node != 0 or var_decl.ast.init_node != 0) {
915921 try renderToken(ais, tree, rparen, .space); // )
916922 } else {
......@@ -925,7 +931,7 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!vo
925931 const rparen = tree.lastToken(var_decl.ast.section_node) + 1;
926932 try renderToken(ais, tree, section_kw, Space.none); // linksection
927933 try renderToken(ais, tree, lparen, Space.none); // (
928 try renderExpression(ais, tree, var_decl.ast.section_node, Space.none);
934 try renderExpression(gpa, ais, tree, var_decl.ast.section_node, Space.none);
929935 if (var_decl.ast.init_node != 0) {
930936 try renderToken(ais, tree, rparen, .space); // )
931937 } else {
......@@ -943,11 +949,11 @@ fn renderVarDecl(ais: *Ais, tree: ast.Tree, var_decl: ast.full.VarDecl) Error!vo
943949 ais.popIndent();
944950 }
945951 ais.pushIndentOneShot();
946 try renderExpression(ais, tree, var_decl.ast.init_node, .semicolon);
952 try renderExpression(gpa, ais, tree, var_decl.ast.init_node, .semicolon);
947953}
948954
949fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error!void {
950 return renderWhile(ais, tree, .{
955fn renderIf(gpa: *Allocator, ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error!void {
956 return renderWhile(gpa, ais, tree, .{
951957 .ast = .{
952958 .while_token = if_node.ast.if_token,
953959 .cond_expr = if_node.ast.cond_expr,
......@@ -965,7 +971,7 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.full.If, space: Space) Error
965971
966972/// Note that this function is additionally used to render if and for expressions, with
967973/// respective values set to null.
968fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void {
974fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Space) Error!void {
969975 const node_tags = tree.nodes.items(.tag);
970976 const token_tags = tree.tokens.items(.tag);
971977
......@@ -980,7 +986,7 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
980986
981987 try renderToken(ais, tree, while_node.ast.while_token, .space); // if
982988 try renderToken(ais, tree, while_node.ast.while_token + 1, .none); // lparen
983 try renderExpression(ais, tree, while_node.ast.cond_expr, .none); // condition
989 try renderExpression(gpa, ais, tree, while_node.ast.cond_expr, .none); // condition
984990
985991 const then_tag = node_tags[while_node.ast.then_expr];
986992 if (nodeIsBlock(then_tag) and !nodeIsIf(then_tag)) {
......@@ -1023,21 +1029,21 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
10231029 const lparen = tree.firstToken(while_node.ast.cont_expr) - 1;
10241030 try renderToken(ais, tree, lparen - 1, .space); // :
10251031 try renderToken(ais, tree, lparen, .none); // lparen
1026 try renderExpression(ais, tree, while_node.ast.cont_expr, .none);
1032 try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none);
10271033 const brace_space: Space = if (ais.isLineOverIndented()) .newline else .space;
10281034 try renderToken(ais, tree, rparen, brace_space); // rparen
10291035 }
10301036 if (while_node.ast.else_expr != 0) {
1031 try renderExpression(ais, tree, while_node.ast.then_expr, Space.space);
1037 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, Space.space);
10321038 try renderToken(ais, tree, while_node.else_token, .space); // else
10331039 if (while_node.error_token) |error_token| {
10341040 try renderToken(ais, tree, error_token - 1, .none); // |
10351041 try renderToken(ais, tree, error_token, .none); // identifier
10361042 try renderToken(ais, tree, error_token + 1, .space); // |
10371043 }
1038 return renderExpression(ais, tree, while_node.ast.else_expr, space);
1044 return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space);
10391045 } else {
1040 return renderExpression(ais, tree, while_node.ast.then_expr, space);
1046 return renderExpression(gpa, ais, tree, while_node.ast.then_expr, space);
10411047 }
10421048 }
10431049
......@@ -1067,11 +1073,11 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
10671073 break :blk ident + 1;
10681074 }
10691075 };
1070 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline;
1076 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline;
10711077 try renderToken(ais, tree, pipe, after_space); // |
10721078 } else {
10731079 ais.pushIndent();
1074 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline;
1080 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline;
10751081 try renderToken(ais, tree, rparen, after_space); // rparen
10761082 ais.popIndent();
10771083 }
......@@ -1080,12 +1086,12 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
10801086 const cont_lparen = tree.firstToken(while_node.ast.cont_expr) - 1;
10811087 try renderToken(ais, tree, cont_lparen - 1, .space); // :
10821088 try renderToken(ais, tree, cont_lparen, .none); // lparen
1083 try renderExpression(ais, tree, while_node.ast.cont_expr, .none);
1089 try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none);
10841090 try renderToken(ais, tree, cont_rparen, .newline); // rparen
10851091 }
10861092 if (while_node.ast.else_expr != 0) {
10871093 ais.pushIndent();
1088 try renderExpression(ais, tree, while_node.ast.then_expr, Space.newline);
1094 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, Space.newline);
10891095 ais.popIndent();
10901096 const else_is_block = nodeIsBlock(node_tags[while_node.ast.else_expr]);
10911097 if (else_is_block) {
......@@ -1095,7 +1101,7 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
10951101 try renderToken(ais, tree, error_token, .none); // identifier
10961102 try renderToken(ais, tree, error_token + 1, .space); // |
10971103 }
1098 return renderExpression(ais, tree, while_node.ast.else_expr, space);
1104 return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space);
10991105 } else {
11001106 if (while_node.error_token) |error_token| {
11011107 try renderToken(ais, tree, while_node.else_token, .space); // else
......@@ -1106,13 +1112,13 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
11061112 try renderToken(ais, tree, while_node.else_token, .newline); // else
11071113 }
11081114 ais.pushIndent();
1109 try renderExpression(ais, tree, while_node.ast.else_expr, space);
1115 try renderExpression(gpa, ais, tree, while_node.ast.else_expr, space);
11101116 ais.popIndent();
11111117 return;
11121118 }
11131119 } else {
11141120 ais.pushIndent();
1115 try renderExpression(ais, tree, while_node.ast.then_expr, space);
1121 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, space);
11161122 ais.popIndent();
11171123 return;
11181124 }
......@@ -1152,12 +1158,12 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
11521158 const cont_lparen = tree.firstToken(while_node.ast.cont_expr) - 1;
11531159 try renderToken(ais, tree, cont_lparen - 1, .space); // :
11541160 try renderToken(ais, tree, cont_lparen, .none); // lparen
1155 try renderExpression(ais, tree, while_node.ast.cont_expr, .none);
1161 try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none);
11561162 try renderToken(ais, tree, cont_rparen, .space); // rparen
11571163 }
11581164
11591165 if (while_node.ast.else_expr != 0) {
1160 try renderExpression(ais, tree, while_node.ast.then_expr, .space);
1166 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .space);
11611167 try renderToken(ais, tree, while_node.else_token, .space); // else
11621168
11631169 if (while_node.error_token) |error_token| {
......@@ -1166,13 +1172,14 @@ fn renderWhile(ais: *Ais, tree: ast.Tree, while_node: ast.full.While, space: Spa
11661172 try renderToken(ais, tree, error_token + 1, .space); // |
11671173 }
11681174
1169 return renderExpression(ais, tree, while_node.ast.else_expr, space);
1175 return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space);
11701176 } else {
1171 return renderExpression(ais, tree, while_node.ast.then_expr, space);
1177 return renderExpression(gpa, ais, tree, while_node.ast.then_expr, space);
11721178 }
11731179}
11741180
11751181fn renderContainerField(
1182 gpa: *Allocator,
11761183 ais: *Ais,
11771184 tree: ast.Tree,
11781185 field: ast.full.ContainerField,
......@@ -1190,26 +1197,26 @@ fn renderContainerField(
11901197 try renderToken(ais, tree, field.ast.name_token + 1, .space); // :
11911198
11921199 if (field.ast.align_expr != 0) {
1193 try renderExpression(ais, tree, field.ast.type_expr, .space); // type
1200 try renderExpression(gpa, ais, tree, field.ast.type_expr, .space); // type
11941201 const align_token = tree.firstToken(field.ast.align_expr) - 2;
11951202 try renderToken(ais, tree, align_token, .none); // align
11961203 try renderToken(ais, tree, align_token + 1, .none); // (
1197 try renderExpression(ais, tree, field.ast.align_expr, .none); // alignment
1204 try renderExpression(gpa, ais, tree, field.ast.align_expr, .none); // alignment
11981205 const rparen = tree.lastToken(field.ast.align_expr) + 1;
11991206 return renderTokenComma(ais, tree, rparen, space); // )
12001207 } else {
1201 return renderExpressionComma(ais, tree, field.ast.type_expr, space); // type
1208 return renderExpressionComma(gpa, ais, tree, field.ast.type_expr, space); // type
12021209 }
12031210 }
12041211 if (field.ast.type_expr == 0 and field.ast.value_expr != 0) {
12051212 try renderToken(ais, tree, field.ast.name_token, .space); // name
12061213 try renderToken(ais, tree, field.ast.name_token + 1, .space); // =
1207 return renderExpressionComma(ais, tree, field.ast.value_expr, space); // value
1214 return renderExpressionComma(gpa, ais, tree, field.ast.value_expr, space); // value
12081215 }
12091216
12101217 try renderToken(ais, tree, field.ast.name_token, .none); // name
12111218 try renderToken(ais, tree, field.ast.name_token + 1, .space); // :
1212 try renderExpression(ais, tree, field.ast.type_expr, .space); // type
1219 try renderExpression(gpa, ais, tree, field.ast.type_expr, .space); // type
12131220
12141221 if (field.ast.align_expr != 0) {
12151222 const lparen_token = tree.firstToken(field.ast.align_expr) - 1;
......@@ -1217,15 +1224,16 @@ fn renderContainerField(
12171224 const rparen_token = tree.lastToken(field.ast.align_expr) + 1;
12181225 try renderToken(ais, tree, align_kw, .none); // align
12191226 try renderToken(ais, tree, lparen_token, .none); // (
1220 try renderExpression(ais, tree, field.ast.align_expr, .none); // alignment
1227 try renderExpression(gpa, ais, tree, field.ast.align_expr, .none); // alignment
12211228 try renderToken(ais, tree, rparen_token, .space); // )
12221229 }
12231230 const eq_token = tree.firstToken(field.ast.value_expr) - 1;
12241231 try renderToken(ais, tree, eq_token, .space); // =
1225 return renderExpressionComma(ais, tree, field.ast.value_expr, space); // value
1232 return renderExpressionComma(gpa, ais, tree, field.ast.value_expr, space); // value
12261233}
12271234
12281235fn renderBuiltinCall(
1236 gpa: *Allocator,
12291237 ais: *Ais,
12301238 tree: ast.Tree,
12311239 builtin_token: ast.TokenIndex,
......@@ -1249,7 +1257,7 @@ fn renderBuiltinCall(
12491257 try renderToken(ais, tree, builtin_token + 1, .none); // (
12501258
12511259 for (params) |param_node, i| {
1252 try renderExpression(ais, tree, param_node, .none);
1260 try renderExpression(gpa, ais, tree, param_node, .none);
12531261
12541262 if (i + 1 < params.len) {
12551263 const comma_token = tree.lastToken(param_node) + 1;
......@@ -1263,7 +1271,7 @@ fn renderBuiltinCall(
12631271 try renderToken(ais, tree, builtin_token + 1, Space.newline); // (
12641272
12651273 for (params) |param_node| {
1266 try renderExpression(ais, tree, param_node, .comma);
1274 try renderExpression(gpa, ais, tree, param_node, .comma);
12671275 }
12681276 ais.popIndent();
12691277
......@@ -1271,7 +1279,7 @@ fn renderBuiltinCall(
12711279 }
12721280}
12731281
1274fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: Space) Error!void {
1282fn renderFnProto(gpa: *Allocator, ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: Space) Error!void {
12751283 const token_tags = tree.tokens.items(.tag);
12761284 const token_starts = tree.tokens.items(.start);
12771285
......@@ -1372,7 +1380,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
13721380 }
13731381 const param = fn_proto.ast.params[param_i];
13741382 param_i += 1;
1375 try renderExpression(ais, tree, param, .none);
1383 try renderExpression(gpa, ais, tree, param, .none);
13761384 last_param_token = tree.lastToken(param);
13771385 }
13781386 } else {
......@@ -1417,7 +1425,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
14171425 }
14181426 const param = fn_proto.ast.params[param_i];
14191427 param_i += 1;
1420 try renderExpression(ais, tree, param, .comma);
1428 try renderExpression(gpa, ais, tree, param, .comma);
14211429 last_param_token = tree.lastToken(param) + 1;
14221430 }
14231431 ais.popIndent();
......@@ -1431,7 +1439,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
14311439
14321440 try renderToken(ais, tree, align_lparen - 1, .none); // align
14331441 try renderToken(ais, tree, align_lparen, .none); // (
1434 try renderExpression(ais, tree, fn_proto.ast.align_expr, .none);
1442 try renderExpression(gpa, ais, tree, fn_proto.ast.align_expr, .none);
14351443 try renderToken(ais, tree, align_rparen, .space); // )
14361444 }
14371445
......@@ -1441,7 +1449,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
14411449
14421450 try renderToken(ais, tree, section_lparen - 1, .none); // section
14431451 try renderToken(ais, tree, section_lparen, .none); // (
1444 try renderExpression(ais, tree, fn_proto.ast.section_expr, .none);
1452 try renderExpression(gpa, ais, tree, fn_proto.ast.section_expr, .none);
14451453 try renderToken(ais, tree, section_rparen, .space); // )
14461454 }
14471455
......@@ -1451,7 +1459,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
14511459
14521460 try renderToken(ais, tree, callconv_lparen - 1, .none); // callconv
14531461 try renderToken(ais, tree, callconv_lparen, .none); // (
1454 try renderExpression(ais, tree, fn_proto.ast.callconv_expr, .none);
1462 try renderExpression(gpa, ais, tree, fn_proto.ast.callconv_expr, .none);
14551463 try renderToken(ais, tree, callconv_rparen, .space); // )
14561464 } else if (is_inline) {
14571465 try ais.writer().writeAll("callconv(.Inline) ");
......@@ -1460,10 +1468,11 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
14601468 if (token_tags[maybe_bang] == .bang) {
14611469 try renderToken(ais, tree, maybe_bang, .none); // !
14621470 }
1463 return renderExpression(ais, tree, fn_proto.ast.return_type, space);
1471 return renderExpression(gpa, ais, tree, fn_proto.ast.return_type, space);
14641472}
14651473
14661474fn renderSwitchCase(
1475 gpa: *Allocator,
14671476 ais: *Ais,
14681477 tree: ast.Tree,
14691478 switch_case: ast.full.SwitchCase,
......@@ -1477,14 +1486,14 @@ fn renderSwitchCase(
14771486 try renderToken(ais, tree, switch_case.ast.arrow_token - 1, .space); // else keyword
14781487 } else if (switch_case.ast.values.len == 1) {
14791488 // render on one line and drop the trailing comma if any
1480 try renderExpression(ais, tree, switch_case.ast.values[0], .space);
1489 try renderExpression(gpa, ais, tree, switch_case.ast.values[0], .space);
14811490 } else if (trailing_comma) {
14821491 // Render each value on a new line
1483 try renderExpressions(ais, tree, switch_case.ast.values, .comma);
1492 try renderExpressions(gpa, ais, tree, switch_case.ast.values, .comma);
14841493 } else {
14851494 // Render on one line
14861495 for (switch_case.ast.values) |value_expr| {
1487 try renderExpression(ais, tree, value_expr, .comma_space);
1496 try renderExpression(gpa, ais, tree, value_expr, .comma_space);
14881497 }
14891498 }
14901499
......@@ -1503,10 +1512,11 @@ fn renderSwitchCase(
15031512 }
15041513 }
15051514
1506 try renderExpression(ais, tree, switch_case.ast.target_expr, space);
1515 try renderExpression(gpa, ais, tree, switch_case.ast.target_expr, space);
15071516}
15081517
15091518fn renderBlock(
1519 gpa: *Allocator,
15101520 ais: *Ais,
15111521 tree: ast.Tree,
15121522 block_node: ast.Node.Index,
......@@ -1533,11 +1543,11 @@ fn renderBlock(
15331543 for (statements) |stmt, i| {
15341544 if (i != 0) try renderExtraNewline(ais, tree, stmt);
15351545 switch (node_tags[stmt]) {
1536 .global_var_decl => try renderVarDecl(ais, tree, tree.globalVarDecl(stmt)),
1537 .local_var_decl => try renderVarDecl(ais, tree, tree.localVarDecl(stmt)),
1538 .simple_var_decl => try renderVarDecl(ais, tree, tree.simpleVarDecl(stmt)),
1539 .aligned_var_decl => try renderVarDecl(ais, tree, tree.alignedVarDecl(stmt)),
1540 else => try renderExpression(ais, tree, stmt, .semicolon),
1546 .global_var_decl => try renderVarDecl(gpa, ais, tree, tree.globalVarDecl(stmt)),
1547 .local_var_decl => try renderVarDecl(gpa, ais, tree, tree.localVarDecl(stmt)),
1548 .simple_var_decl => try renderVarDecl(gpa, ais, tree, tree.simpleVarDecl(stmt)),
1549 .aligned_var_decl => try renderVarDecl(gpa, ais, tree, tree.alignedVarDecl(stmt)),
1550 else => try renderExpression(gpa, ais, tree, stmt, .semicolon),
15411551 }
15421552 }
15431553 }
......@@ -1548,6 +1558,7 @@ fn renderBlock(
15481558
15491559// TODO: handle comments between fields
15501560fn renderStructInit(
1561 gpa: *Allocator,
15511562 ais: *Ais,
15521563 tree: ast.Tree,
15531564 struct_init: ast.full.StructInit,
......@@ -1557,7 +1568,7 @@ fn renderStructInit(
15571568 if (struct_init.ast.type_expr == 0) {
15581569 try renderToken(ais, tree, struct_init.ast.lbrace - 1, .none); // .
15591570 } else {
1560 try renderExpression(ais, tree, struct_init.ast.type_expr, .none); // T
1571 try renderExpression(gpa, ais, tree, struct_init.ast.type_expr, .none); // T
15611572 }
15621573 if (struct_init.ast.fields.len == 0) {
15631574 try renderToken(ais, tree, struct_init.ast.lbrace, .none); // lbrace
......@@ -1573,7 +1584,7 @@ fn renderStructInit(
15731584 try renderToken(ais, tree, struct_init.ast.lbrace + 1, .none); // .
15741585 try renderToken(ais, tree, struct_init.ast.lbrace + 2, .space); // name
15751586 try renderToken(ais, tree, struct_init.ast.lbrace + 3, .space); // =
1576 try renderExpression(ais, tree, struct_init.ast.fields[0], .comma);
1587 try renderExpression(gpa, ais, tree, struct_init.ast.fields[0], .comma);
15771588
15781589 for (struct_init.ast.fields[1..]) |field_init| {
15791590 const init_token = tree.firstToken(field_init);
......@@ -1581,7 +1592,7 @@ fn renderStructInit(
15811592 try renderToken(ais, tree, init_token - 3, .none); // .
15821593 try renderToken(ais, tree, init_token - 2, .space); // name
15831594 try renderToken(ais, tree, init_token - 1, .space); // =
1584 try renderExpression(ais, tree, field_init, .comma);
1595 try renderExpression(gpa, ais, tree, field_init, .comma);
15851596 }
15861597
15871598 ais.popIndent();
......@@ -1595,7 +1606,7 @@ fn renderStructInit(
15951606 try renderToken(ais, tree, init_token - 3, .none); // .
15961607 try renderToken(ais, tree, init_token - 2, .space); // name
15971608 try renderToken(ais, tree, init_token - 1, .space); // =
1598 try renderExpression(ais, tree, field_init, .comma_space);
1609 try renderExpression(gpa, ais, tree, field_init, .comma_space);
15991610 }
16001611
16011612 return renderToken(ais, tree, last_field_token + 1, space); // rbrace
......@@ -1604,16 +1615,19 @@ fn renderStructInit(
16041615
16051616// TODO: handle comments between elements
16061617fn renderArrayInit(
1618 gpa: *Allocator,
16071619 ais: *Ais,
16081620 tree: ast.Tree,
16091621 array_init: ast.full.ArrayInit,
16101622 space: Space,
16111623) Error!void {
16121624 const token_tags = tree.tokens.items(.tag);
1625 const token_starts = tree.tokens.items(.start);
1626
16131627 if (array_init.ast.type_expr == 0) {
16141628 try renderToken(ais, tree, array_init.ast.lbrace - 1, .none); // .
16151629 } else {
1616 try renderExpression(ais, tree, array_init.ast.type_expr, .none); // T
1630 try renderExpression(gpa, ais, tree, array_init.ast.type_expr, .none); // T
16171631 }
16181632
16191633 if (array_init.ast.elements.len == 0) {
......@@ -1626,30 +1640,172 @@ fn renderArrayInit(
16261640 const last_elem = array_init.ast.elements[array_init.ast.elements.len - 1];
16271641 const last_elem_token = tree.lastToken(last_elem);
16281642 const trailing_comma = token_tags[last_elem_token + 1] == .comma;
1629 if (trailing_comma) {
1630 // Render one element per line.
1631 ais.pushIndentNextLine();
1632 try renderToken(ais, tree, array_init.ast.lbrace, .newline);
1633 try renderExpressions(ais, tree, array_init.ast.elements, .comma);
1634 ais.popIndent();
1635 return renderToken(ais, tree, last_elem_token + 2, space); // rbrace
1636 } else {
1643 if (!trailing_comma) {
16371644 // Render all on one line, no trailing comma.
16381645 if (array_init.ast.elements.len == 1) {
16391646 // If there is only one element, we don't use spaces
16401647 try renderToken(ais, tree, array_init.ast.lbrace, .none);
1641 try renderExpression(ais, tree, array_init.ast.elements[0], .none);
1648 try renderExpression(gpa, ais, tree, array_init.ast.elements[0], .none);
16421649 } else {
16431650 try renderToken(ais, tree, array_init.ast.lbrace, .space);
16441651 for (array_init.ast.elements) |elem| {
1645 try renderExpression(ais, tree, elem, .comma_space);
1652 try renderExpression(gpa, ais, tree, elem, .comma_space);
16461653 }
16471654 }
16481655 return renderToken(ais, tree, last_elem_token + 1, space); // rbrace
16491656 }
1657
1658 ais.pushIndentNextLine();
1659 try renderToken(ais, tree, array_init.ast.lbrace, .newline);
1660
1661 const rbrace = last_elem_token + 2;
1662 assert(token_tags[rbrace] == .r_brace);
1663
1664 var expr_index: usize = 0;
1665 while (rowSize(tree, array_init.ast.elements[expr_index..], rbrace)) |row_size| {
1666 const row_exprs = array_init.ast.elements[expr_index..];
1667 // A place to store the width of each expression and its column's maximum
1668 const widths = try gpa.alloc(usize, row_exprs.len + row_size);
1669 defer gpa.free(widths);
1670 mem.set(usize, widths, 0);
1671
1672 const expr_newlines = try gpa.alloc(bool, row_exprs.len);
1673 defer gpa.free(expr_newlines);
1674 mem.set(bool, expr_newlines, false);
1675
1676 const expr_widths = widths[0 .. widths.len - row_size];
1677 const column_widths = widths[widths.len - row_size ..];
1678
1679 // Find next row with trailing comment (if any) to end the current section
1680 const section_end = sec_end: {
1681 var this_line_first_expr: usize = 0;
1682 var this_line_size = rowSize(tree, row_exprs, rbrace);
1683 for (row_exprs) |expr, i| {
1684 // Ignore comment on first line of this section
1685 if (i == 0 or tree.tokensOnSameLine(tree.firstToken(row_exprs[0]), tree.lastToken(expr))) continue;
1686 // Track start of line containing comment
1687 if (!tree.tokensOnSameLine(tree.firstToken(row_exprs[this_line_first_expr]), tree.lastToken(expr))) {
1688 this_line_first_expr = i;
1689 this_line_size = rowSize(tree, row_exprs[this_line_first_expr..], rbrace);
1690 }
1691
1692 const maybe_comma = tree.lastToken(expr) + 1;
1693 if (token_tags[maybe_comma] == .comma) {
1694 const after_comma_src = tree.source[token_starts[maybe_comma]..token_starts[maybe_comma + 1]];
1695 const same_line_comment = for (after_comma_src) |byte| switch (byte) {
1696 '\n' => break,
1697 '/' => break :sec_end i - this_line_size.? + 1, // Found row ending in comment
1698 else => continue,
1699 };
1700 }
1701 }
1702 break :sec_end row_exprs.len;
1703 };
1704 expr_index += section_end;
1705
1706 const section_exprs = row_exprs[0..section_end];
1707
1708 var sub_expr_buffer = std.ArrayList(u8).init(gpa);
1709 defer sub_expr_buffer.deinit();
1710
1711 var auto_indenting_stream = Ais{
1712 .indent_delta = indent_delta,
1713 .underlying_writer = sub_expr_buffer.writer(),
1714 };
1715
1716 // Calculate size of columns in current section
1717 var column_counter: usize = 0;
1718 var single_line = true;
1719 var contains_newline = false;
1720 for (section_exprs) |expr, i| {
1721 sub_expr_buffer.shrinkRetainingCapacity(0);
1722 if (i + 1 < section_exprs.len) {
1723 try renderExpression(gpa, &auto_indenting_stream, tree, expr, .none);
1724 const width = sub_expr_buffer.items.len;
1725 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items, '\n') != null;
1726 contains_newline = contains_newline or this_contains_newline;
1727 expr_widths[i] = width;
1728 expr_newlines[i] = this_contains_newline;
1729
1730 if (!this_contains_newline) {
1731 const column = column_counter % row_size;
1732 column_widths[column] = std.math.max(column_widths[column], width);
1733
1734 const expr_last_token = tree.lastToken(expr) + 1;
1735 const next_expr = section_exprs[i + 1];
1736 column_counter += 1;
1737 if (!tree.tokensOnSameLine(expr_last_token, tree.firstToken(next_expr))) single_line = false;
1738 } else {
1739 single_line = false;
1740 column_counter = 0;
1741 }
1742 } else {
1743 try renderExpression(gpa, &auto_indenting_stream, tree, expr, .none);
1744 const width = sub_expr_buffer.items.len;
1745 contains_newline = contains_newline or mem.indexOfScalar(u8, sub_expr_buffer.items, '\n') != null;
1746 expr_widths[i] = width;
1747 expr_newlines[i] = contains_newline;
1748
1749 if (!contains_newline) {
1750 const column = column_counter % row_size;
1751 column_widths[column] = std.math.max(column_widths[column], width);
1752 }
1753 break;
1754 }
1755 }
1756
1757 // Render exprs in current section
1758 column_counter = 0;
1759 var last_col_index: usize = row_size - 1;
1760 for (section_exprs) |expr, i| {
1761 if (i + 1 < section_exprs.len) {
1762 const next_expr = section_exprs[i + 1];
1763 try renderExpression(gpa, ais, tree, expr, .none);
1764
1765 const comma = tree.lastToken(expr) + 1;
1766
1767 if (column_counter != last_col_index) {
1768 if (!expr_newlines[i] and !expr_newlines[i + 1]) {
1769 // Neither the current or next expression is multiline
1770 try renderToken(ais, tree, comma, .space); // ,
1771 assert(column_widths[column_counter % row_size] >= expr_widths[i]);
1772 const padding = column_widths[column_counter % row_size] - expr_widths[i];
1773 try ais.writer().writeByteNTimes(' ', padding);
1774
1775 column_counter += 1;
1776 continue;
1777 }
1778 }
1779 if (single_line and row_size != 1) {
1780 try renderToken(ais, tree, comma, .space); // ,
1781 continue;
1782 }
1783
1784 column_counter = 0;
1785 try renderToken(ais, tree, comma, .newline); // ,
1786 try renderExtraNewline(ais, tree, next_expr);
1787 } else {
1788 const maybe_comma = tree.lastToken(expr) + 1;
1789 if (token_tags[maybe_comma] == .comma) {
1790 try renderExpression(gpa, ais, tree, expr, .none); // ,
1791 try renderToken(ais, tree, maybe_comma, .newline); // ,
1792 } else {
1793 try renderExpression(gpa, ais, tree, expr, .comma); // ,
1794 }
1795 }
1796 }
1797
1798 if (expr_index == array_init.ast.elements.len) {
1799 break;
1800 }
1801 }
1802
1803 ais.popIndent();
1804 return renderToken(ais, tree, rbrace, space); // rbrace
16501805}
16511806
16521807fn renderContainerDecl(
1808 gpa: *Allocator,
16531809 ais: *Ais,
16541810 tree: ast.Tree,
16551811 container_decl: ast.full.ContainerDecl,
......@@ -1669,7 +1825,7 @@ fn renderContainerDecl(
16691825 try renderToken(ais, tree, enum_token, .none); // enum
16701826 if (container_decl.ast.arg != 0) {
16711827 try renderToken(ais, tree, enum_token + 1, .none); // lparen
1672 try renderExpression(ais, tree, container_decl.ast.arg, .none);
1828 try renderExpression(gpa, ais, tree, container_decl.ast.arg, .none);
16731829 const rparen = tree.lastToken(container_decl.ast.arg) + 1;
16741830 try renderToken(ais, tree, rparen, .none); // rparen
16751831 try renderToken(ais, tree, rparen + 1, .space); // rparen
......@@ -1681,7 +1837,7 @@ fn renderContainerDecl(
16811837 } else if (container_decl.ast.arg != 0) {
16821838 try renderToken(ais, tree, container_decl.ast.main_token, .none); // union
16831839 try renderToken(ais, tree, container_decl.ast.main_token + 1, .none); // lparen
1684 try renderExpression(ais, tree, container_decl.ast.arg, .none);
1840 try renderExpression(gpa, ais, tree, container_decl.ast.arg, .none);
16851841 const rparen = tree.lastToken(container_decl.ast.arg) + 1;
16861842 try renderToken(ais, tree, rparen, .space); // rparen
16871843 lbrace = rparen + 1;
......@@ -1717,7 +1873,7 @@ fn renderContainerDecl(
17171873 // All the declarations on the same line.
17181874 try renderToken(ais, tree, lbrace, .space); // lbrace
17191875 for (container_decl.ast.members) |member| {
1720 try renderMember(ais, tree, member, .space);
1876 try renderMember(gpa, ais, tree, member, .space);
17211877 }
17221878 return renderToken(ais, tree, rbrace, space); // rbrace
17231879 }
......@@ -1725,13 +1881,14 @@ fn renderContainerDecl(
17251881 // One member per line.
17261882 ais.pushIndentNextLine();
17271883 try renderToken(ais, tree, lbrace, .newline); // lbrace
1728 try renderMembers(ais, tree, container_decl.ast.members);
1884 try renderMembers(gpa, ais, tree, container_decl.ast.members);
17291885 ais.popIndent();
17301886
17311887 return renderToken(ais, tree, rbrace, space); // rbrace
17321888}
17331889
17341890fn renderAsm(
1891 gpa: *Allocator,
17351892 ais: *Ais,
17361893 tree: ast.Tree,
17371894 asm_node: ast.full.Asm,
......@@ -1749,7 +1906,7 @@ fn renderAsm(
17491906 }
17501907
17511908 if (asm_node.ast.items.len == 0) {
1752 try renderExpression(ais, tree, asm_node.ast.template, .none);
1909 try renderExpression(gpa, ais, tree, asm_node.ast.template, .none);
17531910 if (asm_node.first_clobber) |first_clobber| {
17541911 // asm ("foo" ::: "a", "b")
17551912 var tok_i = first_clobber;
......@@ -1769,7 +1926,7 @@ fn renderAsm(
17691926 }
17701927
17711928 ais.pushIndent();
1772 try renderExpression(ais, tree, asm_node.ast.template, .newline);
1929 try renderExpression(gpa, ais, tree, asm_node.ast.template, .newline);
17731930 ais.setIndentDelta(asm_indent_delta);
17741931 const colon1 = tree.lastToken(asm_node.ast.template) + 1;
17751932
......@@ -1783,19 +1940,19 @@ fn renderAsm(
17831940 for (asm_node.outputs) |asm_output, i| {
17841941 if (i + 1 < asm_node.outputs.len) {
17851942 const next_asm_output = asm_node.outputs[i + 1];
1786 try renderAsmOutput(ais, tree, asm_output, .none);
1943 try renderAsmOutput(gpa, ais, tree, asm_output, .none);
17871944
17881945 const comma = tree.firstToken(next_asm_output) - 1;
17891946 try renderToken(ais, tree, comma, .newline); // ,
17901947 try renderExtraNewlineToken(ais, tree, tree.firstToken(next_asm_output));
17911948 } else if (asm_node.inputs.len == 0 and asm_node.first_clobber == null) {
1792 try renderAsmOutput(ais, tree, asm_output, .newline);
1949 try renderAsmOutput(gpa, ais, tree, asm_output, .newline);
17931950 ais.popIndent();
17941951 ais.setIndentDelta(indent_delta);
17951952 ais.popIndent();
17961953 return renderToken(ais, tree, asm_node.ast.rparen, space); // rparen
17971954 } else {
1798 try renderAsmOutput(ais, tree, asm_output, .newline);
1955 try renderAsmOutput(gpa, ais, tree, asm_output, .newline);
17991956 const comma_or_colon = tree.lastToken(asm_output) + 1;
18001957 ais.popIndent();
18011958 break :colon2 switch (token_tags[comma_or_colon]) {
......@@ -1815,19 +1972,19 @@ fn renderAsm(
18151972 for (asm_node.inputs) |asm_input, i| {
18161973 if (i + 1 < asm_node.inputs.len) {
18171974 const next_asm_input = asm_node.inputs[i + 1];
1818 try renderAsmInput(ais, tree, asm_input, .none);
1975 try renderAsmInput(gpa, ais, tree, asm_input, .none);
18191976
18201977 const first_token = tree.firstToken(next_asm_input);
18211978 try renderToken(ais, tree, first_token - 1, .newline); // ,
18221979 try renderExtraNewlineToken(ais, tree, first_token);
18231980 } else if (asm_node.first_clobber == null) {
1824 try renderAsmInput(ais, tree, asm_input, .newline);
1981 try renderAsmInput(gpa, ais, tree, asm_input, .newline);
18251982 ais.popIndent();
18261983 ais.setIndentDelta(indent_delta);
18271984 ais.popIndent();
18281985 return renderToken(ais, tree, asm_node.ast.rparen, space); // rparen
18291986 } else {
1830 try renderAsmInput(ais, tree, asm_input, .newline);
1987 try renderAsmInput(gpa, ais, tree, asm_input, .newline);
18311988 const comma_or_colon = tree.lastToken(asm_input) + 1;
18321989 ais.popIndent();
18331990 break :colon3 switch (token_tags[comma_or_colon]) {
......@@ -1861,6 +2018,7 @@ fn renderAsm(
18612018}
18622019
18632020fn renderCall(
2021 gpa: *Allocator,
18642022 ais: *Ais,
18652023 tree: ast.Tree,
18662024 call: ast.full.Call,
......@@ -1872,7 +2030,7 @@ fn renderCall(
18722030 if (call.async_token) |async_token| {
18732031 try renderToken(ais, tree, async_token, .space);
18742032 }
1875 try renderExpression(ais, tree, call.ast.fn_expr, .none);
2033 try renderExpression(gpa, ais, tree, call.ast.fn_expr, .none);
18762034
18772035 const lparen = call.ast.lparen;
18782036 const params = call.ast.params;
......@@ -1890,7 +2048,7 @@ fn renderCall(
18902048 try renderToken(ais, tree, lparen, .newline); // (
18912049 for (params) |param_node, i| {
18922050 if (i + 1 < params.len) {
1893 try renderExpression(ais, tree, param_node, .none);
2051 try renderExpression(gpa, ais, tree, param_node, .none);
18942052
18952053 // Unindent the comma for multiline string literals.
18962054 const is_multiline_string =
......@@ -1904,7 +2062,7 @@ fn renderCall(
19042062
19052063 try renderExtraNewline(ais, tree, params[i + 1]);
19062064 } else {
1907 try renderExpression(ais, tree, param_node, .comma);
2065 try renderExpression(gpa, ais, tree, param_node, .comma);
19082066 }
19092067 }
19102068 ais.popIndent();
......@@ -1919,7 +2077,7 @@ fn renderCall(
19192077 if (this_multiline_string) {
19202078 ais.pushIndentOneShot();
19212079 }
1922 try renderExpression(ais, tree, param_node, .none);
2080 try renderExpression(gpa, ais, tree, param_node, .none);
19232081
19242082 if (i + 1 < params.len) {
19252083 const comma = tree.lastToken(param_node) + 1;
......@@ -1934,14 +2092,14 @@ fn renderCall(
19342092}
19352093
19362094/// Render an expression, and the comma that follows it, if it is present in the source.
1937fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
2095fn renderExpressionComma(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
19382096 const token_tags = tree.tokens.items(.tag);
19392097 const maybe_comma = tree.lastToken(node) + 1;
19402098 if (token_tags[maybe_comma] == .comma) {
1941 try renderExpression(ais, tree, node, .none);
2099 try renderExpression(gpa, ais, tree, node, .none);
19422100 return renderToken(ais, tree, maybe_comma, space);
19432101 } else {
1944 return renderExpression(ais, tree, node, space);
2102 return renderExpression(gpa, ais, tree, node, space);
19452103 }
19462104}
19472105
......@@ -2218,6 +2376,32 @@ fn nodeCausesSliceOpSpace(tag: ast.Node.Tag) bool {
22182376 };
22192377}
22202378
2379// Returns the number of nodes in `expr` that are on the same line as `rtoken`,
2380// or null if they all are on the same line.
2381fn rowSize(tree: ast.Tree, exprs: []const ast.Node.Index, rtoken: ast.TokenIndex) ?usize {
2382 const token_tags = tree.tokens.items(.tag);
2383
2384 const first_token = tree.firstToken(exprs[0]);
2385 if (tree.tokensOnSameLine(first_token, rtoken)) {
2386 const maybe_comma = rtoken - 1;
2387 if (token_tags[maybe_comma] == .comma)
2388 return 1;
2389 return null; // no newlines
2390 }
2391
2392 var count: usize = 1;
2393 for (exprs) |expr, i| {
2394 if (i + 1 < exprs.len) {
2395 const expr_last_token = tree.lastToken(expr) + 1;
2396 if (!tree.tokensOnSameLine(expr_last_token, tree.firstToken(exprs[i + 1]))) return count;
2397 count += 1;
2398 } else {
2399 return count;
2400 }
2401 }
2402 unreachable;
2403}
2404
22212405/// Automatically inserts indentation of written data by keeping
22222406/// track of the current indentation level
22232407fn AutoIndentingStream(comptime UnderlyingWriter: type) type {