From b4db03d8bb29f0cded857300df460b4247e85670 Mon Sep 17 00:00:00 2001 From: Lewis Gaul Date: Sun, 28 Feb 2021 23:46:35 +0000 Subject: [PATCH] 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' --- lib/std/zig/parser_test.zig | 25 +++++++ lib/std/zig/render.zig | 126 +++++++++++++++--------------------- 2 files changed, 76 insertions(+), 75 deletions(-) diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index b6bd2844a486fad586b7f29aea219077223dbbd7..e4a9583887339da106f4a6f2623e12b00b24f68a 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -3184,6 +3184,31 @@ test "zig fmt: for" { ); } +test "zig fmt: for if" { + try testCanonical( + \\test "for if" { + \\ for (a) |x| if (x) f(x); + \\ + \\ for (a) |x| if (x) + \\ f(x); + \\ + \\ for (a) |x| if (x) { + \\ f(x); + \\ }; + \\ + \\ for (a) |x| + \\ if (x) + \\ f(x); + \\ + \\ for (a) |x| + \\ if (x) { + \\ f(x); + \\ }; + \\} + \\ + ); +} + test "zig fmt: if" { try testCanonical( \\test "if" { diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 30e83e9a7c278c43d7b8cbca6783724e702268d4..23e9e030857e93f50de8049c5b29852050af6f01 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -1025,31 +1025,11 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. const then_tag = node_tags[while_node.ast.then_expr]; if (nodeIsBlock(then_tag) and !nodeIsIf(then_tag)) { if (while_node.payload_token) |payload_token| { - try renderToken(ais, tree, payload_token - 2, .space); // rparen - try renderToken(ais, tree, payload_token - 1, .none); // | - const ident = blk: { - if (token_tags[payload_token] == .asterisk) { - try renderToken(ais, tree, payload_token, .none); // * - break :blk payload_token + 1; - } else { - break :blk payload_token; - } - }; - try renderToken(ais, tree, ident, .none); // identifier - const pipe = blk: { - if (token_tags[ident + 1] == .comma) { - try renderToken(ais, tree, ident + 1, .space); // , - try renderToken(ais, tree, ident + 2, .none); // index - break :blk ident + 3; - } else { - break :blk ident + 1; - } - }; const brace_space = if (while_node.ast.cont_expr == 0 and ais.isLineOverIndented()) Space.newline else Space.space; - try renderToken(ais, tree, pipe, brace_space); // | + try renderWhilePayload(gpa, ais, tree, payload_token, brace_space); } else { const rparen = tree.lastToken(while_node.ast.cond_expr) + 1; 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. } const rparen = tree.lastToken(while_node.ast.cond_expr) + 1; + const first_then_token = tree.firstToken(while_node.ast.then_expr); const last_then_token = tree.lastToken(while_node.ast.then_expr); const src_has_newline = !tree.tokensOnSameLine(rparen, last_then_token); if (src_has_newline) { + const newline_before_then_token = !tree.tokensOnSameLine(rparen, first_then_token); + const space_before_then_token: Space = if (newline_before_then_token) .newline else .space; + const indent_expression = !nodeIsIf(then_tag) or newline_before_then_token; + if (while_node.payload_token) |payload_token| { - try renderToken(ais, tree, payload_token - 2, .space); // rparen - try renderToken(ais, tree, payload_token - 1, .none); // | - const ident = blk: { - if (token_tags[payload_token] == .asterisk) { - try renderToken(ais, tree, payload_token, .none); // * - break :blk payload_token + 1; - } else { - break :blk payload_token; - } - }; - try renderToken(ais, tree, ident, .none); // identifier - const pipe = blk: { - if (token_tags[ident + 1] == .comma) { - try renderToken(ais, tree, ident + 1, .space); // , - try renderToken(ais, tree, ident + 2, .none); // index - break :blk ident + 3; - } else { - break :blk ident + 1; - } - }; - const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline; - try renderToken(ais, tree, pipe, after_space); // | + const after_space: Space = if (while_node.ast.cont_expr != 0) .space else space_before_then_token; + try renderWhilePayload(gpa, ais, tree, payload_token, after_space); } else { - ais.pushIndent(); - const after_space: Space = if (while_node.ast.cont_expr != 0) .space else .newline; + if (indent_expression) ais.pushIndent(); + const after_space: Space = if (while_node.ast.cont_expr != 0) .space else space_before_then_token; try renderToken(ais, tree, rparen, after_space); // rparen - ais.popIndent(); + if (indent_expression) ais.popIndent(); } if (while_node.ast.cont_expr != 0) { 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. try renderToken(ais, tree, cont_lparen - 1, .space); // : try renderToken(ais, tree, cont_lparen, .none); // lparen try renderExpression(gpa, ais, tree, while_node.ast.cont_expr, .none); - try renderToken(ais, tree, cont_rparen, .newline); // rparen + try renderToken(ais, tree, cont_rparen, space_before_then_token); // rparen } if (while_node.ast.else_expr != 0) { - ais.pushIndent(); - try renderExpression(gpa, ais, tree, while_node.ast.then_expr, Space.newline); - ais.popIndent(); + if (indent_expression) ais.pushIndent(); + try renderExpression(gpa, ais, tree, while_node.ast.then_expr, .newline); + if (indent_expression) ais.popIndent(); const else_is_block = nodeIsBlock(node_tags[while_node.ast.else_expr]); if (else_is_block) { 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. } else { try renderToken(ais, tree, while_node.else_token, .newline); // else } - try renderExpressionIndented(gpa, ais, tree, while_node.ast.else_expr, space); - return; + if (indent_expression) { + return renderExpressionIndented(gpa, ais, tree, while_node.ast.else_expr, space); + } else { + return renderExpression(gpa, ais, tree, while_node.ast.else_expr, space); + } } } else { - try renderExpressionIndented(gpa, ais, tree, while_node.ast.then_expr, space); - return; + if (indent_expression) { + return renderExpressionIndented(gpa, ais, tree, while_node.ast.then_expr, space); + } else { + return renderExpression(gpa, ais, tree, while_node.ast.then_expr, space); + } } } @@ -1158,27 +1129,7 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. if (while_node.payload_token) |payload_token| { assert(payload_token - 2 == rparen); - try renderToken(ais, tree, payload_token - 2, .space); // ) - try renderToken(ais, tree, payload_token - 1, .none); // | - const ident = blk: { - if (token_tags[payload_token] == .asterisk) { - try renderToken(ais, tree, payload_token, .none); // * - break :blk payload_token + 1; - } else { - break :blk payload_token; - } - }; - try renderToken(ais, tree, ident, .none); // identifier - const pipe = blk: { - if (token_tags[ident + 1] == .comma) { - try renderToken(ais, tree, ident + 1, .space); // , - try renderToken(ais, tree, ident + 2, .none); // index - break :blk ident + 3; - } else { - break :blk ident + 1; - } - }; - try renderToken(ais, tree, pipe, .space); // | + try renderWhilePayload(gpa, ais, tree, payload_token, .space); } else { try renderToken(ais, tree, rparen, .space); // ) } @@ -1208,6 +1159,31 @@ fn renderWhile(gpa: *Allocator, ais: *Ais, tree: ast.Tree, while_node: ast.full. } } +fn renderWhilePayload(gpa: *Allocator, ais: *Ais, tree: ast.Tree, payload_token: ast.TokenIndex, space: Space) Error!void { + const token_tags = tree.tokens.items(.tag); + try renderToken(ais, tree, payload_token - 2, .space); // rparen + try renderToken(ais, tree, payload_token - 1, .none); // | + const ident = blk: { + if (token_tags[payload_token] == .asterisk) { + try renderToken(ais, tree, payload_token, .none); // * + break :blk payload_token + 1; + } else { + break :blk payload_token; + } + }; + try renderToken(ais, tree, ident, .none); // identifier + const pipe = blk: { + if (token_tags[ident + 1] == .comma) { + try renderToken(ais, tree, ident + 1, .space); // , + try renderToken(ais, tree, ident + 2, .none); // index + break :blk ident + 3; + } else { + break :blk ident + 1; + } + }; + try renderToken(ais, tree, pipe, space); // | +} + fn renderContainerField( gpa: *Allocator, ais: *Ais, -- 2.54.0