| ... | ... | @@ -522,7 +522,11 @@ fn renderExpression( |
| 522 | 522 | break :blk if (loc.line == 0) op_space else Space.Newline; |
| 523 | 523 | }; |
| 524 | 524 | |
| 525 | | try renderToken(tree, ais, infix_op_node.op_token, after_op_space); |
| 525 | { |
| 526 | ais.pushIndent(); |
| 527 | defer ais.popIndent(); |
| 528 | try renderToken(tree, ais, infix_op_node.op_token, after_op_space); |
| 529 | } |
| 526 | 530 | ais.pushIndentOneShot(); |
| 527 | 531 | return renderExpression(allocator, ais, tree, infix_op_node.rhs, space); |
| 528 | 532 | }, |
| ... | ... | @@ -710,141 +714,194 @@ fn renderExpression( |
| 710 | 714 | .node => |node| tree.nextToken(node.lastToken()), |
| 711 | 715 | }; |
| 712 | 716 | |
| 713 | | if (exprs.len == 0) { |
| 714 | | switch (lhs) { |
| 715 | | .dot => |dot| try renderToken(tree, ais, dot, Space.None), |
| 716 | | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), |
| 717 | | } |
| 718 | | |
| 719 | | { |
| 720 | | ais.pushIndent(); |
| 721 | | defer ais.popIndent(); |
| 722 | | try renderToken(tree, ais, lbrace, Space.None); |
| 723 | | } |
| 717 | switch (lhs) { |
| 718 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), |
| 719 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), |
| 720 | } |
| 724 | 721 | |
| 722 | if (exprs.len == 0) { |
| 723 | try renderToken(tree, ais, lbrace, Space.None); |
| 725 | 724 | return renderToken(tree, ais, rtoken, space); |
| 726 | 725 | } |
| 727 | | if (exprs.len == 1 and tree.token_ids[exprs[0].*.lastToken() + 1] == .RBrace) { |
| 726 | |
| 727 | if (exprs.len == 1 and exprs[0].tag != .MultilineStringLiteral and tree.token_ids[exprs[0].*.lastToken() + 1] == .RBrace) { |
| 728 | 728 | const expr = exprs[0]; |
| 729 | 729 | |
| 730 | | switch (lhs) { |
| 731 | | .dot => |dot| try renderToken(tree, ais, dot, Space.None), |
| 732 | | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), |
| 733 | | } |
| 734 | 730 | try renderToken(tree, ais, lbrace, Space.None); |
| 735 | 731 | try renderExpression(allocator, ais, tree, expr, Space.None); |
| 736 | 732 | return renderToken(tree, ais, rtoken, space); |
| 737 | 733 | } |
| 738 | 734 | |
| 739 | | switch (lhs) { |
| 740 | | .dot => |dot| try renderToken(tree, ais, dot, Space.None), |
| 741 | | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), |
| 742 | | } |
| 743 | | |
| 744 | 735 | // scan to find row size |
| 745 | | const maybe_row_size: ?usize = blk: { |
| 746 | | var count: usize = 1; |
| 747 | | for (exprs) |expr, i| { |
| 748 | | if (i + 1 < exprs.len) { |
| 749 | | const expr_last_token = expr.lastToken() + 1; |
| 750 | | const loc = tree.tokenLocation(tree.token_locs[expr_last_token].end, exprs[i + 1].firstToken()); |
| 751 | | if (loc.line != 0) break :blk count; |
| 752 | | count += 1; |
| 753 | | } else { |
| 754 | | const expr_last_token = expr.lastToken(); |
| 755 | | const loc = tree.tokenLocation(tree.token_locs[expr_last_token].end, rtoken); |
| 756 | | if (loc.line == 0) { |
| 757 | | // all on one line |
| 758 | | const src_has_trailing_comma = trailblk: { |
| 759 | | const maybe_comma = tree.prevToken(rtoken); |
| 760 | | break :trailblk tree.token_ids[maybe_comma] == .Comma; |
| 761 | | }; |
| 762 | | if (src_has_trailing_comma) { |
| 763 | | break :blk 1; // force row size 1 |
| 764 | | } else { |
| 765 | | break :blk null; // no newlines |
| 766 | | } |
| 767 | | } |
| 768 | | break :blk count; |
| 769 | | } |
| 770 | | } |
| 771 | | unreachable; |
| 772 | | }; |
| 773 | | |
| 774 | | if (maybe_row_size) |row_size| { |
| 775 | | // A place to store the width of each expression and its column's maximum |
| 776 | | var widths = try allocator.alloc(usize, exprs.len + row_size); |
| 777 | | defer allocator.free(widths); |
| 778 | | mem.set(usize, widths, 0); |
| 779 | | |
| 780 | | var expr_widths = widths[0 .. widths.len - row_size]; |
| 781 | | var column_widths = widths[widths.len - row_size ..]; |
| 782 | | |
| 783 | | // Null ais for counting the printed length of each expression |
| 784 | | var counting_stream = std.io.countingOutStream(std.io.null_out_stream); |
| 785 | | var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, counting_stream.writer()); |
| 786 | | |
| 787 | | for (exprs) |expr, i| { |
| 788 | | counting_stream.bytes_written = 0; |
| 789 | | try renderExpression(allocator, &auto_indenting_stream, tree, expr, Space.None); |
| 790 | | const width = @intCast(usize, counting_stream.bytes_written); |
| 791 | | const col = i % row_size; |
| 792 | | column_widths[col] = std.math.max(column_widths[col], width); |
| 793 | | expr_widths[i] = width; |
| 794 | | } |
| 795 | | |
| 736 | if (rowSize(tree, exprs, rtoken) != null) { |
| 796 | 737 | { |
| 797 | 738 | ais.pushIndentNextLine(); |
| 798 | 739 | defer ais.popIndent(); |
| 799 | 740 | try renderToken(tree, ais, lbrace, Space.Newline); |
| 800 | 741 | |
| 801 | | var col: usize = 1; |
| 802 | | for (exprs) |expr, i| { |
| 803 | | if (i + 1 < exprs.len) { |
| 804 | | const next_expr = exprs[i + 1]; |
| 805 | | try renderExpression(allocator, ais, tree, expr, Space.None); |
| 806 | | |
| 807 | | const comma = tree.nextToken(expr.*.lastToken()); |
| 808 | | |
| 809 | | if (col != row_size) { |
| 810 | | try renderToken(tree, ais, comma, Space.Space); // , |
| 811 | | |
| 812 | | const padding = column_widths[i % row_size] - expr_widths[i]; |
| 813 | | try ais.writer().writeByteNTimes(' ', padding); |
| 814 | | |
| 815 | | col += 1; |
| 816 | | continue; |
| 742 | var expr_index: usize = 0; |
| 743 | while (rowSize(tree, exprs[expr_index..], rtoken)) |row_size| { |
| 744 | const row_exprs = exprs[expr_index..]; |
| 745 | // A place to store the width of each expression and its column's maximum |
| 746 | var widths = try allocator.alloc(usize, row_exprs.len + row_size); |
| 747 | defer allocator.free(widths); |
| 748 | mem.set(usize, widths, 0); |
| 749 | |
| 750 | var expr_newlines = try allocator.alloc(bool, row_exprs.len); |
| 751 | defer allocator.free(expr_newlines); |
| 752 | mem.set(bool, expr_newlines, false); |
| 753 | |
| 754 | var expr_widths = widths[0 .. widths.len - row_size]; |
| 755 | var column_widths = widths[widths.len - row_size ..]; |
| 756 | |
| 757 | // Find next row with trailing comment (if any) to end the current section |
| 758 | var section_end = sec_end: { |
| 759 | var this_line_first_expr: usize = 0; |
| 760 | var this_line_size = rowSize(tree, row_exprs, rtoken); |
| 761 | for (row_exprs) |expr, i| { |
| 762 | // Ignore comment on first line of this section |
| 763 | if (i == 0 or tree.tokensOnSameLine(row_exprs[0].firstToken(), expr.lastToken())) continue; |
| 764 | // Track start of line containing comment |
| 765 | if (!tree.tokensOnSameLine(row_exprs[this_line_first_expr].firstToken(), expr.lastToken())) { |
| 766 | this_line_first_expr = i; |
| 767 | this_line_size = rowSize(tree, row_exprs[this_line_first_expr..], rtoken); |
| 768 | } |
| 769 | |
| 770 | const maybe_comma = expr.lastToken() + 1; |
| 771 | const maybe_comment = expr.lastToken() + 2; |
| 772 | if (maybe_comment < tree.token_ids.len) { |
| 773 | if (tree.token_ids[maybe_comma] == .Comma and |
| 774 | tree.token_ids[maybe_comment] == .LineComment and |
| 775 | tree.tokensOnSameLine(expr.lastToken(), maybe_comment)) |
| 776 | { |
| 777 | var comment_token_loc = tree.token_locs[maybe_comment]; |
| 778 | const comment_is_empty = mem.trimRight(u8, tree.tokenSliceLoc(comment_token_loc), " ").len == 2; |
| 779 | if (!comment_is_empty) { |
| 780 | // Found row ending in comment |
| 781 | break :sec_end i - this_line_size.? + 1; |
| 782 | } |
| 783 | } |
| 784 | } |
| 817 | 785 | } |
| 818 | | col = 1; |
| 786 | break :sec_end row_exprs.len; |
| 787 | }; |
| 788 | expr_index += section_end; |
| 789 | |
| 790 | const section_exprs = row_exprs[0..section_end]; |
| 791 | |
| 792 | // Null stream for counting the printed length of each expression |
| 793 | var line_find_stream = std.io.findByteOutStream('\n', std.io.null_out_stream); |
| 794 | var counting_stream = std.io.countingOutStream(line_find_stream.writer()); |
| 795 | var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, counting_stream.writer()); |
| 796 | |
| 797 | // Calculate size of columns in current section |
| 798 | var column_counter: usize = 0; |
| 799 | var single_line = true; |
| 800 | for (section_exprs) |expr, i| { |
| 801 | if (i + 1 < section_exprs.len) { |
| 802 | counting_stream.bytes_written = 0; |
| 803 | line_find_stream.byte_found = false; |
| 804 | try renderExpression(allocator, &auto_indenting_stream, tree, expr, Space.None); |
| 805 | const width = @intCast(usize, counting_stream.bytes_written); |
| 806 | expr_widths[i] = width; |
| 807 | expr_newlines[i] = line_find_stream.byte_found; |
| 808 | |
| 809 | if (!line_find_stream.byte_found) { |
| 810 | const column = column_counter % row_size; |
| 811 | column_widths[column] = std.math.max(column_widths[column], width); |
| 812 | |
| 813 | const expr_last_token = expr.*.lastToken() + 1; |
| 814 | const next_expr = section_exprs[i + 1]; |
| 815 | const loc = tree.tokenLocation(tree.token_locs[expr_last_token].start, next_expr.*.firstToken()); |
| 816 | if (loc.line == 0) { |
| 817 | column_counter += 1; |
| 818 | } else { |
| 819 | single_line = false; |
| 820 | column_counter = 0; |
| 821 | } |
| 822 | } else { |
| 823 | single_line = false; |
| 824 | column_counter = 0; |
| 825 | } |
| 826 | } else { |
| 827 | counting_stream.bytes_written = 0; |
| 828 | try renderExpression(allocator, &auto_indenting_stream, tree, expr, Space.None); |
| 829 | const width = @intCast(usize, counting_stream.bytes_written); |
| 830 | expr_widths[i] = width; |
| 831 | expr_newlines[i] = line_find_stream.byte_found; |
| 832 | |
| 833 | if (!line_find_stream.byte_found) { |
| 834 | const column = column_counter % row_size; |
| 835 | column_widths[column] = std.math.max(column_widths[column], width); |
| 836 | } |
| 837 | break; |
| 838 | } |
| 839 | } |
| 819 | 840 | |
| 820 | | if (tree.token_ids[tree.nextToken(comma)] != .MultilineStringLiteralLine) { |
| 841 | // Render exprs in current section |
| 842 | column_counter = 0; |
| 843 | var last_col_index: usize = row_size - 1; |
| 844 | for (section_exprs) |expr, i| { |
| 845 | if (i + 1 < section_exprs.len) { |
| 846 | const next_expr = section_exprs[i + 1]; |
| 847 | try renderExpression(allocator, ais, tree, expr, Space.None); |
| 848 | |
| 849 | const comma = tree.nextToken(expr.*.lastToken()); |
| 850 | |
| 851 | if (column_counter != last_col_index) { |
| 852 | if (!expr_newlines[i] and !expr_newlines[i + 1]) { |
| 853 | // Neither the current or next expression is multiline |
| 854 | try renderToken(tree, ais, comma, Space.Space); // , |
| 855 | assert(column_widths[column_counter % row_size] >= expr_widths[i]); |
| 856 | const padding = column_widths[column_counter % row_size] - expr_widths[i]; |
| 857 | try ais.writer().writeByteNTimes(' ', padding); |
| 858 | |
| 859 | column_counter += 1; |
| 860 | continue; |
| 861 | } |
| 862 | } |
| 863 | if (single_line and row_size != 1) { |
| 864 | try renderToken(tree, ais, comma, Space.Space); // , |
| 865 | continue; |
| 866 | } |
| 867 | |
| 868 | column_counter = 0; |
| 821 | 869 | try renderToken(tree, ais, comma, Space.Newline); // , |
| 870 | try renderExtraNewline(tree, ais, next_expr); |
| 822 | 871 | } else { |
| 823 | | try renderToken(tree, ais, comma, Space.None); // , |
| 872 | const maybe_comma = tree.nextToken(expr.*.lastToken()); |
| 873 | if (tree.token_ids[maybe_comma] == .Comma) { |
| 874 | try renderExpression(allocator, ais, tree, expr, Space.None); // , |
| 875 | try renderToken(tree, ais, maybe_comma, Space.Newline); // , |
| 876 | } else { |
| 877 | try renderExpression(allocator, ais, tree, expr, Space.Comma); // , |
| 878 | } |
| 824 | 879 | } |
| 880 | } |
| 825 | 881 | |
| 826 | | try renderExtraNewline(tree, ais, next_expr); |
| 827 | | } else { |
| 828 | | try renderExpression(allocator, ais, tree, expr, Space.Comma); // , |
| 882 | if (expr_index == exprs.len) { |
| 883 | break; |
| 829 | 884 | } |
| 830 | 885 | } |
| 831 | 886 | } |
| 832 | | return renderToken(tree, ais, rtoken, space); |
| 833 | | } else { |
| 834 | | try renderToken(tree, ais, lbrace, Space.Space); |
| 835 | | for (exprs) |expr, i| { |
| 836 | | if (i + 1 < exprs.len) { |
| 837 | | const next_expr = exprs[i + 1]; |
| 838 | | try renderExpression(allocator, ais, tree, expr, Space.None); |
| 839 | | const comma = tree.nextToken(expr.*.lastToken()); |
| 840 | | try renderToken(tree, ais, comma, Space.Space); // , |
| 841 | | } else { |
| 842 | | try renderExpression(allocator, ais, tree, expr, Space.Space); |
| 843 | | } |
| 844 | | } |
| 845 | 887 | |
| 846 | 888 | return renderToken(tree, ais, rtoken, space); |
| 847 | 889 | } |
| 890 | |
| 891 | // Single line |
| 892 | try renderToken(tree, ais, lbrace, Space.Space); |
| 893 | for (exprs) |expr, i| { |
| 894 | if (i + 1 < exprs.len) { |
| 895 | const next_expr = exprs[i + 1]; |
| 896 | try renderExpression(allocator, ais, tree, expr, Space.None); |
| 897 | const comma = tree.nextToken(expr.*.lastToken()); |
| 898 | try renderToken(tree, ais, comma, Space.Space); // , |
| 899 | } else { |
| 900 | try renderExpression(allocator, ais, tree, expr, Space.Space); |
| 901 | } |
| 902 | } |
| 903 | |
| 904 | return renderToken(tree, ais, rtoken, space); |
| 848 | 905 | }, |
| 849 | 906 | |
| 850 | 907 | .StructInitializer, .StructInitializerDot => { |
| ... | ... | @@ -1004,21 +1061,29 @@ fn renderExpression( |
| 1004 | 1061 | }; |
| 1005 | 1062 | |
| 1006 | 1063 | if (src_has_trailing_comma) { |
| 1007 | | try renderToken(tree, ais, lparen, Space.Newline); |
| 1008 | | |
| 1009 | | const params = call.params(); |
| 1010 | | for (params) |param_node, i| { |
| 1064 | { |
| 1011 | 1065 | ais.pushIndent(); |
| 1012 | 1066 | defer ais.popIndent(); |
| 1013 | 1067 | |
| 1014 | | if (i + 1 < params.len) { |
| 1015 | | const next_node = params[i + 1]; |
| 1016 | | try renderExpression(allocator, ais, tree, param_node, Space.None); |
| 1017 | | const comma = tree.nextToken(param_node.lastToken()); |
| 1018 | | try renderToken(tree, ais, comma, Space.Newline); // , |
| 1019 | | try renderExtraNewline(tree, ais, next_node); |
| 1020 | | } else { |
| 1021 | | try renderExpression(allocator, ais, tree, param_node, Space.Comma); |
| 1068 | try renderToken(tree, ais, lparen, Space.Newline); // ( |
| 1069 | const params = call.params(); |
| 1070 | for (params) |param_node, i| { |
| 1071 | if (i + 1 < params.len) { |
| 1072 | const next_node = params[i + 1]; |
| 1073 | try renderExpression(allocator, ais, tree, param_node, Space.None); |
| 1074 | |
| 1075 | // Unindent the comma for multiline string literals |
| 1076 | const maybe_multiline_string = param_node.firstToken(); |
| 1077 | const is_multiline_string = tree.token_ids[maybe_multiline_string] == .MultilineStringLiteralLine; |
| 1078 | if (is_multiline_string) ais.popIndent(); |
| 1079 | defer if (is_multiline_string) ais.pushIndent(); |
| 1080 | |
| 1081 | const comma = tree.nextToken(param_node.lastToken()); |
| 1082 | try renderToken(tree, ais, comma, Space.Newline); // , |
| 1083 | try renderExtraNewline(tree, ais, next_node); |
| 1084 | } else { |
| 1085 | try renderExpression(allocator, ais, tree, param_node, Space.Comma); |
| 1086 | } |
| 1022 | 1087 | } |
| 1023 | 1088 | } |
| 1024 | 1089 | return renderToken(tree, ais, call.rtoken, space); |
| ... | ... | @@ -1028,17 +1093,20 @@ fn renderExpression( |
| 1028 | 1093 | |
| 1029 | 1094 | const params = call.params(); |
| 1030 | 1095 | for (params) |param_node, i| { |
| 1031 | | if (param_node.*.tag == .MultilineStringLiteral) ais.pushIndentOneShot(); |
| 1096 | const maybe_comment = param_node.firstToken() - 1; |
| 1097 | const maybe_multiline_string = param_node.firstToken(); |
| 1098 | if (tree.token_ids[maybe_multiline_string] == .MultilineStringLiteralLine or tree.token_ids[maybe_comment] == .LineComment) { |
| 1099 | ais.pushIndentOneShot(); |
| 1100 | } |
| 1032 | 1101 | |
| 1033 | 1102 | try renderExpression(allocator, ais, tree, param_node, Space.None); |
| 1034 | 1103 | |
| 1035 | 1104 | if (i + 1 < params.len) { |
| 1036 | | const next_param = params[i + 1]; |
| 1037 | 1105 | const comma = tree.nextToken(param_node.lastToken()); |
| 1038 | 1106 | try renderToken(tree, ais, comma, Space.Space); |
| 1039 | 1107 | } |
| 1040 | 1108 | } |
| 1041 | | return renderToken(tree, ais, call.rtoken, space); |
| 1109 | return renderToken(tree, ais, call.rtoken, space); // ) |
| 1042 | 1110 | }, |
| 1043 | 1111 | |
| 1044 | 1112 | .ArrayAccess => { |
| ... | ... | @@ -1429,7 +1497,7 @@ fn renderExpression( |
| 1429 | 1497 | try renderToken(tree, ais, builtin_call.builtin_token, Space.None); // @name |
| 1430 | 1498 | |
| 1431 | 1499 | const src_params_trailing_comma = blk: { |
| 1432 | | if (builtin_call.params_len < 2) break :blk false; |
| 1500 | if (builtin_call.params_len == 0) break :blk false; |
| 1433 | 1501 | const last_node = builtin_call.params()[builtin_call.params_len - 1]; |
| 1434 | 1502 | const maybe_comma = tree.nextToken(last_node.lastToken()); |
| 1435 | 1503 | break :blk tree.token_ids[maybe_comma] == .Comma; |
| ... | ... | @@ -1443,6 +1511,10 @@ fn renderExpression( |
| 1443 | 1511 | // render all on one line, no trailing comma |
| 1444 | 1512 | const params = builtin_call.params(); |
| 1445 | 1513 | for (params) |param_node, i| { |
| 1514 | const maybe_comment = param_node.firstToken() - 1; |
| 1515 | if (param_node.*.tag == .MultilineStringLiteral or tree.token_ids[maybe_comment] == .LineComment) { |
| 1516 | ais.pushIndentOneShot(); |
| 1517 | } |
| 1446 | 1518 | try renderExpression(allocator, ais, tree, param_node, Space.None); |
| 1447 | 1519 | |
| 1448 | 1520 | if (i + 1 < params.len) { |
| ... | ... | @@ -1494,19 +1566,20 @@ fn renderExpression( |
| 1494 | 1566 | assert(tree.token_ids[lparen] == .LParen); |
| 1495 | 1567 | |
| 1496 | 1568 | const rparen = tree.prevToken( |
| 1497 | | // the first token for the annotation expressions is the left |
| 1498 | | // parenthesis, hence the need for two prevToken |
| 1499 | | if (fn_proto.getAlignExpr()) |align_expr| |
| 1500 | | tree.prevToken(tree.prevToken(align_expr.firstToken())) |
| 1501 | | else if (fn_proto.getSectionExpr()) |section_expr| |
| 1502 | | tree.prevToken(tree.prevToken(section_expr.firstToken())) |
| 1503 | | else if (fn_proto.getCallconvExpr()) |callconv_expr| |
| 1504 | | tree.prevToken(tree.prevToken(callconv_expr.firstToken())) |
| 1505 | | else switch (fn_proto.return_type) { |
| 1506 | | .Explicit => |node| node.firstToken(), |
| 1507 | | .InferErrorSet => |node| tree.prevToken(node.firstToken()), |
| 1508 | | .Invalid => unreachable, |
| 1509 | | }); |
| 1569 | // the first token for the annotation expressions is the left |
| 1570 | // parenthesis, hence the need for two prevToken |
| 1571 | if (fn_proto.getAlignExpr()) |align_expr| |
| 1572 | tree.prevToken(tree.prevToken(align_expr.firstToken())) |
| 1573 | else if (fn_proto.getSectionExpr()) |section_expr| |
| 1574 | tree.prevToken(tree.prevToken(section_expr.firstToken())) |
| 1575 | else if (fn_proto.getCallconvExpr()) |callconv_expr| |
| 1576 | tree.prevToken(tree.prevToken(callconv_expr.firstToken())) |
| 1577 | else switch (fn_proto.return_type) { |
| 1578 | .Explicit => |node| node.firstToken(), |
| 1579 | .InferErrorSet => |node| tree.prevToken(node.firstToken()), |
| 1580 | .Invalid => unreachable, |
| 1581 | }, |
| 1582 | ); |
| 1510 | 1583 | assert(tree.token_ids[rparen] == .RParen); |
| 1511 | 1584 | |
| 1512 | 1585 | const src_params_trailing_comma = blk: { |
| ... | ... | @@ -1758,7 +1831,7 @@ fn renderExpression( |
| 1758 | 1831 | } |
| 1759 | 1832 | |
| 1760 | 1833 | if (while_node.payload) |payload| { |
| 1761 | | const payload_space = Space.Space; //if (while_node.continue_expr != null) Space.Space else block_start_space; |
| 1834 | const payload_space = if (while_node.continue_expr != null) Space.Space else block_start_space; |
| 1762 | 1835 | try renderExpression(allocator, ais, tree, payload, payload_space); |
| 1763 | 1836 | } |
| 1764 | 1837 | |
| ... | ... | @@ -1873,7 +1946,12 @@ fn renderExpression( |
| 1873 | 1946 | |
| 1874 | 1947 | if (src_has_newline) { |
| 1875 | 1948 | const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space; |
| 1876 | | try renderToken(tree, ais, rparen, after_rparen_space); // ) |
| 1949 | |
| 1950 | { |
| 1951 | ais.pushIndent(); |
| 1952 | defer ais.popIndent(); |
| 1953 | try renderToken(tree, ais, rparen, after_rparen_space); // ) |
| 1954 | } |
| 1877 | 1955 | |
| 1878 | 1956 | if (if_node.payload) |payload| { |
| 1879 | 1957 | try renderExpression(allocator, ais, tree, payload, Space.Newline); |
| ... | ... | @@ -2558,3 +2636,27 @@ fn copyFixingWhitespace(ais: anytype, slice: []const u8) @TypeOf(ais.*).Error!vo |
| 2558 | 2636 | else => try ais.writer().writeByte(byte), |
| 2559 | 2637 | }; |
| 2560 | 2638 | } |
| 2639 | |
| 2640 | fn rowSize(tree: *ast.Tree, exprs: []*ast.Node, rtoken: ast.TokenIndex) ?usize { |
| 2641 | const first_token = exprs[0].firstToken(); |
| 2642 | const first_loc = tree.tokenLocation(tree.token_locs[first_token].start, rtoken); |
| 2643 | if (first_loc.line == 0) { |
| 2644 | const maybe_comma = tree.prevToken(rtoken); |
| 2645 | if (tree.token_ids[maybe_comma] == .Comma) |
| 2646 | return 1; |
| 2647 | return null; // no newlines |
| 2648 | } |
| 2649 | |
| 2650 | var count: usize = 1; |
| 2651 | for (exprs) |expr, i| { |
| 2652 | if (i + 1 < exprs.len) { |
| 2653 | const expr_last_token = expr.lastToken() + 1; |
| 2654 | const loc = tree.tokenLocation(tree.token_locs[expr_last_token].start, exprs[i + 1].firstToken()); |
| 2655 | if (loc.line != 0) return count; |
| 2656 | count += 1; |
| 2657 | } else { |
| 2658 | return count; |
| 2659 | } |
| 2660 | } |
| 2661 | unreachable; |
| 2662 | } |