authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-19 23:07:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-19 23:08:48-04:00
log82225f6568969856ffe9363d2b8b0f39548bd9df
treea74377f8e12cfd8c26fb001dc90a6230ff28c5cb
parent93384f7428c5186a1b44c6f5f8891ce40bc46e72

zig fmt parser tests are compiling again


2 files changed, 238 insertions(+), 185 deletions(-)

lib/std/zig/ast.zig+2-2
......@@ -36,7 +36,7 @@ pub const Tree = struct {
3636 return self.tokenSlicePtr(self.tokens[token_index]);
3737 }
3838
39 pub fn tokenSlicePtr(self: *Tree, token: *const Token) []const u8 {
39 pub fn tokenSlicePtr(self: *Tree, token: Token) []const u8 {
4040 return self.source[token.start..token.end];
4141 }
4242
......@@ -89,7 +89,7 @@ pub const Tree = struct {
8989 return self.tokensOnSameLinePtr(self.tokens[token1_index], self.tokens[token2_index]);
9090 }
9191
92 pub fn tokensOnSameLinePtr(self: *Tree, token1: *const Token, token2: *const Token) bool {
92 pub fn tokensOnSameLinePtr(self: *Tree, token1: Token, token2: Token) bool {
9393 return mem.indexOfScalar(u8, self.source[token1.end..token2.start], '\n') == null;
9494 }
9595
lib/std/zig/render.zig+236-183
......@@ -68,7 +68,7 @@ fn renderRoot(
6868 tree: *ast.Tree,
6969) (@TypeOf(stream).Error || Error)!void {
7070 // render all the line comments at the beginning of the file
71 for (tree.tokens) |*token, i| {
71 for (tree.tokens) |token, i| {
7272 if (token.id != .LineComment) break;
7373 try stream.print("{}\n", .{mem.trimRight(u8, tree.tokenSlicePtr(token), " ")});
7474 const next_token = &tree.tokens[i + 1];
......@@ -321,10 +321,10 @@ fn renderContainerDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree,
321321
322322 .DocComment => {
323323 const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl);
324 var it = comment.lines.iterator(0);
325 while (it.next()) |line_token_index| {
326 try renderToken(tree, stream, line_token_index.*, indent, start_col, .Newline);
327 if (it.peek()) |_| {
324 var it = comment.lines.first;
325 while (it) |node| : (it = node.next) {
326 try renderToken(tree, stream, node.data, indent, start_col, .Newline);
327 if (node.next != null) {
328328 try stream.writeByteNTimes(' ', indent);
329329 }
330330 }
......@@ -355,20 +355,21 @@ fn renderExpression(
355355 try renderToken(tree, stream, tree.nextToken(label), indent, start_col, Space.Space);
356356 }
357357
358 if (block.statements.len == 0) {
358 if (block.statements.first == null) {
359359 try renderToken(tree, stream, block.lbrace, indent + indent_delta, start_col, Space.None);
360360 return renderToken(tree, stream, block.rbrace, indent, start_col, space);
361361 } else {
362362 const block_indent = indent + indent_delta;
363363 try renderToken(tree, stream, block.lbrace, block_indent, start_col, Space.Newline);
364364
365 var it = block.statements.iterator(0);
366 while (it.next()) |statement| {
365 var it = block.statements.first;
366 while (it) |statement_node| : (it = statement_node.next) {
367 const statement = statement_node.data;
367368 try stream.writeByteNTimes(' ', block_indent);
368 try renderStatement(allocator, stream, tree, block_indent, start_col, statement.*);
369 try renderStatement(allocator, stream, tree, block_indent, start_col, statement);
369370
370 if (it.peek()) |next_statement| {
371 try renderExtraNewline(tree, stream, start_col, next_statement.*);
371 if (statement_node.next) |next_statement| {
372 try renderExtraNewline(tree, stream, start_col, next_statement.data);
372373 }
373374 }
374375
......@@ -620,7 +621,7 @@ fn renderExpression(
620621
621622 const lparen = tree.nextToken(suffix_op.lhs.node.lastToken());
622623
623 if (call_info.params.len == 0) {
624 if (call_info.params.first == null) {
624625 try renderToken(tree, stream, lparen, indent, start_col, Space.None);
625626 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
626627 }
......@@ -634,24 +635,26 @@ fn renderExpression(
634635 const new_indent = indent + indent_delta;
635636 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline);
636637
637 var it = call_info.params.iterator(0);
638 var it = call_info.params.first;
638639 while (true) {
639 const param_node = it.next().?;
640 const param_node_node = it.?;
641 it = param_node_node.next;
642 const param_node = param_node_node.data;
640643
641 const param_node_new_indent = if (param_node.*.id == .MultilineStringLiteral) blk: {
644 const param_node_new_indent = if (param_node.id == .MultilineStringLiteral) blk: {
642645 break :blk indent;
643646 } else blk: {
644647 try stream.writeByteNTimes(' ', new_indent);
645648 break :blk new_indent;
646649 };
647650
648 if (it.peek()) |next_node| {
649 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.None);
650 const comma = tree.nextToken(param_node.*.lastToken());
651 if (it) |next_node| {
652 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node, Space.None);
653 const comma = tree.nextToken(param_node.lastToken());
651654 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
652 try renderExtraNewline(tree, stream, start_col, next_node.*);
655 try renderExtraNewline(tree, stream, start_col, next_node.data);
653656 } else {
654 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node.*, Space.Comma);
657 try renderExpression(allocator, stream, tree, param_node_new_indent, start_col, param_node, Space.Comma);
655658 try stream.writeByteNTimes(' ', indent);
656659 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
657660 }
......@@ -660,12 +663,13 @@ fn renderExpression(
660663
661664 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
662665
663 var it = call_info.params.iterator(0);
664 while (it.next()) |param_node| {
665 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);
666 var it = call_info.params.first;
667 while (it) |param_node_node| : (it = param_node_node.next) {
668 const param_node = param_node_node.data;
669 try renderExpression(allocator, stream, tree, indent, start_col, param_node, Space.None);
666670
667 if (it.peek() != null) {
668 const comma = tree.nextToken(param_node.*.lastToken());
671 if (param_node_node.next != null) {
672 const comma = tree.nextToken(param_node.lastToken());
669673 try renderToken(tree, stream, comma, indent, start_col, Space.Space);
670674 }
671675 }
......@@ -736,7 +740,7 @@ fn renderExpression(
736740 .node => |node| tree.nextToken(node.lastToken()),
737741 };
738742
739 if (field_inits.len == 0) {
743 if (field_inits.first == null) {
740744 switch (suffix_op.lhs) {
741745 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
742746 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
......@@ -757,18 +761,19 @@ fn renderExpression(
757761
758762 const expr_outputs_one_line = blk: {
759763 // render field expressions until a LF is found
760 var it = field_inits.iterator(0);
761 while (it.next()) |field_init| {
764 var it = field_inits.first;
765 while (it) |field_init_node| : (it = field_init_node.next) {
766 const field_init = field_init_node.data;
762767 var find_stream = FindByteOutStream.init('\n');
763768 var dummy_col: usize = 0;
764 try renderExpression(allocator, find_stream.outStream(), tree, 0, &dummy_col, field_init.*, Space.None);
769 try renderExpression(allocator, find_stream.outStream(), tree, 0, &dummy_col, field_init, Space.None);
765770 if (find_stream.byte_found) break :blk false;
766771 }
767772 break :blk true;
768773 };
769774
770 if (field_inits.len == 1) blk: {
771 const field_init = field_inits.at(0).*.cast(ast.Node.FieldInitializer).?;
775 if (field_inits.first != null and field_inits.first.?.next == null) blk: {
776 const field_init = field_inits.first.?.data.cast(ast.Node.FieldInitializer).?;
772777
773778 if (field_init.expr.cast(ast.Node.SuffixOp)) |nested_suffix_op| {
774779 if (nested_suffix_op.op == .StructInitializer) {
......@@ -798,15 +803,16 @@ fn renderExpression(
798803 }
799804 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
800805
801 var it = field_inits.iterator(0);
802 while (it.next()) |field_init| {
803 if (it.peek() != null) {
804 try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.None);
806 var it = field_inits.first;
807 while (it) |field_init_node| : (it = field_init_node.next) {
808 const field_init = field_init_node.data;
809 if (field_init_node.next != null) {
810 try renderExpression(allocator, stream, tree, indent, start_col, field_init, Space.None);
805811
806 const comma = tree.nextToken(field_init.*.lastToken());
812 const comma = tree.nextToken(field_init.lastToken());
807813 try renderToken(tree, stream, comma, indent, start_col, Space.Space);
808814 } else {
809 try renderExpression(allocator, stream, tree, indent, start_col, field_init.*, Space.Space);
815 try renderExpression(allocator, stream, tree, indent, start_col, field_init, Space.Space);
810816 }
811817 }
812818
......@@ -821,19 +827,20 @@ fn renderExpression(
821827 }
822828 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
823829
824 var it = field_inits.iterator(0);
825 while (it.next()) |field_init| {
830 var it = field_inits.first;
831 while (it) |field_init_node| : (it = field_init_node.next) {
832 const field_init = field_init_node.data;
826833 try stream.writeByteNTimes(' ', new_indent);
827834
828 if (it.peek()) |next_field_init| {
829 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.None);
835 if (field_init_node.next) |next_field_init| {
836 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init, Space.None);
830837
831 const comma = tree.nextToken(field_init.*.lastToken());
838 const comma = tree.nextToken(field_init.lastToken());
832839 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline);
833840
834 try renderExtraNewline(tree, stream, start_col, next_field_init.*);
841 try renderExtraNewline(tree, stream, start_col, next_field_init.data);
835842 } else {
836 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init.*, Space.Comma);
843 try renderExpression(allocator, stream, tree, new_indent, start_col, field_init, Space.Comma);
837844 }
838845 }
839846
......@@ -847,7 +854,7 @@ fn renderExpression(
847854 .node => |node| tree.nextToken(node.lastToken()),
848855 };
849856
850 if (exprs.len == 0) {
857 if (exprs.first == null) {
851858 switch (suffix_op.lhs) {
852859 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
853860 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
......@@ -855,16 +862,17 @@ fn renderExpression(
855862 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
856863 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
857864 }
858 if (exprs.len == 1 and tree.tokens[exprs.at(0).*.lastToken() + 1].id == .RBrace) {
859 const expr = exprs.at(0).*;
860
861 switch (suffix_op.lhs) {
862 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
863 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
865 if (exprs.first) |first_expr_node| {
866 const expr = first_expr_node.data;
867 if (first_expr_node.next == null and tree.tokens[expr.lastToken() + 1].id == .RBrace) {
868 switch (suffix_op.lhs) {
869 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
870 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
871 }
872 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
873 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
874 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
864875 }
865 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
866 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
867 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
868876 }
869877
870878 switch (suffix_op.lhs) {
......@@ -875,16 +883,18 @@ fn renderExpression(
875883 // scan to find row size
876884 const maybe_row_size: ?usize = blk: {
877885 var count: usize = 1;
878 var it = exprs.iterator(0);
886 var it = exprs.first;
879887 while (true) {
880 const expr = it.next().?.*;
881 if (it.peek()) |next_expr| {
882 const expr_last_token = expr.*.lastToken() + 1;
883 const loc = tree.tokenLocation(tree.tokens[expr_last_token].end, next_expr.*.firstToken());
888 const expr_node = it.?;
889 it = expr_node.next;
890 const expr = expr_node.data;
891 if (expr_node.next) |next_expr| {
892 const expr_last_token = expr.lastToken() + 1;
893 const loc = tree.tokenLocation(tree.tokens[expr_last_token].end, next_expr.data.firstToken());
884894 if (loc.line != 0) break :blk count;
885895 count += 1;
886896 } else {
887 const expr_last_token = expr.*.lastToken();
897 const expr_last_token = expr.lastToken();
888898 const loc = tree.tokenLocation(tree.tokens[expr_last_token].end, suffix_op.rtoken);
889899 if (loc.line == 0) {
890900 // all on one line
......@@ -905,7 +915,8 @@ fn renderExpression(
905915
906916 if (maybe_row_size) |row_size| {
907917 // A place to store the width of each expression and its column's maximum
908 var widths = try allocator.alloc(usize, exprs.len + row_size);
918 const exprs_len = countLen(exprs.first);
919 var widths = try allocator.alloc(usize, exprs_len + row_size);
909920 defer allocator.free(widths);
910921 mem.set(usize, widths, 0);
911922
......@@ -915,13 +926,14 @@ fn renderExpression(
915926 // Null stream for counting the printed length of each expression
916927 var counting_stream = std.io.countingOutStream(std.io.null_out_stream);
917928
918 var it = exprs.iterator(0);
929 var it = exprs.first;
919930 var i: usize = 0;
920931
921 while (it.next()) |expr| : (i += 1) {
932 while (it) |expr_node| : ({i += 1; it = expr_node.next;}) {
933 const expr = expr_node.data;
922934 counting_stream.bytes_written = 0;
923935 var dummy_col: usize = 0;
924 try renderExpression(allocator, counting_stream.outStream(), tree, indent, &dummy_col, expr.*, Space.None);
936 try renderExpression(allocator, counting_stream.outStream(), tree, indent, &dummy_col, expr, Space.None);
925937 const width = @intCast(usize, counting_stream.bytes_written);
926938 const col = i % row_size;
927939 column_widths[col] = std.math.max(column_widths[col], width);
......@@ -938,14 +950,16 @@ fn renderExpression(
938950 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.None);
939951 }
940952
941 it.set(0);
953 it = exprs.first;
942954 i = 0;
943955 var col: usize = 1;
944 while (it.next()) |expr| : (i += 1) {
945 if (it.peek()) |next_expr| {
946 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.None);
956 var last_node = it.?;
957 while (it) |expr_node| : ({i += 1; it = expr_node.next; last_node = expr_node;}) {
958 const expr = expr_node.data;
959 if (expr_node.next) |next_expr| {
960 try renderExpression(allocator, stream, tree, new_indent, start_col, expr, Space.None);
947961
948 const comma = tree.nextToken(expr.*.lastToken());
962 const comma = tree.nextToken(expr.lastToken());
949963
950964 if (col != row_size) {
951965 try renderToken(tree, stream, comma, new_indent, start_col, Space.Space); // ,
......@@ -964,29 +978,29 @@ fn renderExpression(
964978 try renderToken(tree, stream, comma, new_indent, start_col, Space.None); // ,
965979 }
966980
967 try renderExtraNewline(tree, stream, start_col, next_expr.*);
968 if (next_expr.*.id != .MultilineStringLiteral) {
981 try renderExtraNewline(tree, stream, start_col, next_expr.data);
982 if (next_expr.data.id != .MultilineStringLiteral) {
969983 try stream.writeByteNTimes(' ', new_indent);
970984 }
971985 } else {
972 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,
986 try renderExpression(allocator, stream, tree, new_indent, start_col, expr, Space.Comma); // ,
973987 }
974988 }
975 const last_node = it.prev().?;
976 if (last_node.*.id != .MultilineStringLiteral) {
989 if (last_node.data.id != .MultilineStringLiteral) {
977990 try stream.writeByteNTimes(' ', indent);
978991 }
979992 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
980993 } else {
981994 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
982 var it = exprs.iterator(0);
983 while (it.next()) |expr| {
984 if (it.peek()) |next_expr| {
985 try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.None);
986 const comma = tree.nextToken(expr.*.lastToken());
995 var it = exprs.first;
996 while (it) |expr_node| : (it = expr_node.next) {
997 const expr = expr_node.data;
998 if (expr_node.next) |next_expr| {
999 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
1000 const comma = tree.nextToken(expr.lastToken());
9871001 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
9881002 } else {
989 try renderExpression(allocator, stream, tree, indent, start_col, expr.*, Space.Space);
1003 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.Space);
9901004 }
9911005 }
9921006
......@@ -1176,7 +1190,7 @@ fn renderExpression(
11761190 },
11771191 }
11781192
1179 if (container_decl.fields_and_decls.len == 0) {
1193 if (container_decl.fields_and_decls.first == null) {
11801194 try renderToken(tree, stream, container_decl.lbrace_token, indent + indent_delta, start_col, Space.None); // {
11811195 return renderToken(tree, stream, container_decl.rbrace_token, indent, start_col, space); // }
11821196 }
......@@ -1193,15 +1207,16 @@ fn renderExpression(
11931207 // Check if the first declaration and the { are on the same line
11941208 const src_has_newline = !tree.tokensOnSameLine(
11951209 container_decl.lbrace_token,
1196 container_decl.fields_and_decls.at(0).*.firstToken(),
1210 container_decl.fields_and_decls.first.?.data.firstToken(),
11971211 );
11981212
11991213 // We can only print all the elements in-line if all the
12001214 // declarations inside are fields
12011215 const src_has_only_fields = blk: {
1202 var it = container_decl.fields_and_decls.iterator(0);
1203 while (it.next()) |decl| {
1204 if (decl.*.id != .ContainerField) break :blk false;
1216 var it = container_decl.fields_and_decls.first;
1217 while (it) |decl_node| : (it = decl_node.next) {
1218 const decl = decl_node.data;
1219 if (decl.id != .ContainerField) break :blk false;
12051220 }
12061221 break :blk true;
12071222 };
......@@ -1211,13 +1226,14 @@ fn renderExpression(
12111226 const new_indent = indent + indent_delta;
12121227 try renderToken(tree, stream, container_decl.lbrace_token, new_indent, start_col, .Newline); // {
12131228
1214 var it = container_decl.fields_and_decls.iterator(0);
1215 while (it.next()) |decl| {
1229 var it = container_decl.fields_and_decls.first;
1230 while (it) |decl_node| : (it = decl_node.next) {
1231 const decl = decl_node.data;
12161232 try stream.writeByteNTimes(' ', new_indent);
1217 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl.*, .Newline);
1233 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl, .Newline);
12181234
1219 if (it.peek()) |next_decl| {
1220 try renderExtraNewline(tree, stream, start_col, next_decl.*);
1235 if (decl_node.next) |next_decl| {
1236 try renderExtraNewline(tree, stream, start_col, next_decl.data);
12211237 }
12221238 }
12231239
......@@ -1230,10 +1246,11 @@ fn renderExpression(
12301246 const new_indent = indent + indent_delta;
12311247 try stream.writeByteNTimes(' ', new_indent);
12321248
1233 var it = container_decl.fields_and_decls.iterator(0);
1234 while (it.next()) |decl| {
1235 const space_after_decl: Space = if (it.peek() == null) .Newline else .Space;
1236 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl.*, space_after_decl);
1249 var it = container_decl.fields_and_decls.first;
1250 while (it) |decl_node| : (it = decl_node.next) {
1251 const decl = decl_node.data;
1252 const space_after_decl: Space = if (decl_node.next == null) .Newline else .Space;
1253 try renderContainerDecl(allocator, stream, tree, new_indent, start_col, decl, space_after_decl);
12371254 }
12381255
12391256 try stream.writeByteNTimes(' ', indent);
......@@ -1241,9 +1258,10 @@ fn renderExpression(
12411258 // All the declarations on the same line
12421259 try renderToken(tree, stream, container_decl.lbrace_token, indent, start_col, .Space); // {
12431260
1244 var it = container_decl.fields_and_decls.iterator(0);
1245 while (it.next()) |decl| {
1246 try renderContainerDecl(allocator, stream, tree, indent, start_col, decl.*, .Space);
1261 var it = container_decl.fields_and_decls.first;
1262 while (it) |decl_node| : (it = decl_node.next) {
1263 const decl = decl_node.data;
1264 try renderContainerDecl(allocator, stream, tree, indent, start_col, decl, .Space);
12471265 }
12481266 }
12491267
......@@ -1255,14 +1273,14 @@ fn renderExpression(
12551273
12561274 const lbrace = tree.nextToken(err_set_decl.error_token);
12571275
1258 if (err_set_decl.decls.len == 0) {
1276 if (err_set_decl.decls.first == null) {
12591277 try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None);
12601278 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
12611279 return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space);
12621280 }
12631281
1264 if (err_set_decl.decls.len == 1) blk: {
1265 const node = err_set_decl.decls.at(0).*;
1282 if (err_set_decl.decls.first.?.next == null) blk: {
1283 const node = err_set_decl.decls.first.?.data;
12661284
12671285 // if there are any doc comments or same line comments
12681286 // don't try to put it all on one line
......@@ -1289,17 +1307,18 @@ fn renderExpression(
12891307 try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {
12901308 const new_indent = indent + indent_delta;
12911309
1292 var it = err_set_decl.decls.iterator(0);
1293 while (it.next()) |node| {
1310 var it = err_set_decl.decls.first;
1311 while (it) |node_node| : (it = node_node.next) {
1312 const node = node_node.data;
12941313 try stream.writeByteNTimes(' ', new_indent);
12951314
1296 if (it.peek()) |next_node| {
1297 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None);
1298 try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // ,
1315 if (node_node.next) |next_node| {
1316 try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.None);
1317 try renderToken(tree, stream, tree.nextToken(node.lastToken()), new_indent, start_col, Space.Newline); // ,
12991318
1300 try renderExtraNewline(tree, stream, start_col, next_node.*);
1319 try renderExtraNewline(tree, stream, start_col, next_node.data);
13011320 } else {
1302 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
1321 try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.Comma);
13031322 }
13041323 }
13051324
......@@ -1308,17 +1327,18 @@ fn renderExpression(
13081327 } else {
13091328 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); // {
13101329
1311 var it = err_set_decl.decls.iterator(0);
1312 while (it.next()) |node| {
1313 if (it.peek()) |next_node| {
1314 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
1330 var it = err_set_decl.decls.first;
1331 while (it) |node_node| : (it = node_node.next) {
1332 const node = node_node.data;
1333 if (node_node.next) |next_node| {
1334 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
13151335
1316 const comma_token = tree.nextToken(node.*.lastToken());
1336 const comma_token = tree.nextToken(node.lastToken());
13171337 assert(tree.tokens[comma_token].id == .Comma);
13181338 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
1319 try renderExtraNewline(tree, stream, start_col, next_node.*);
1339 try renderExtraNewline(tree, stream, start_col, next_node.data);
13201340 } else {
1321 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space);
1341 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.Space);
13221342 }
13231343 }
13241344
......@@ -1344,9 +1364,9 @@ fn renderExpression(
13441364 skip_first_indent = false;
13451365 }
13461366
1347 var i: usize = 0;
1348 while (i < multiline_str_literal.lines.len) : (i += 1) {
1349 const t = multiline_str_literal.lines.at(i).*;
1367 var it = multiline_str_literal.lines.first;
1368 while (it) |t_node| : (it = t_node.next) {
1369 const t = t_node.data;
13501370 if (!skip_first_indent) {
13511371 try stream.writeByteNTimes(' ', indent + indent_delta);
13521372 }
......@@ -1366,8 +1386,12 @@ fn renderExpression(
13661386 try renderToken(tree, stream, builtin_call.builtin_token, indent, start_col, Space.None); // @name
13671387
13681388 const src_params_trailing_comma = blk: {
1369 if (builtin_call.params.len < 2) break :blk false;
1370 const last_node = builtin_call.params.at(builtin_call.params.len - 1).*;
1389 if (builtin_call.params.first == null or
1390 builtin_call.params.first.?.next == null)
1391 {
1392 break :blk false;
1393 }
1394 const last_node = findLast(builtin_call.params.first.?).data;
13711395 const maybe_comma = tree.nextToken(last_node.lastToken());
13721396 break :blk tree.tokens[maybe_comma].id == .Comma;
13731397 };
......@@ -1378,12 +1402,13 @@ fn renderExpression(
13781402 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
13791403
13801404 // render all on one line, no trailing comma
1381 var it = builtin_call.params.iterator(0);
1382 while (it.next()) |param_node| {
1383 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.None);
1405 var it = builtin_call.params.first;
1406 while (it) |param_node_node| : (it = param_node_node.next) {
1407 const param_node = param_node_node.data;
1408 try renderExpression(allocator, stream, tree, indent, start_col, param_node, Space.None);
13841409
1385 if (it.peek() != null) {
1386 const comma_token = tree.nextToken(param_node.*.lastToken());
1410 if (param_node_node.next != null) {
1411 const comma_token = tree.nextToken(param_node.lastToken());
13871412 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
13881413 }
13891414 }
......@@ -1392,10 +1417,11 @@ fn renderExpression(
13921417 const new_indent = indent + indent_delta;
13931418 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (
13941419
1395 var it = builtin_call.params.iterator(0);
1396 while (it.next()) |param_node| {
1420 var it = builtin_call.params.first;
1421 while (it) |param_node_node| : (it = param_node_node.next) {
1422 const param_node = param_node_node.data;
13971423 try stream.writeByteNTimes(' ', new_indent);
1398 try renderExpression(allocator, stream, tree, indent, start_col, param_node.*, Space.Comma);
1424 try renderExpression(allocator, stream, tree, indent, start_col, param_node, Space.Comma);
13991425 }
14001426 try stream.writeByteNTimes(' ', indent);
14011427 }
......@@ -1457,12 +1483,13 @@ fn renderExpression(
14571483 try renderToken(tree, stream, lparen, indent, start_col, Space.None); // (
14581484
14591485 // render all on one line, no trailing comma
1460 var it = fn_proto.params.iterator(0);
1461 while (it.next()) |param_decl_node| {
1462 try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node.*, Space.None);
1486 var it = fn_proto.params.first;
1487 while (it) |param_decl_node_node| : (it = param_decl_node_node.next) {
1488 const param_decl_node = param_decl_node_node.data;
1489 try renderParamDecl(allocator, stream, tree, indent, start_col, param_decl_node, Space.None);
14631490
1464 if (it.peek() != null) {
1465 const comma = tree.nextToken(param_decl_node.*.lastToken());
1491 if (param_decl_node_node.next != null) {
1492 const comma = tree.nextToken(param_decl_node.lastToken());
14661493 try renderToken(tree, stream, comma, indent, start_col, Space.Space); // ,
14671494 }
14681495 }
......@@ -1471,10 +1498,11 @@ fn renderExpression(
14711498 const new_indent = indent + indent_delta;
14721499 try renderToken(tree, stream, lparen, new_indent, start_col, Space.Newline); // (
14731500
1474 var it = fn_proto.params.iterator(0);
1475 while (it.next()) |param_decl_node| {
1501 var it = fn_proto.params.first;
1502 while (it) |param_decl_node_node| : (it = param_decl_node_node.next) {
1503 const param_decl_node = param_decl_node_node.data;
14761504 try stream.writeByteNTimes(' ', new_indent);
1477 try renderParamDecl(allocator, stream, tree, new_indent, start_col, param_decl_node.*, Space.Comma);
1505 try renderParamDecl(allocator, stream, tree, new_indent, start_col, param_decl_node, Space.Comma);
14781506 }
14791507 try stream.writeByteNTimes(' ', indent);
14801508 }
......@@ -1553,7 +1581,7 @@ fn renderExpression(
15531581 const rparen = tree.nextToken(switch_node.expr.lastToken());
15541582 const lbrace = tree.nextToken(rparen);
15551583
1556 if (switch_node.cases.len == 0) {
1584 if (switch_node.cases.first == null) {
15571585 try renderExpression(allocator, stream, tree, indent, start_col, switch_node.expr, Space.None);
15581586 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
15591587 try renderToken(tree, stream, lbrace, indent, start_col, Space.None); // {
......@@ -1567,13 +1595,14 @@ fn renderExpression(
15671595 try renderToken(tree, stream, rparen, indent, start_col, Space.Space); // )
15681596 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); // {
15691597
1570 var it = switch_node.cases.iterator(0);
1571 while (it.next()) |node| {
1598 var it = switch_node.cases.first;
1599 while (it) |node_node| : (it = node_node.next) {
1600 const node = node_node.data;
15721601 try stream.writeByteNTimes(' ', new_indent);
1573 try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
1602 try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.Comma);
15741603
1575 if (it.peek()) |next_node| {
1576 try renderExtraNewline(tree, stream, start_col, next_node.*);
1604 if (node_node.next) |next_node| {
1605 try renderExtraNewline(tree, stream, start_col, next_node.data);
15771606 }
15781607 }
15791608
......@@ -1584,38 +1613,40 @@ fn renderExpression(
15841613 .SwitchCase => {
15851614 const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);
15861615
1587 assert(switch_case.items.len != 0);
1616 assert(switch_case.items.first != null);
15881617 const src_has_trailing_comma = blk: {
1589 const last_node = switch_case.items.at(switch_case.items.len - 1).*;
1618 const last_node = findLast(switch_case.items.first.?).data;
15901619 const maybe_comma = tree.nextToken(last_node.lastToken());
15911620 break :blk tree.tokens[maybe_comma].id == .Comma;
15921621 };
15931622
1594 if (switch_case.items.len == 1 or !src_has_trailing_comma) {
1595 var it = switch_case.items.iterator(0);
1596 while (it.next()) |node| {
1597 if (it.peek()) |next_node| {
1598 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
1623 if (switch_case.items.first.?.next == null or !src_has_trailing_comma) {
1624 var it = switch_case.items.first;
1625 while (it) |node_node| : (it = node_node.next) {
1626 const node = node_node.data;
1627 if (node_node.next) |next_node| {
1628 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
15991629
1600 const comma_token = tree.nextToken(node.*.lastToken());
1630 const comma_token = tree.nextToken(node.lastToken());
16011631 try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // ,
1602 try renderExtraNewline(tree, stream, start_col, next_node.*);
1632 try renderExtraNewline(tree, stream, start_col, next_node.data);
16031633 } else {
1604 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space);
1634 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.Space);
16051635 }
16061636 }
16071637 } else {
1608 var it = switch_case.items.iterator(0);
1609 while (it.next()) |node| {
1610 if (it.peek()) |next_node| {
1611 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
1638 var it = switch_case.items.first;
1639 while (it) |node_node| : (it = node_node.next) {
1640 const node = node_node.data;
1641 if (node_node.next) |next_node| {
1642 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None);
16121643
1613 const comma_token = tree.nextToken(node.*.lastToken());
1644 const comma_token = tree.nextToken(node.lastToken());
16141645 try renderToken(tree, stream, comma_token, indent, start_col, Space.Newline); // ,
1615 try renderExtraNewline(tree, stream, start_col, next_node.*);
1646 try renderExtraNewline(tree, stream, start_col, next_node.data);
16161647 try stream.writeByteNTimes(' ', indent);
16171648 } else {
1618 try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma);
1649 try renderExpression(allocator, stream, tree, indent, start_col, node, Space.Comma);
16191650 try stream.writeByteNTimes(' ', indent);
16201651 }
16211652 }
......@@ -1887,7 +1918,7 @@ fn renderExpression(
18871918 try renderToken(tree, stream, tree.nextToken(asm_node.asm_token), indent, start_col, Space.None); // (
18881919 }
18891920
1890 if (asm_node.outputs.len == 0 and asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
1921 if (asm_node.outputs.first == null and asm_node.inputs.first == null and asm_node.clobbers.first == null) {
18911922 try renderExpression(allocator, stream, tree, indent, start_col, asm_node.template, Space.None);
18921923 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
18931924 }
......@@ -1907,7 +1938,7 @@ fn renderExpression(
19071938 const colon1 = tree.nextToken(asm_node.template.lastToken());
19081939 const indent_extra = indent_once + 2;
19091940
1910 const colon2 = if (asm_node.outputs.len == 0) blk: {
1941 const colon2 = if (asm_node.outputs.first == null) blk: {
19111942 try renderToken(tree, stream, colon1, indent, start_col, Space.Newline); // :
19121943 try stream.writeByteNTimes(' ', indent_once);
19131944
......@@ -1915,21 +1946,23 @@ fn renderExpression(
19151946 } else blk: {
19161947 try renderToken(tree, stream, colon1, indent, start_col, Space.Space); // :
19171948
1918 var it = asm_node.outputs.iterator(0);
1949 var it = asm_node.outputs.first;
19191950 while (true) {
1920 const asm_output = it.next().?;
1921 const node = &(asm_output.*).base;
1951 const asm_output_node = it.?;
1952 it = asm_output_node.next;
1953 const asm_output = asm_output_node.data;
1954 const node = &asm_output.base;
19221955
1923 if (it.peek()) |next_asm_output| {
1956 if (asm_output_node.next) |next_asm_output| {
19241957 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
1925 const next_node = &(next_asm_output.*).base;
1958 const next_node = &next_asm_output.data.base;
19261959
1927 const comma = tree.prevToken(next_asm_output.*.firstToken());
1960 const comma = tree.prevToken(next_asm_output.data.firstToken());
19281961 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
19291962 try renderExtraNewline(tree, stream, start_col, next_node);
19301963
19311964 try stream.writeByteNTimes(' ', indent_extra);
1932 } else if (asm_node.inputs.len == 0 and asm_node.clobbers.len == 0) {
1965 } else if (asm_node.inputs.first == null and asm_node.clobbers.first == null) {
19331966 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
19341967 try stream.writeByteNTimes(' ', indent);
19351968 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
......@@ -1945,7 +1978,7 @@ fn renderExpression(
19451978 }
19461979 };
19471980
1948 const colon3 = if (asm_node.inputs.len == 0) blk: {
1981 const colon3 = if (asm_node.inputs.first == null) blk: {
19491982 try renderToken(tree, stream, colon2, indent, start_col, Space.Newline); // :
19501983 try stream.writeByteNTimes(' ', indent_once);
19511984
......@@ -1953,21 +1986,22 @@ fn renderExpression(
19531986 } else blk: {
19541987 try renderToken(tree, stream, colon2, indent, start_col, Space.Space); // :
19551988
1956 var it = asm_node.inputs.iterator(0);
1989 var it = asm_node.inputs.first;
19571990 while (true) {
1958 const asm_input = it.next().?;
1959 const node = &(asm_input.*).base;
1991 const asm_input_node = it.?;
1992 it = asm_input_node.next;
1993 const node = &asm_input_node.data.base;
19601994
1961 if (it.peek()) |next_asm_input| {
1995 if (it) |next_asm_input| {
19621996 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.None);
1963 const next_node = &(next_asm_input.*).base;
1997 const next_node = &next_asm_input.data.base;
19641998
1965 const comma = tree.prevToken(next_asm_input.*.firstToken());
1999 const comma = tree.prevToken(next_asm_input.data.firstToken());
19662000 try renderToken(tree, stream, comma, indent_extra, start_col, Space.Newline); // ,
19672001 try renderExtraNewline(tree, stream, start_col, next_node);
19682002
19692003 try stream.writeByteNTimes(' ', indent_extra);
1970 } else if (asm_node.clobbers.len == 0) {
2004 } else if (asm_node.clobbers.first == null) {
19712005 try renderExpression(allocator, stream, tree, indent_extra, start_col, node, Space.Newline);
19722006 try stream.writeByteNTimes(' ', indent);
19732007 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space); // )
......@@ -1985,11 +2019,13 @@ fn renderExpression(
19852019
19862020 try renderToken(tree, stream, colon3, indent, start_col, Space.Space); // :
19872021
1988 var it = asm_node.clobbers.iterator(0);
2022 var it = asm_node.clobbers.first;
19892023 while (true) {
1990 const clobber_node = it.next().?.*;
2024 const clobber_node_node = it.?;
2025 it = clobber_node_node.next;
2026 const clobber_node = clobber_node_node.data;
19912027
1992 if (it.peek() == null) {
2028 if (it == null) {
19932029 try renderExpression(allocator, stream, tree, indent_extra, start_col, clobber_node, Space.Newline);
19942030 try stream.writeByteNTimes(' ', indent);
19952031 return renderToken(tree, stream, asm_node.rparen, indent, start_col, space);
......@@ -2401,14 +2437,15 @@ fn renderDocComments(
24012437 start_col: *usize,
24022438) (@TypeOf(stream).Error || Error)!void {
24032439 const comment = node.doc_comments orelse return;
2404 var it = comment.lines.iterator(0);
2440 var it = comment.lines.first;
24052441 const first_token = node.firstToken();
2406 while (it.next()) |line_token_index| {
2407 if (line_token_index.* < first_token) {
2408 try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.Newline);
2442 while (it) |line_token_index_node| : (it = line_token_index_node.next) {
2443 const line_token_index = line_token_index_node.data;
2444 if (line_token_index < first_token) {
2445 try renderToken(tree, stream, line_token_index, indent, start_col, Space.Newline);
24092446 try stream.writeByteNTimes(' ', indent);
24102447 } else {
2411 try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.NoComment);
2448 try renderToken(tree, stream, line_token_index, indent, start_col, Space.NoComment);
24122449 try stream.writeAll("\n");
24132450 try stream.writeByteNTimes(' ', indent);
24142451 }
......@@ -2473,3 +2510,19 @@ fn copyFixingWhitespace(stream: var, slice: []const u8) @TypeOf(stream).Error!vo
24732510 else => try stream.writeByte(byte),
24742511 };
24752512}
2513
2514fn countLen(node: ?*std.SinglyLinkedList(*ast.Node).Node) usize {
2515 var count: usize = 0;
2516 var it = node;
2517 while (it) |n| : (it = n.next) {
2518 count += 1;
2519 }
2520 return count;
2521}
2522
2523fn findLast(node: *std.SinglyLinkedList(*ast.Node).Node) *std.SinglyLinkedList(*ast.Node).Node {
2524 var it = node;
2525 while (true) {
2526 it = it.next orelse return it;
2527 }
2528}