authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-28 22:22:01-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-28 22:22:01-04:00
log77ec81b0353eac45a66b4ed79821c8c954032345
tree48516212340c012c8339d3f1e1dcad0e8b699ad4
parent71badebd08a1e5da9326fc7126c4de0fba4ae3d0

zig fmt: respect line breaks in if-else


2 files changed, 107 insertions(+), 28 deletions(-)

std/zig/parser_test.zig+19
......@@ -1,3 +1,22 @@
1test "zig fmt: respect line breaks in if-else" {
2 try testCanonical(
3 \\comptime {
4 \\ return if (cond) a else b;
5 \\ return if (cond)
6 \\ a
7 \\ else
8 \\ b;
9 \\ return if (cond)
10 \\ a
11 \\ else if (cond)
12 \\ b
13 \\ else
14 \\ c;
15 \\}
16 \\
17 );
18}
19
120test "zig fmt: respect line breaks after infix operators" {
221 try testCanonical(
322 \\comptime {
std/zig/render.zig+88-28
......@@ -1315,49 +1315,109 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
13151315 ast.Node.Id.If => {
13161316 const if_node = @fieldParentPtr(ast.Node.If, "base", base);
13171317
1318 try renderToken(tree, stream, if_node.if_token, indent, Space.Space);
1319 try renderToken(tree, stream, tree.prevToken(if_node.condition.firstToken()), indent, Space.None);
1318 const lparen = tree.prevToken(if_node.condition.firstToken());
1319 const rparen = tree.nextToken(if_node.condition.lastToken());
13201320
1321 try renderExpression(allocator, stream, tree, indent, if_node.condition, Space.None);
1322 try renderToken(tree, stream, tree.nextToken(if_node.condition.lastToken()), indent, Space.Space);
1321 try renderToken(tree, stream, if_node.if_token, indent, Space.Space); // if
1322 try renderToken(tree, stream, lparen, indent, Space.None); // (
13231323
1324 if (if_node.payload) |payload| {
1325 try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
1326 }
1324 try renderExpression(allocator, stream, tree, indent, if_node.condition, Space.None); // condition
13271325
1328 switch (if_node.body.id) {
1326 const body_is_block = switch (if_node.body.id) {
13291327 ast.Node.Id.Block,
13301328 ast.Node.Id.If,
13311329 ast.Node.Id.For,
13321330 ast.Node.Id.While,
1333 ast.Node.Id.Switch => {
1334 if (if_node.@"else") |@"else"| {
1335 if (if_node.body.id == ast.Node.Id.Block) {
1336 try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Space);
1337 } else {
1338 try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Newline);
1339 try stream.writeByteNTimes(' ', indent);
1340 }
1331 ast.Node.Id.Switch,
1332 => true,
1333 else => false,
1334 };
13411335
1342 try renderExpression(allocator, stream, tree, indent, &@"else".base, space);
1343 } else {
1344 try renderExpression(allocator, stream, tree, indent, if_node.body, space);
1345 }
1346 },
1347 else => {
1348 if (if_node.@"else") |@"else"| {
1349 try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Space);
1350 try renderToken(tree, stream, @"else".else_token, indent, Space.Space);
1336 if (body_is_block) {
1337 try renderToken(tree, stream, rparen, indent, Space.Space); // )
1338
1339 if (if_node.payload) |payload| {
1340 try renderExpression(allocator, stream, tree, indent, payload, Space.Space); // |x|
1341 }
1342
1343 if (if_node.@"else") |@"else"| {
1344 try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Space);
1345 return renderExpression(allocator, stream, tree, indent, &@"else".base, space);
1346 } else {
1347 return renderExpression(allocator, stream, tree, indent, if_node.body, space);
1348 }
1349 }
1350
1351 const src_has_newline = blk: {
1352 const loc = tree.tokenLocation(tree.tokens.at(rparen).end, if_node.body.lastToken());
1353 break :blk loc.line != 0;
1354 };
1355
1356 if (src_has_newline) {
1357 const after_rparen_space = if (if_node.payload == null) Space.Newline else Space.Space;
1358 try renderToken(tree, stream, rparen, indent, after_rparen_space); // )
1359
1360 if (if_node.payload) |payload| {
1361 try renderExpression(allocator, stream, tree, indent, payload, Space.Newline);
1362 }
1363
1364 const new_indent = indent + indent_delta;
1365 try stream.writeByteNTimes(' ', new_indent);
1366
1367 if (if_node.@"else") |@"else"| {
1368 const else_is_block = switch (@"else".body.id) {
1369 ast.Node.Id.Block,
1370 ast.Node.Id.If,
1371 ast.Node.Id.For,
1372 ast.Node.Id.While,
1373 ast.Node.Id.Switch,
1374 => true,
1375 else => false,
1376 };
1377 try renderExpression(allocator, stream, tree, new_indent, if_node.body, Space.Newline);
1378 try stream.writeByteNTimes(' ', indent);
1379
1380 if (else_is_block) {
1381 try renderToken(tree, stream, @"else".else_token, indent, Space.Space); // else
13511382
13521383 if (@"else".payload) |payload| {
13531384 try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
13541385 }
13551386
1356 try renderExpression(allocator, stream, tree, indent, @"else".body, space);
1387 return renderExpression(allocator, stream, tree, indent, @"else".body, space);
13571388 } else {
1358 try renderExpression(allocator, stream, tree, indent, if_node.body, space);
1389 const after_else_space = if (@"else".payload == null) Space.Newline else Space.Space;
1390 try renderToken(tree, stream, @"else".else_token, indent, after_else_space); // else
1391
1392 if (@"else".payload) |payload| {
1393 try renderExpression(allocator, stream, tree, indent, payload, Space.Newline);
1394 }
1395 try stream.writeByteNTimes(' ', new_indent);
1396
1397 return renderExpression(allocator, stream, tree, new_indent, @"else".body, space);
13591398 }
1360 },
1399 } else {
1400 return renderExpression(allocator, stream, tree, new_indent, if_node.body, space);
1401 }
1402 }
1403
1404 try renderToken(tree, stream, rparen, indent, Space.Space); // )
1405
1406 if (if_node.payload) |payload| {
1407 try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
1408 }
1409
1410 if (if_node.@"else") |@"else"| {
1411 try renderExpression(allocator, stream, tree, indent, if_node.body, Space.Space);
1412 try renderToken(tree, stream, @"else".else_token, indent, Space.Space);
1413
1414 if (@"else".payload) |payload| {
1415 try renderExpression(allocator, stream, tree, indent, payload, Space.Space);
1416 }
1417
1418 return renderExpression(allocator, stream, tree, indent, @"else".body, space);
1419 } else {
1420 return renderExpression(allocator, stream, tree, indent, if_node.body, space);
13611421 }
13621422 },
13631423