Skip to content

Commit a8ab052

Browse files
authored
Improve how expressions in control flow headers are handled. (#1326)
Improve how parenthesized expressions in control flow are handled. In the process of writing tests for if statements, I realized that the way if conditions are formatted was different than switch values. And it turns out that, based on looking at how all of the control flow in Flutter is hand-formatted, the way I was handling switches was more complex than needed. It seems like the right behavior we want is to just visit the expression directly and let the parentheses attach directly to it. So I updated if, while, and switch to all do that. Also added tests for comments in if statements.
1 parent 967d15e commit a8ab052

File tree

7 files changed

+141
-32
lines changed

7 files changed

+141
-32
lines changed

lib/src/front_end/ast_node_visitor.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<void>
12801280
var list = DelimitedListBuilder(this,
12811281
const ListStyle(spaceWhenUnsplit: true, splitListIfBeforeSplits: true));
12821282

1283-
createSwitchValue(node.switchKeyword, node.leftParenthesis, node.expression,
1283+
startControlFlow(node.switchKeyword, node.leftParenthesis, node.expression,
12841284
node.rightParenthesis);
12851285
space();
12861286
list.leftBracket(node.leftBracket);
@@ -1304,7 +1304,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<void>
13041304

13051305
@override
13061306
void visitSwitchStatement(SwitchStatement node) {
1307-
createSwitchValue(node.switchKeyword, node.leftParenthesis, node.expression,
1307+
startControlFlow(node.switchKeyword, node.leftParenthesis, node.expression,
13081308
node.rightParenthesis);
13091309

13101310
// Attach the ` {` after the `)` in the [ListPiece] created by

lib/src/front_end/piece_factory.dart

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ mixin PieceFactory implements CommentWriter {
148148
);
149149
}
150150

151+
/// Visits the leading keyword and parenthesized expression at the beginning
152+
/// of an `if`, `while`, or `switch` expression or statement.
153+
void startControlFlow(Token keyword, Token leftParenthesis, Expression value,
154+
Token rightParenthesis) {
155+
// Attach the keyword to the `(`.
156+
token(keyword);
157+
space();
158+
token(leftParenthesis);
159+
visit(value);
160+
token(rightParenthesis);
161+
}
162+
151163
/// Creates metadata annotations for a directive.
152164
///
153165
/// Always forces the annotations to be on a previous line.
@@ -231,11 +243,8 @@ mixin PieceFactory implements CommentWriter {
231243
// Recurses through the else branches to flatten them into a linear if-else
232244
// chain handled by a single [IfPiece].
233245
void traverse(IfStatement node) {
234-
token(node.ifKeyword);
235-
space();
236-
token(node.leftParenthesis);
237-
visit(node.expression);
238-
token(node.rightParenthesis);
246+
startControlFlow(node.ifKeyword, node.leftParenthesis, node.expression,
247+
node.rightParenthesis);
239248
var condition = pieces.split();
240249

241250
// Edge case: When the then branch is a block and there is an else clause
@@ -432,21 +441,6 @@ mixin PieceFactory implements CommentWriter {
432441
pieces.give(builder.build());
433442
}
434443

435-
/// Visits the `switch (expr)` part of a switch statement or expression.
436-
void createSwitchValue(Token switchKeyword, Token leftParenthesis,
437-
Expression value, Token rightParenthesis) {
438-
// Attach the `switch ` as part of the `(`.
439-
token(switchKeyword);
440-
space();
441-
442-
createList(
443-
leftBracket: leftParenthesis,
444-
[value],
445-
rightBracket: rightParenthesis,
446-
style: const ListStyle(
447-
commas: Commas.none, splitCost: 2, allowBlockElement: true));
448-
}
449-
450444
/// Creates a class, enum, extension, mixin, or mixin application class
451445
/// declaration.
452446
///

test/expression/switch.stmt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,12 @@ e = switch (obj) {
5252
1 => b,
5353
2 => c,
5454
};
55-
>>> Split before switch value.
55+
>>> Don't split at parentheses.
5656
e = switch ("a long string that must wrap") {
5757
0 => "ok"
5858
};
5959
<<<
60-
e = switch (
61-
"a long string that must wrap"
62-
) {
60+
e = switch ("a long string that must wrap") {
6361
0 => "ok",
6462
};
6563
>>> Split in delimited value expression.

test/statement/if.stmt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,38 @@
11
40 columns |
2-
>>> Split in condition.
2+
>>> Don't split before or after condition.
3+
if (veryLongConditionExpressionWithNoSplit) { body;}
4+
<<<
5+
if (veryLongConditionExpressionWithNoSplit) {
6+
body;
7+
}
8+
>>> Split inside condition expression.
39
if (veryLongCondition || anotherLongCondition) { body; }
410
<<<
511
if (veryLongCondition ||
612
anotherLongCondition) {
713
body;
814
}
15+
>>> Condition expressions can use block formatting.
16+
if ([element, element, element, element]) { body; }
17+
<<<
18+
if ([
19+
element,
20+
element,
21+
element,
22+
element,
23+
]) {
24+
body;
25+
}
26+
>>>
27+
if (someFunction(argument, argument, argument)) { body; }
28+
<<<
29+
if (someFunction(
30+
argument,
31+
argument,
32+
argument,
33+
)) {
34+
body;
35+
}
936
>>> Indentation.
1037
if ( true ) { return 42; } else { return 13; }
1138
<<<

test/statement/if_comment.stmt

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
40 columns |
2+
>>> Line comment after `if`.
3+
if // comment
4+
(c) { body; }
5+
<<<
6+
if // comment
7+
(c) {
8+
body;
9+
}
10+
>>> Line comment before condition.
11+
if (// comment
12+
c) { body; }
13+
<<<
14+
if ( // comment
15+
c) {
16+
body;
17+
}
18+
>>> Line comment after condition.
19+
if (c // comment
20+
){ body; }
21+
<<<
22+
if (c // comment
23+
) {
24+
body;
25+
}
26+
>>> Line comment after `)`.
27+
if (c) // comment
28+
{ body; }
29+
<<<
30+
if (c) // comment
31+
{
32+
body;
33+
}
34+
>>> Line comment after body.
35+
if (c)
36+
{ body; } // comment
37+
<<<
38+
if (c) {
39+
body;
40+
} // comment
41+
>>> Line comment before `else`.
42+
if (c) { body; } // comment
43+
else { other; }
44+
<<<
45+
if (c) {
46+
body;
47+
} // comment
48+
else {
49+
other;
50+
}
51+
>>> Line comment after `else`.
52+
if (c) { body; } else// comment
53+
{ other; }
54+
<<<
55+
if (c) {
56+
body;
57+
} else // comment
58+
{
59+
other;
60+
}
61+
>>> Line comment after `else` body.
62+
if (c) { body; } else { other; }// comment
63+
<<<
64+
if (c) {
65+
body;
66+
} else {
67+
other;
68+
} // comment
69+
>>> Line comments in logic condition.
70+
if (// Do stuff.
71+
condition1 ||
72+
// More stuff.
73+
condition2) { body; }
74+
<<<
75+
if ( // Do stuff.
76+
condition1 ||
77+
// More stuff.
78+
condition2) {
79+
body;
80+
}

test/statement/switch.stmt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,13 @@ switch (fruit) {
251251
default:
252252
break;
253253
}
254-
>>> Split before the switch expression.
254+
>>> Don't split at parentheses.
255255
switch ("a long string that must wrap") {
256256
case 0:
257257
return "ok";
258258
}
259259
<<<
260-
switch (
261-
"a long string that must wrap"
262-
) {
260+
switch ("a long string that must wrap") {
263261
case 0:
264262
return "ok";
265263
}

test/statement/while.stmt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ while (true) {}
77
while (true);
88
<<<
99
while (true) ;
10-
>>> Don't split before long condition.
10+
>>> Don't split at parentheses.
1111
while (aLongConditionExpressionThatWraps) {
1212
;
1313
}
@@ -24,6 +24,18 @@ while (aLongCondition +
2424
expressionThatWraps) {
2525
;
2626
}
27+
>>> Block format condition expressions that allow it.
28+
while (function(argument, argument, argument)) {
29+
;
30+
}
31+
<<<
32+
while (function(
33+
argument,
34+
argument,
35+
argument,
36+
)) {
37+
;
38+
}
2739
>>> Unbraced body.
2840
while (condition) something(i);
2941
<<<

0 commit comments

Comments
 (0)