authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-24 13:46:11+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-24 13:46:11+01:00
log371b21bdfbfa8917b44e809fb8a041411ffc6b8a
tree60e75816fba82121406b4fe094214e5a20f0ca28
parent15c7c6ab970830a87b6aa502a369fb2b29b933c5
signaturelock-open Commit is signed but in an unrecognized format.

zig fmt: fix comment indent after multiline single statement if/while/for


2 files changed, 89 insertions(+), 33 deletions(-)

lib/std/zig/parser_test.zig+29-13
...@@ -4164,19 +4164,35 @@ test "zig fmt: for loop with ptr payload and index" {...@@ -4164,19 +4164,35 @@ test "zig fmt: for loop with ptr payload and index" {
4164 );4164 );
4165}4165}
41664166
4167// TODO4167test "zig fmt: proper indent line comment after multi-line single expr while loop" {
4168//test "zig fmt: proper indent line comment after multi-line single expr while loop" {4168 try testCanonical(
4169// try testCanonical(4169 \\test {
4170// \\test {4170 \\ while (a) : (b)
4171// \\ while (a) : (b)4171 \\ foo();
4172// \\ foo();4172 \\
4173// \\4173 \\ // bar
4174// \\ // bar4174 \\ baz();
4175// \\ baz();4175 \\}
4176// \\}4176 \\
4177// \\4177 );
4178// );4178}
4179//}4179
4180test "zig fmt: line comment after multiline single expr if statement with multiline string" {
4181 try testCanonical(
4182 \\test {
4183 \\ if (foo)
4184 \\ x =
4185 \\ \\hello
4186 \\ \\hello
4187 \\ \\
4188 \\ ;
4189 \\
4190 \\ // bar
4191 \\ baz();
4192 \\}
4193 \\
4194 );
4195}
41804196
4181test "zig fmt: respect extra newline between fn and pub usingnamespace" {4197test "zig fmt: respect extra newline between fn and pub usingnamespace" {
4182 try testCanonical(4198 try testCanonical(
lib/std/zig/render.zig+60-20
...@@ -203,7 +203,9 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I...@@ -203,7 +203,9 @@ fn renderExpression(gpa: *Allocator, ais: *Ais, tree: ast.Tree, node: ast.Node.I
203203
204 switch (space) {204 switch (space) {
205 .none, .space, .newline => {},205 .none, .space, .newline => {},
206 .newline_pop => ais.popIndent(),
206 .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline),207 .semicolon => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline),
208 .semicolon_pop => if (token_tags[i] == .semicolon) try renderToken(ais, tree, i, .newline_pop),
207 .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline),209 .comma => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .newline),
208 .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space),210 .comma_space => if (token_tags[i] == .comma) try renderToken(ais, tree, i, .space),
209 }211 }
...@@ -1152,8 +1154,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full....@@ -1152,8 +1154,8 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full.
1152 }1154 }
1153 } else {1155 } else {
1154 ais.pushIndent();1156 ais.pushIndent();
1155 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, space);1157 assert(space == .semicolon);
1156 ais.popIndent();1158 try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .semicolon_pop);
1157 return;1159 return;
1158 }1160 }
1159 }1161 }
...@@ -2196,6 +2198,9 @@ const Space = enum {...@@ -2196,6 +2198,9 @@ const Space = enum {
2196 space,2198 space,
2197 /// Output the token lexeme followed by a newline.2199 /// Output the token lexeme followed by a newline.
2198 newline,2200 newline,
2201 /// Same as newline, but pop an indent level before rendering the
2202 /// following comments if any.
2203 newline_pop,
2199 /// If the next token is a comma, render it as well. If not, insert one.2204 /// If the next token is a comma, render it as well. If not, insert one.
2200 /// In either case, a newline will be inserted afterwards.2205 /// In either case, a newline will be inserted afterwards.
2201 comma,2206 comma,
...@@ -2205,6 +2210,9 @@ const Space = enum {...@@ -2205,6 +2210,9 @@ const Space = enum {
2205 /// Additionally consume the next token if it is a semicolon.2210 /// Additionally consume the next token if it is a semicolon.
2206 /// In either case, a newline will be inserted afterwards.2211 /// In either case, a newline will be inserted afterwards.
2207 semicolon,2212 semicolon,
2213 /// Same as semicolon, but pop an indent level before rendering the
2214 /// following comments if any.
2215 semicolon_pop,
2208};2216};
22092217
2210fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void {2218fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Space) Error!void {
...@@ -2216,32 +2224,64 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp...@@ -2216,32 +2224,64 @@ fn renderToken(ais: *Ais, tree: ast.Tree, token_index: ast.TokenIndex, space: Sp
22162224
2217 try ais.writer().writeAll(lexeme);2225 try ais.writer().writeAll(lexeme);
22182226
2219 if (space == .comma and token_tags[token_index + 1] != .comma) {2227 const token_end = token_start + lexeme.len;
2220 try ais.writer().writeByte(',');2228 const next_token_start = token_starts[token_index + 1];
2221 }
2222
2223 const comment = try renderComments(ais, tree, token_start + lexeme.len, token_starts[token_index + 1]);
2224 switch (space) {2229 switch (space) {
2225 .none => {},2230 .none => _ = try renderComments(ais, tree, token_end, next_token_start),
2226 .space => if (!comment) try ais.writer().writeByte(' '),
2227 .newline => if (!comment) try ais.insertNewline(),
22282231
2229 .comma => if (token_tags[token_index + 1] == .comma) {2232 .space => if (!try renderComments(ais, tree, token_end, next_token_start)) {
2230 try renderToken(ais, tree, token_index + 1, .newline);2233 try ais.writer().writeByte(' ');
2231 } else if (!comment) {2234 },
2235
2236 .newline => if (!try renderComments(ais, tree, token_end, next_token_start)) {
2232 try ais.insertNewline();2237 try ais.insertNewline();
2233 },2238 },
22342239
2235 .comma_space => if (token_tags[token_index + 1] == .comma) {2240 .newline_pop => {
2236 try renderToken(ais, tree, token_index + 1, .space);2241 ais.popIndent();
2237 } else if (!comment) {2242 if (!try renderComments(ais, tree, token_end, next_token_start)) {
2238 try ais.writer().writeByte(' ');2243 try ais.insertNewline();
2244 }
2239 },2245 },
22402246
2241 .semicolon => if (token_tags[token_index + 1] == .semicolon) {2247 .comma => if (token_tags[token_index + 1] == .comma) {
2248 _ = try renderComments(ais, tree, token_end, next_token_start);
2242 try renderToken(ais, tree, token_index + 1, .newline);2249 try renderToken(ais, tree, token_index + 1, .newline);
2243 } else if (!comment) {2250 } else {
2244 try ais.insertNewline();2251 try ais.writer().writeByte(',');
2252 if (!try renderComments(ais, tree, token_end, next_token_start)) {
2253 try ais.insertNewline();
2254 }
2255 },
2256
2257 .comma_space => {
2258 const comment = try renderComments(ais, tree, token_end, next_token_start);
2259 if (token_tags[token_index + 1] == .comma) {
2260 try renderToken(ais, tree, token_index + 1, .space);
2261 } else if (!comment) {
2262 try ais.writer().writeByte(' ');
2263 }
2264 },
2265
2266 .semicolon => {
2267 const comment = try renderComments(ais, tree, token_end, next_token_start);
2268 if (token_tags[token_index + 1] == .semicolon) {
2269 try renderToken(ais, tree, token_index + 1, .newline);
2270 } else if (!comment) {
2271 try ais.insertNewline();
2272 }
2273 },
2274
2275 .semicolon_pop => {
2276 if (token_tags[token_index + 1] == .semicolon) {
2277 _ = try renderComments(ais, tree, token_end, next_token_start);
2278 try renderToken(ais, tree, token_index + 1, .newline_pop);
2279 } else {
2280 ais.popIndent();
2281 if (!try renderComments(ais, tree, token_end, next_token_start)) {
2282 try ais.insertNewline();
2283 }
2284 }
2245 },2285 },
2246 }2286 }
2247}2287}