Skip to content

Commit 80288ef

Browse files
authored
Don't split cascades on record literals. (#1207)
This is consistent with how other collection literals preceding single-section cascades are formatted.
1 parent 33efb25 commit 80288ef

File tree

4 files changed

+30
-44
lines changed

4 files changed

+30
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Don't indent `||` pattern operands in switch expression cases.
77
* Don't format `sealed`, `interface`, and `final` keywords on mixin
88
declarations. The proposal was updated to no longer support them.
9+
* Don't split before a single-section cascade following a record literal.
910

1011
# 2.3.0
1112

lib/src/ast_extensions.dart

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -88,40 +88,6 @@ extension AstIterableExtensions on Iterable<AstNode> {
8888
}
8989

9090
extension ExpressionExtensions on Expression {
91-
/// Whether [expression] is a collection literal, or a call with a trailing
92-
/// comma in an argument list.
93-
///
94-
/// In that case, when the expression is a target of a cascade, we don't
95-
/// force a split before the ".." as eagerly to avoid ugly results like:
96-
///
97-
/// [
98-
/// 1,
99-
/// 2,
100-
/// ]..addAll(numbers);
101-
bool get isCollectionLike {
102-
var expression = this;
103-
if (expression is ListLiteral) return true;
104-
if (expression is SetOrMapLiteral) return true;
105-
106-
// If the target is a call with a trailing comma in the argument list,
107-
// treat it like a collection literal.
108-
ArgumentList? arguments;
109-
if (expression is InvocationExpression) {
110-
arguments = expression.argumentList;
111-
} else if (expression is InstanceCreationExpression) {
112-
arguments = expression.argumentList;
113-
}
114-
115-
// TODO(rnystrom): Do we want to allow an invocation where the last
116-
// argument is a collection literal? Like:
117-
//
118-
// foo(argument, [
119-
// element
120-
// ])..cascade();
121-
122-
return arguments != null && arguments.arguments.hasCommaAfter;
123-
}
124-
12591
/// Whether this is an argument in an argument list with a trailing comma.
12692
bool get isTrailingCommaArgument {
12793
var parent = this.parent;

lib/src/source_visitor.dart

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,25 @@ class SourceVisitor extends ThrowingAstVisitor {
424424
// stuff
425425
// ]
426426
// ..add(more);
427-
var splitIfOperandsSplit =
428-
node.cascadeSections.length > 1 || !node.target.isCollectionLike;
429-
if (splitIfOperandsSplit) {
427+
var target = node.target;
428+
var splitIfTargetSplits = true;
429+
if (node.cascadeSections.length > 1) {
430+
// Always split if there are multiple cascade sections.
431+
} else if (target is ListLiteral ||
432+
target is RecordLiteral ||
433+
target is SetOrMapLiteral) {
434+
splitIfTargetSplits = false;
435+
} else if (target is InvocationExpression) {
436+
// If the target is a call with a trailing comma in the argument list,
437+
// treat it like a collection literal.
438+
splitIfTargetSplits = !target.argumentList.arguments.hasCommaAfter;
439+
} else if (target is InstanceCreationExpression) {
440+
// If the target is a call with a trailing comma in the argument list,
441+
// treat it like a collection literal.
442+
splitIfTargetSplits = !target.argumentList.arguments.hasCommaAfter;
443+
}
444+
445+
if (splitIfTargetSplits) {
430446
builder.startLazyRule(node.allowInline ? Rule() : Rule.hard());
431447
}
432448

@@ -437,21 +453,17 @@ class SourceVisitor extends ThrowingAstVisitor {
437453

438454
// If the cascade section shouldn't cause the cascade to split, end the
439455
// rule early so it isn't affected by it.
440-
if (!splitIfOperandsSplit) {
456+
if (!splitIfTargetSplits) {
441457
builder.startRule(node.allowInline ? Rule() : Rule.hard());
442458
}
443459

444460
zeroSplit();
445461

446-
if (!splitIfOperandsSplit) {
447-
builder.endRule();
448-
}
462+
if (!splitIfTargetSplits) builder.endRule();
449463

450464
visitNodes(node.cascadeSections, between: zeroSplit);
451465

452-
if (splitIfOperandsSplit) {
453-
builder.endRule();
454-
}
466+
if (splitIfTargetSplits) builder.endRule();
455467

456468
builder.endBlockArgumentNesting();
457469
builder.unnest();

test/whitespace/cascades.stmt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ var map = {1:2,}..addAll(more);
108108
var map = {
109109
1: 2,
110110
}..addAll(more);
111+
>>> omit split if single section on record literal
112+
(1,2,)..addAll(more);
113+
<<<
114+
(
115+
1,
116+
2,
117+
)..addAll(more);
111118
>>> omit split if single section on trailing comma call
112119
foo(1,)..addAll(more);
113120
<<<

0 commit comments

Comments
 (0)