| ... | @@ -522,7 +522,11 @@ fn renderExpression( | ... | @@ -522,7 +522,11 @@ fn renderExpression( |
| 522 | break :blk if (loc.line == 0) op_space else Space.Newline; | 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 | ais.pushIndentOneShot(); | 530 | ais.pushIndentOneShot(); |
| 527 | return renderExpression(allocator, ais, tree, infix_op_node.rhs, space); | 531 | return renderExpression(allocator, ais, tree, infix_op_node.rhs, space); |
| 528 | }, | 532 | }, |
| ... | @@ -710,141 +714,194 @@ fn renderExpression( | ... | @@ -710,141 +714,194 @@ fn renderExpression( |
| 710 | .node => |node| tree.nextToken(node.lastToken()), | 714 | .node => |node| tree.nextToken(node.lastToken()), |
| 711 | }; | 715 | }; |
| 712 | | 716 | |
| 713 | if (exprs.len == 0) { | 717 | switch (lhs) { |
| 714 | switch (lhs) { | 718 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), |
| 715 | .dot => |dot| try renderToken(tree, ais, dot, Space.None), | 719 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), |
| 716 | .node => |node| try renderExpression(allocator, ais, tree, node, Space.None), | 720 | } |
| 717 | } | | |
| 718 | | | |
| 719 | { | | |
| 720 | ais.pushIndent(); | | |
| 721 | defer ais.popIndent(); | | |
| 722 | try renderToken(tree, ais, lbrace, Space.None); | | |
| 723 | } | | |
| 724 | | 721 | |
| | 722 | if (exprs.len == 0) { |
| | 723 | try renderToken(tree, ais, lbrace, Space.None); |
| 725 | return renderToken(tree, ais, rtoken, space); | 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 | const expr = exprs[0]; | 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 | try renderToken(tree, ais, lbrace, Space.None); | 730 | try renderToken(tree, ais, lbrace, Space.None); |
| 735 | try renderExpression(allocator, ais, tree, expr, Space.None); | 731 | try renderExpression(allocator, ais, tree, expr, Space.None); |
| 736 | return renderToken(tree, ais, rtoken, space); | 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 | // scan to find row size | 735 | // scan to find row size |
| 745 | const maybe_row_size: ?usize = blk: { | 736 | if (rowSize(tree, exprs, rtoken) != null) { |
| 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 | | | |
| 796 | { | 737 | { |
| 797 | ais.pushIndentNextLine(); | 738 | ais.pushIndentNextLine(); |
| 798 | defer ais.popIndent(); | 739 | defer ais.popIndent(); |
| 799 | try renderToken(tree, ais, lbrace, Space.Newline); | 740 | try renderToken(tree, ais, lbrace, Space.Newline); |
| 800 | | 741 | |
| 801 | var col: usize = 1; | 742 | var expr_index: usize = 0; |
| 802 | for (exprs) |expr, i| { | 743 | while (rowSize(tree, exprs[expr_index..], rtoken)) |row_size| { |
| 803 | if (i + 1 < exprs.len) { | 744 | const row_exprs = exprs[expr_index..]; |
| 804 | const next_expr = exprs[i + 1]; | 745 | // A place to store the width of each expression and its column's maximum |
| 805 | try renderExpression(allocator, ais, tree, expr, Space.None); | 746 | var widths = try allocator.alloc(usize, row_exprs.len + row_size); |
| 806 | | 747 | defer allocator.free(widths); |
| 807 | const comma = tree.nextToken(expr.*.lastToken()); | 748 | mem.set(usize, widths, 0); |
| 808 | | 749 | |
| 809 | if (col != row_size) { | 750 | var expr_newlines = try allocator.alloc(bool, row_exprs.len); |
| 810 | try renderToken(tree, ais, comma, Space.Space); // , | 751 | defer allocator.free(expr_newlines); |
| 811 | | 752 | mem.set(bool, expr_newlines, false); |
| 812 | const padding = column_widths[i % row_size] - expr_widths[i]; | 753 | |
| 813 | try ais.writer().writeByteNTimes(' ', padding); | 754 | var expr_widths = widths[0 .. widths.len - row_size]; |
| 814 | | 755 | var column_widths = widths[widths.len - row_size ..]; |
| 815 | col += 1; | 756 | |
| 816 | continue; | 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 | try renderToken(tree, ais, comma, Space.Newline); // , | 869 | try renderToken(tree, ais, comma, Space.Newline); // , |
| | 870 | try renderExtraNewline(tree, ais, next_expr); |
| 822 | } else { | 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); | 882 | if (expr_index == exprs.len) { |
| 827 | } else { | 883 | break; |
| 828 | try renderExpression(allocator, ais, tree, expr, Space.Comma); // , | | |
| 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 | return renderToken(tree, ais, rtoken, space); | 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 | .StructInitializer, .StructInitializerDot => { | 907 | .StructInitializer, .StructInitializerDot => { |
| ... | @@ -1004,21 +1061,29 @@ fn renderExpression( | ... | @@ -1004,21 +1061,29 @@ fn renderExpression( |
| 1004 | }; | 1061 | }; |
| 1005 | | 1062 | |
| 1006 | if (src_has_trailing_comma) { | 1063 | if (src_has_trailing_comma) { |
| 1007 | try renderToken(tree, ais, lparen, Space.Newline); | 1064 | { |
| 1008 | | | |
| 1009 | const params = call.params(); | | |
| 1010 | for (params) |param_node, i| { | | |
| 1011 | ais.pushIndent(); | 1065 | ais.pushIndent(); |
| 1012 | defer ais.popIndent(); | 1066 | defer ais.popIndent(); |
| 1013 | | 1067 | |
| 1014 | if (i + 1 < params.len) { | 1068 | try renderToken(tree, ais, lparen, Space.Newline); // ( |
| 1015 | const next_node = params[i + 1]; | 1069 | const params = call.params(); |
| 1016 | try renderExpression(allocator, ais, tree, param_node, Space.None); | 1070 | for (params) |param_node, i| { |
| 1017 | const comma = tree.nextToken(param_node.lastToken()); | 1071 | if (i + 1 < params.len) { |
| 1018 | try renderToken(tree, ais, comma, Space.Newline); // , | 1072 | const next_node = params[i + 1]; |
| 1019 | try renderExtraNewline(tree, ais, next_node); | 1073 | try renderExpression(allocator, ais, tree, param_node, Space.None); |
| 1020 | } else { | 1074 | |
| 1021 | try renderExpression(allocator, ais, tree, param_node, Space.Comma); | 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 | return renderToken(tree, ais, call.rtoken, space); | 1089 | return renderToken(tree, ais, call.rtoken, space); |
| ... | @@ -1028,17 +1093,20 @@ fn renderExpression( | ... | @@ -1028,17 +1093,20 @@ fn renderExpression( |
| 1028 | | 1093 | |
| 1029 | const params = call.params(); | 1094 | const params = call.params(); |
| 1030 | for (params) |param_node, i| { | 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 | try renderExpression(allocator, ais, tree, param_node, Space.None); | 1102 | try renderExpression(allocator, ais, tree, param_node, Space.None); |
| 1034 | | 1103 | |
| 1035 | if (i + 1 < params.len) { | 1104 | if (i + 1 < params.len) { |
| 1036 | const next_param = params[i + 1]; | | |
| 1037 | const comma = tree.nextToken(param_node.lastToken()); | 1105 | const comma = tree.nextToken(param_node.lastToken()); |
| 1038 | try renderToken(tree, ais, comma, Space.Space); | 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 | .ArrayAccess => { | 1112 | .ArrayAccess => { |
| ... | @@ -1429,7 +1497,7 @@ fn renderExpression( | ... | @@ -1429,7 +1497,7 @@ fn renderExpression( |
| 1429 | try renderToken(tree, ais, builtin_call.builtin_token, Space.None); // @name | 1497 | try renderToken(tree, ais, builtin_call.builtin_token, Space.None); // @name |
| 1430 | | 1498 | |
| 1431 | const src_params_trailing_comma = blk: { | 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 | const last_node = builtin_call.params()[builtin_call.params_len - 1]; | 1501 | const last_node = builtin_call.params()[builtin_call.params_len - 1]; |
| 1434 | const maybe_comma = tree.nextToken(last_node.lastToken()); | 1502 | const maybe_comma = tree.nextToken(last_node.lastToken()); |
| 1435 | break :blk tree.token_ids[maybe_comma] == .Comma; | 1503 | break :blk tree.token_ids[maybe_comma] == .Comma; |
| ... | @@ -1443,6 +1511,10 @@ fn renderExpression( | ... | @@ -1443,6 +1511,10 @@ fn renderExpression( |
| 1443 | // render all on one line, no trailing comma | 1511 | // render all on one line, no trailing comma |
| 1444 | const params = builtin_call.params(); | 1512 | const params = builtin_call.params(); |
| 1445 | for (params) |param_node, i| { | 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 | try renderExpression(allocator, ais, tree, param_node, Space.None); | 1518 | try renderExpression(allocator, ais, tree, param_node, Space.None); |
| 1447 | | 1519 | |
| 1448 | if (i + 1 < params.len) { | 1520 | if (i + 1 < params.len) { |
| ... | @@ -1494,19 +1566,20 @@ fn renderExpression( | ... | @@ -1494,19 +1566,20 @@ fn renderExpression( |
| 1494 | assert(tree.token_ids[lparen] == .LParen); | 1566 | assert(tree.token_ids[lparen] == .LParen); |
| 1495 | | 1567 | |
| 1496 | const rparen = tree.prevToken( | 1568 | const rparen = tree.prevToken( |
| 1497 | // the first token for the annotation expressions is the left | 1569 | // the first token for the annotation expressions is the left |
| 1498 | // parenthesis, hence the need for two prevToken | 1570 | // parenthesis, hence the need for two prevToken |
| 1499 | if (fn_proto.getAlignExpr()) |align_expr| | 1571 | if (fn_proto.getAlignExpr()) |align_expr| |
| 1500 | tree.prevToken(tree.prevToken(align_expr.firstToken())) | 1572 | tree.prevToken(tree.prevToken(align_expr.firstToken())) |
| 1501 | else if (fn_proto.getSectionExpr()) |section_expr| | 1573 | else if (fn_proto.getSectionExpr()) |section_expr| |
| 1502 | tree.prevToken(tree.prevToken(section_expr.firstToken())) | 1574 | tree.prevToken(tree.prevToken(section_expr.firstToken())) |
| 1503 | else if (fn_proto.getCallconvExpr()) |callconv_expr| | 1575 | else if (fn_proto.getCallconvExpr()) |callconv_expr| |
| 1504 | tree.prevToken(tree.prevToken(callconv_expr.firstToken())) | 1576 | tree.prevToken(tree.prevToken(callconv_expr.firstToken())) |
| 1505 | else switch (fn_proto.return_type) { | 1577 | else switch (fn_proto.return_type) { |
| 1506 | .Explicit => |node| node.firstToken(), | 1578 | .Explicit => |node| node.firstToken(), |
| 1507 | .InferErrorSet => |node| tree.prevToken(node.firstToken()), | 1579 | .InferErrorSet => |node| tree.prevToken(node.firstToken()), |
| 1508 | .Invalid => unreachable, | 1580 | .Invalid => unreachable, |
| 1509 | }); | 1581 | }, |
| | 1582 | ); |
| 1510 | assert(tree.token_ids[rparen] == .RParen); | 1583 | assert(tree.token_ids[rparen] == .RParen); |
| 1511 | | 1584 | |
| 1512 | const src_params_trailing_comma = blk: { | 1585 | const src_params_trailing_comma = blk: { |
| ... | @@ -1758,7 +1831,7 @@ fn renderExpression( | ... | @@ -1758,7 +1831,7 @@ fn renderExpression( |
| 1758 | } | 1831 | } |
| 1759 | | 1832 | |
| 1760 | if (while_node.payload) |payload| { | 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 | try renderExpression(allocator, ais, tree, payload, payload_space); | 1835 | try renderExpression(allocator, ais, tree, payload, payload_space); |
| 1763 | } | 1836 | } |
| 1764 | | 1837 | |
| ... | @@ -1873,7 +1946,12 @@ fn renderExpression( | ... | @@ -1873,7 +1946,12 @@ fn renderExpression( |
| 1873 | | 1946 | |
| 1874 | if (src_has_newline) { | 1947 | if (src_has_newline) { |
| 1875 | const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space; | 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 | if (if_node.payload) |payload| { | 1956 | if (if_node.payload) |payload| { |
| 1879 | try renderExpression(allocator, ais, tree, payload, Space.Newline); | 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,3 +2636,27 @@ fn copyFixingWhitespace(ais: anytype, slice: []const u8) @TypeOf(ais.*).Error!vo |
| 2558 | else => try ais.writer().writeByte(byte), | 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 | } |