Skip to content

Commit 33efb25

Browse files
authored
Don't indent outermost "||" pattern operands in switch expression cases. (#1203)
* Don't indent outermost "||" pattern operands in switch expression cases. This makes them all line up as if they were empty cases in a switch statement, which is essentially how they behave. Instead of: ```dart e = switch (obj) { constant1 || constant2 || constant3 => body }; ``` Gives: ```dart e = switch (obj) { constant1 || constant2 || constant3 => body }; ``` This addresses some of the bad formatting in #1197. The rest is #1202. * Add comment.
1 parent b9b484c commit 33efb25

File tree

6 files changed

+330
-15
lines changed

6 files changed

+330
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Hide `--fix` and related options in `--help`. The options are still there and
44
supported, but are no longer shown by default. Eventually, we would like all
55
users to move to using `dart fix` instead of `dart format --fix`.
6+
* Don't indent `||` pattern operands in switch expression cases.
67
* Don't format `sealed`, `interface`, and `final` keywords on mixin
78
declarations. The proposal was updated to no longer support them.
89

lib/src/source_visitor.dart

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2755,25 +2755,72 @@ class SourceVisitor extends ThrowingAstVisitor {
27552755

27562756
@override
27572757
void visitSwitchExpressionCase(SwitchExpressionCase node) {
2758+
// If the pattern is a series of `||` patterns, then flatten them out and
2759+
// format them like empty cases with fallthrough in a switch statement
2760+
// instead of like a single indented binary pattern. Prefer:
2761+
//
2762+
// e = switch (obj) {
2763+
// constant1 ||
2764+
// constant2 ||
2765+
// constant3 =>
2766+
// body
2767+
// };
2768+
//
2769+
// Instead of:
2770+
//
2771+
// e = switch (obj) {
2772+
// constant1 ||
2773+
// constant2 ||
2774+
// constant3 =>
2775+
// body
2776+
// };
2777+
var orBranches = <DartPattern>[];
2778+
var orTokens = <Token>[];
2779+
2780+
void flattenOr(DartPattern e) {
2781+
if (e is! LogicalOrPattern) {
2782+
orBranches.add(e);
2783+
} else {
2784+
flattenOr(e.leftOperand);
2785+
orTokens.add(e.operator);
2786+
flattenOr(e.rightOperand);
2787+
}
2788+
}
2789+
2790+
flattenOr(node.guardedPattern.pattern);
2791+
27582792
// Wrap the rule for splitting after "=>" around the pattern so that a
27592793
// split in the pattern forces the expression to move to the next line too.
27602794
builder.startLazyRule();
27612795

2762-
// Wrap the expression's nesting around the pattern too so that a split in
2796+
// Write the "||" operands up to the last one.
2797+
for (var i = 0; i < orBranches.length - 1; i++) {
2798+
// Note that orBranches will always have one more element than orTokens.
2799+
visit(orBranches[i]);
2800+
space();
2801+
token(orTokens[i]);
2802+
split();
2803+
}
2804+
2805+
// Wrap the expression's nesting around the final pattern so that a split in
27632806
// the pattern is indented farther then the body expression. Used +2 indent
27642807
// because switch expressions are block-like, similar to how we split the
27652808
// bodies of if and for elements in collections.
27662809
builder.nestExpression(indent: Indent.block);
27672810

27682811
var whenClause = node.guardedPattern.whenClause;
2769-
if (whenClause == null) {
2770-
visit(node.guardedPattern.pattern);
2771-
} else {
2812+
if (whenClause != null) {
27722813
// Wrap the when clause rule around the pattern so that if the pattern
27732814
// splits then we split before "when" too.
27742815
builder.startRule();
27752816
builder.nestExpression(indent: Indent.block);
2776-
visit(node.guardedPattern.pattern);
2817+
}
2818+
2819+
// Write the last pattern in the "||" chain. If the case pattern isn't an
2820+
// "||" pattern at all, this writes the one pattern.
2821+
visit(orBranches.last);
2822+
2823+
if (whenClause != null) {
27772824
split();
27782825
builder.startBlockArgumentNesting();
27792826
_visitWhenClause(whenClause);
@@ -2785,10 +2832,12 @@ class SourceVisitor extends ThrowingAstVisitor {
27852832
space();
27862833
token(node.arrow);
27872834
split();
2788-
27892835
builder.endRule();
27902836

2837+
builder.startBlockArgumentNesting();
27912838
visit(node.expression);
2839+
builder.endBlockArgumentNesting();
2840+
27922841
builder.unnest();
27932842
}
27942843

test/regression/1100/1197.unit

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
>>>
2+
main() {
3+
{
4+
return TextFieldTapRegion(
5+
onLongPressMoveUpdate: (longPressMoveUpdateDetails) {
6+
(switch (Theme.of(this.context).platform) {
7+
TargetPlatform.iOS || TargetPlatform.macOS =>
8+
_renderEditable.selectPositionAt(
9+
from: longPressMoveUpdateDetails.globalPosition,
10+
cause: SelectionChangedCause.longPress,
11+
),
12+
TargetPlatform.android ||
13+
TargetPlatform.fuchsia ||
14+
TargetPlatform.linux ||
15+
TargetPlatform.windows =>
16+
_renderEditable.selectWordsInRange(
17+
from: longPressMoveUpdateDetails.globalPosition -
18+
longPressMoveUpdateDetails.offsetFromOrigin,
19+
to: longPressMoveUpdateDetails.globalPosition,
20+
cause: SelectionChangedCause.longPress,
21+
)
22+
});
23+
},
24+
);
25+
}
26+
}
27+
<<<
28+
main() {
29+
{
30+
return TextFieldTapRegion(
31+
onLongPressMoveUpdate: (longPressMoveUpdateDetails) {
32+
(switch (Theme.of(this.context).platform) {
33+
TargetPlatform.iOS ||
34+
TargetPlatform.macOS =>
35+
_renderEditable.selectPositionAt(
36+
from: longPressMoveUpdateDetails.globalPosition,
37+
cause: SelectionChangedCause.longPress,
38+
),
39+
TargetPlatform.android ||
40+
TargetPlatform.fuchsia ||
41+
TargetPlatform.linux ||
42+
TargetPlatform.windows =>
43+
_renderEditable.selectWordsInRange(
44+
from: longPressMoveUpdateDetails.globalPosition -
45+
longPressMoveUpdateDetails.offsetFromOrigin,
46+
to: longPressMoveUpdateDetails.globalPosition,
47+
cause: SelectionChangedCause.longPress,
48+
)
49+
});
50+
},
51+
);
52+
}
53+
}
54+
>>>
55+
main() {
56+
{
57+
return TextFieldTapRegion(
58+
onLongPressMoveUpdate: (longPressMoveUpdateDetails) =>
59+
switch (Theme.of(this.context).platform) {
60+
TargetPlatform.iOS || TargetPlatform.macOS =>
61+
_renderEditable.selectPositionAt(
62+
from: longPressMoveUpdateDetails.globalPosition,
63+
cause: SelectionChangedCause.longPress,
64+
),
65+
TargetPlatform.android ||
66+
TargetPlatform.fuchsia ||
67+
TargetPlatform.linux ||
68+
TargetPlatform.windows =>
69+
_renderEditable.selectWordsInRange(
70+
from: longPressMoveUpdateDetails.globalPosition -
71+
longPressMoveUpdateDetails.offsetFromOrigin,
72+
to: longPressMoveUpdateDetails.globalPosition,
73+
cause: SelectionChangedCause.longPress,
74+
)
75+
},
76+
);
77+
}
78+
}
79+
<<<
80+
main() {
81+
{
82+
return TextFieldTapRegion(
83+
onLongPressMoveUpdate: (longPressMoveUpdateDetails) =>
84+
switch (Theme.of(this.context).platform) {
85+
TargetPlatform.iOS ||
86+
TargetPlatform.macOS =>
87+
_renderEditable.selectPositionAt(
88+
from: longPressMoveUpdateDetails.globalPosition,
89+
cause: SelectionChangedCause.longPress,
90+
),
91+
TargetPlatform.android ||
92+
TargetPlatform.fuchsia ||
93+
TargetPlatform.linux ||
94+
TargetPlatform.windows =>
95+
_renderEditable.selectWordsInRange(
96+
from: longPressMoveUpdateDetails.globalPosition -
97+
longPressMoveUpdateDetails.offsetFromOrigin,
98+
to: longPressMoveUpdateDetails.globalPosition,
99+
cause: SelectionChangedCause.longPress,
100+
)
101+
},
102+
);
103+
}
104+
}

test/splitting/arrows.stmt

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,32 @@ doSomethingWithFn((argument) =>
1313
{
1414
() => one;
1515
() => two;
16-
}
16+
}
17+
>>> indent entire block body
18+
SomeLongFunctionName(
19+
(longParameterName______) =>
20+
<LongTypeArgument>[
21+
longListElement,
22+
],
23+
);
24+
<<<
25+
SomeLongFunctionName(
26+
(longParameterName______) =>
27+
<LongTypeArgument>[
28+
longListElement,
29+
],
30+
);
31+
>>>
32+
SomeLongFunctionName(
33+
(longParameterName______) =>
34+
switch (value) {
35+
constant => body,
36+
},
37+
);
38+
<<<
39+
SomeLongFunctionName(
40+
(longParameterName______) =>
41+
switch (value) {
42+
constant => body,
43+
},
44+
);

test/splitting/switch.stmt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,15 @@ switch (obj) {
265265
element,
266266
]:
267267
body;
268+
}
269+
>>> indent || patterns when outermost in switch statement (as opposed to expr)
270+
switch (obj) {
271+
case oneConstant || twoConstant || threeConstant: body;
272+
}
273+
<<<
274+
switch (obj) {
275+
case oneConstant ||
276+
twoConstant ||
277+
threeConstant:
278+
body;
268279
}

0 commit comments

Comments
 (0)