authorgravatar for legaul@cisco.comLewis Gaul <legaul@cisco.com> 2021-02-28 23:46:35+00:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-15 14:55:34+01:00
logb4db03d8bb29f0cded857300df460b4247e85670
tree57d801b9efa60deaa615c16a1c3a6db0604e46bd
parenta502c160cd51ce3de80b3be945245b7a91967a85

zig fmt: fix extra newline before if nested in for

Add failing testcase to reproduce issue 8088 Tidy up renderWhile(), factoring out renderWhilePayload() Ensure correct newline is used before 'then' token in while/for/if Handle indents for 'if' inside 'for' or 'while' Stop special-casing 'if' compared to 'for' and 'while'

2 files changed, 76 insertions(+), 75 deletions(-)

lib/std/zig/parser_test.zig+25
......@@ -3184,6 +3184,31 @@ test "zig fmt: for" {
31843184 );
31853185}
31863186
3187test "zig fmt: for if" {
3188 try testCanonical(
3189 \\test "for if" {
3190 \\ for (a) |x| if (x) f(x);
3191 \\
3192 \\ for (a) |x| if (x)
3193 \\ f(x);
3194 \\
3195 \\ for (a) |x| if (x) {
3196 \\ f(x);
3197 \\ };
3198 \\
3199 \\ for (a) |x|
3200 \\ if (x)
3201 \\ f(x);
3202 \\
3203 \\ for (a) |x|
3204 \\ if (x) {
3205 \\ f(x);
3206 \\ };
3207 \\}
3208 \\
3209 );
3210}
3211
31873212test "zig fmt: if" {
31883213 try testCanonical(
31893214 \\test "if" {
lib/std/zig/render.zig+51-75
......@@ -1025,31 +1025,11 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
10251025 const then_tag = node_tags[while_node.ast.then_expr];
10261026 if (nodeIsBlock(then_tag) and !nodeIsIf(then_tag)) {
10271027 if (while_node.payload_token) |payload_token| {
1028 try renderToken(ais, tree, payload_token - 2, .space); // rparen
1029 try renderToken(ais, tree, payload_token - 1, .none); // |
1030 const ident = blk: {
1031 if (token_tags[payload_token] == .asterisk) {
1032 try renderToken(ais, tree, payload_token, .none); // *
1033 break :blk payload_token + 1;
1034 } else {
1035 break :blk payload_token;
1036 }
1037 };
1038 try renderToken(ais, tree, ident, .none); // identifier
1039 const pipe = blk: {
1040 if (token_tags[ident + 1] == .comma) {
1041 try renderToken(ais, tree, ident + 1, .space); // ,
1042 try renderToken(ais, tree, ident + 2, .none); // index
1043 break :blk ident + 3;
1044 } else {
1045 break :blk ident + 1;
1046 }
1047 };
10481028 const brace_space = if (while_node.ast.cont_expr == 0 and ais.isLineOverIndented())
10491029 Space.newline
10501030 else
10511031 Space.space;
1052 try renderToken(ais, tree, pipe, brace_space); // |
1032 try renderWhilePayload(gpa, ais, tree, payload_token, brace_space);
10531033 } else {
10541034 const rparen = tree.lastToken(while_node.ast.cond_expr) + 1;
10551035 const brace_space = if (while_node.ast.cont_expr == 0 and ais.isLineOverIndented())
......@@ -1082,38 +1062,23 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
10821062 }
10831063
10841064 const rparen = tree.lastToken(while_node.ast.cond_expr) + 1;
1065 const first_then_token = tree.firstToken(while_node.ast.then_expr);
10851066 const last_then_token = tree.lastToken(while_node.ast.then_expr);
10861067 const src_has_newline = !tree.tokensOnSameLine(rparen, last_then_token);
10871068
10881069 if (src_has_newline) {
1070 const newline_before_then_token = !tree.tokensOnSameLine(rparen, first_then_token);
1071 const space_before_then_token: Space = if (newline_before_then_token) .newline else .space;
1072 const indent_expression = !nodeIsIf(then_tag) or newline_before_then_token;
1073
10891074 if (while_node.payload_token) |payload_token| {
1090 try renderToken(ais, tree, payload_token - 2, .space); // rparen
1091 try renderToken(ais, tree, payload_token - 1, .none); // |
1092 const ident = blk: {
1093 if (token_tags[payload_token] == .asterisk) {
1094 try renderToken(ais, tree, payload_token, .none); // *
1095 break :blk payload_token + 1;
1096 } else {
1097 break :blk payload_token;
1098 }
1099 };
1100 try renderToken(ais, tree, ident, .none); // identifier
1101 const pipe = blk: {
1102 if (token_tags[ident + 1] == .comma) {
1103 try renderToken(ais, tree, ident + 1, .space); // ,
1104 try renderToken(ais, tree, ident + 2, .none); // index
1105 break :blk ident + 3;
1106 } else {
1107 break :blk ident + 1;
1108 }
1109 };
1110 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline;
1111 try renderToken(ais, tree, pipe, after_space); // |
1075 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else space_before_then_token;
1076 try renderWhilePayload(gpa, ais, tree, payload_token, after_space);
11121077 } else {
1113 ais.pushIndent();
1114 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline;
1078 if (indent_expression) ais.pushIndent();
1079 const after_space: Space = if (while_node.ast.cont_expr != 0) .space else space_before_then_token;
11151080 try renderToken(ais, tree, rparen, after_space); // rparen
1116 ais.popIndent();
1081 if (indent_expression) ais.popIndent();
11171082 }
11181083 if (while_node.ast.cont_expr != 0) {
11191084 const cont_rparen = tree.lastToken(while_node.ast.cont_expr) + 1;
......@@ -1121,12 +1086,12 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
11211086 try renderToken(ais, tree, cont_lparen - 1, .space); // :
11221087 try renderToken(ais, tree, cont_lparen, .none); // lparen
11231088 try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none);
1124 try renderToken(ais, tree, cont_rparen, .newline); // rparen
1089 try renderToken(ais, tree, cont_rparen, space_before_then_token); // rparen
11251090 }
11261091 if (while_node.ast.else_expr != 0) {
1127 ais.pushIndent();
1128 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, Space.newline);
1129 ais.popIndent();
1092 if (indent_expression) ais.pushIndent();
1093 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .newline);
1094 if (indent_expression) ais.popIndent();
11301095 const else_is_block = nodeIsBlock(node_tags[while_node.ast.else_expr]);
11311096 if (else_is_block) {
11321097 try renderToken(ais, tree, while_node.else_token, .space); // else
......@@ -1145,12 +1110,18 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
11451110 } else {
11461111 try renderToken(ais, tree, while_node.else_token, .newline); // else
11471112 }
1148 try renderExpressionIndented(gpa, ais, tree, while_node.ast.else_expr, space);
1149 return;
1113 if (indent_expression) {
1114 return renderExpressionIndented(gpa, ais, tree, while_node.ast.else_expr, space);
1115 } else {
1116 return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space);
1117 }
11501118 }
11511119 } else {
1152 try renderExpressionIndented(gpa, ais, tree, while_node.ast.then_expr, space);
1153 return;
1120 if (indent_expression) {
1121 return renderExpressionIndented(gpa, ais, tree, while_node.ast.then_expr, space);
1122 } else {
1123 return renderExpression(gpa, ais, tree, while_node.ast.then_expr, space);
1124 }
11541125 }
11551126 }
11561127
......@@ -1158,27 +1129,7 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
11581129
11591130 if (while_node.payload_token) |payload_token| {
11601131 assert(payload_token - 2 == rparen);
1161 try renderToken(ais, tree, payload_token - 2, .space); // )
1162 try renderToken(ais, tree, payload_token - 1, .none); // |
1163 const ident = blk: {
1164 if (token_tags[payload_token] == .asterisk) {
1165 try renderToken(ais, tree, payload_token, .none); // *
1166 break :blk payload_token + 1;
1167 } else {
1168 break :blk payload_token;
1169 }
1170 };
1171 try renderToken(ais, tree, ident, .none); // identifier
1172 const pipe = blk: {
1173 if (token_tags[ident + 1] == .comma) {
1174 try renderToken(ais, tree, ident + 1, .space); // ,
1175 try renderToken(ais, tree, ident + 2, .none); // index
1176 break :blk ident + 3;
1177 } else {
1178 break :blk ident + 1;
1179 }
1180 };
1181 try renderToken(ais, tree, pipe, .space); // |
1132 try renderWhilePayload(gpa, ais, tree, payload_token, .space);
11821133 } else {
11831134 try renderToken(ais, tree, rparen, .space); // )
11841135 }
......@@ -1208,6 +1159,31 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
12081159 }
12091160}
12101161
1162fn renderWhilePayload(gpa: *Allocator, ais: *Ais, tree: ast.Tree, payload_token: ast.TokenIndex, space: Space) Error!void {
1163 const token_tags = tree.tokens.items(.tag);
1164 try renderToken(ais, tree, payload_token - 2, .space); // rparen
1165 try renderToken(ais, tree, payload_token - 1, .none); // |
1166 const ident = blk: {
1167 if (token_tags[payload_token] == .asterisk) {
1168 try renderToken(ais, tree, payload_token, .none); // *
1169 break :blk payload_token + 1;
1170 } else {
1171 break :blk payload_token;
1172 }
1173 };
1174 try renderToken(ais, tree, ident, .none); // identifier
1175 const pipe = blk: {
1176 if (token_tags[ident + 1] == .comma) {
1177 try renderToken(ais, tree, ident + 1, .space); // ,
1178 try renderToken(ais, tree, ident + 2, .none); // index
1179 break :blk ident + 3;
1180 } else {
1181 break :blk ident + 1;
1182 }
1183 };
1184 try renderToken(ais, tree, pipe, space); // |
1185}
1186
12111187fn renderContainerField(
12121188 gpa: *Allocator,
12131189 ais: *Ais,