Skip to content

Commit 4dc2e97

Browse files
committed
Handle trailing commas in for-loop updaters.
Fix #1354.
1 parent 1208f9e commit 4dc2e97

File tree

7 files changed

+79
-12
lines changed

7 files changed

+79
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## 3.0.1-wip
22

33
* Ensure comment formatting is idempotent (#1606).
4+
* Handle trailing commas in for-loop updaters (#1354).
45

56
## 3.0.0
67

lib/src/front_end/delimited_list_builder.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,18 @@ final class DelimitedListBuilder {
138138
_commentsBeforeComma = CommentSequence.empty;
139139
}
140140

141-
/// Adds the contents of [lineBuilder] to this outer [DelimitedListBuilder].
141+
/// Adds the contents of [inner] to this outer [DelimitedListBuilder].
142142
///
143-
/// This is used when preserving newlines inside a collection literal. The
144-
/// [lineBuilder] will be used for the elements that should be packed onto a
145-
/// single line, and this builder is for the rows that are each on their own
146-
/// line.
147-
void addLineBuilder(DelimitedListBuilder lineBuilder) {
143+
/// This is used when a [DelimiterListBuilder] is building a piece that will
144+
/// then become an element in a surrounding [DelimitedListBuilder]. It ensures
145+
/// that any comments around a trailing comma after [inner] don't get lost and
146+
/// are instead hoisted up to be captured by this builder.
147+
void addInnerBuilder(DelimitedListBuilder inner) {
148148
// Add the elements of the line to this builder.
149-
add(lineBuilder.build());
149+
add(inner.build());
150150

151151
// Make sure that any trailing comments on the line aren't lost.
152-
_commentsBeforeComma = lineBuilder._commentsBeforeComma;
152+
_commentsBeforeComma = inner._commentsBeforeComma;
153153
}
154154

155155
/// Writes any comments appearing before [token] to the list.

lib/src/front_end/piece_factory.dart

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,16 @@ mixin PieceFactory {
430430
// The update clauses.
431431
if (forParts.updaters.isNotEmpty) {
432432
partsList.addCommentsBefore(forParts.updaters.first.beginToken);
433-
partsList.add(createCommaSeparated(forParts.updaters));
433+
434+
// Create a nested list builder for the updaters so that they can
435+
// remain unsplit even while the clauses split.
436+
var updaterBuilder = DelimitedListBuilder(
437+
this, const ListStyle(commas: Commas.nonTrailing));
438+
forParts.updaters.forEach(updaterBuilder.visit);
439+
440+
// Add the updater builder to the clause builder so that any comments
441+
// around a trailing comma after the updaters don't get dropped.
442+
partsList.addInnerBuilder(updaterBuilder);
434443
}
435444

436445
partsList.rightBracket(rightParenthesis);
@@ -1083,7 +1092,7 @@ mixin PieceFactory {
10831092
elements[i - 1].endToken, element.beginToken)) {
10841093
// This element begins a new line. Add the elements on the previous
10851094
// line to the list builder and start a new line.
1086-
builder.addLineBuilder(lineBuilder);
1095+
builder.addInnerBuilder(lineBuilder);
10871096
lineBuilder = DelimitedListBuilder(this, lineStyle);
10881097
atLineStart = true;
10891098
}
@@ -1099,7 +1108,7 @@ mixin PieceFactory {
10991108
}
11001109

11011110
// Finish the last line if there is anything on it.
1102-
if (!atLineStart) builder.addLineBuilder(lineBuilder);
1111+
if (!atLineStart) builder.addInnerBuilder(lineBuilder);
11031112
}
11041113

11051114
/// Writes a [VariablePiece] for a named or wildcard variable pattern.

test/tall/expression/collection_for.stmt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,18 @@ var list = [
170170
inc
171171
)
172172
element,
173+
];
174+
>>> Trailing comma in increments.
175+
var list = [
176+
for (
177+
x = 1;
178+
true;
179+
x += 1, x += 2,
180+
)
181+
element,
182+
];
183+
<<<
184+
var list = [
185+
for (x = 1; true; x += 1, x += 2)
186+
element,
173187
];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
>>>
2+
void main() {
3+
for (int i; i < 10; print("foo"), ++i, print("bar"),) {
4+
break;
5+
}
6+
}
7+
<<<
8+
void main() {
9+
for (int i; i < 10; print("foo"), ++i, print("bar")) {
10+
break;
11+
}
12+
}

test/tall/statement/for_comment.stmt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,22 @@ for (
223223
) {
224224
body;
225225
}
226+
>>> Preserve comments around discarded increment trailing comma.
227+
for (
228+
init;
229+
cond;
230+
incr /* c1 */ , /* c2 */
231+
) {
232+
body;
233+
}
234+
<<<
235+
for (
236+
init;
237+
cond;
238+
incr /* c1 */ /* c2 */
239+
) {
240+
body;
241+
}
226242
>>> Line comment before first `;` in fully empty clauses.
227243
for ( // comment
228244
; ; ) { body; }

test/tall/statement/for_initializer.stmt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,19 @@ for (
155155
second = 2,
156156
third = 3,
157157
fourth = 4
158-
) {}
158+
) {}
159+
>>> Discard trailing comma in unsplit increments.
160+
for (foo; bar; first = 1, second = 2,) {}
161+
<<<
162+
for (foo; bar; first = 1, second = 2) {}
163+
>>> Discard trailing comma in split increments.
164+
for (foo; bar; first = 1, second = 2, third = 3, fourth = 4,) {}
165+
<<<
166+
for (
167+
foo;
168+
bar;
169+
first = 1,
170+
second = 2,
171+
third = 3,
172+
fourth = 4
173+
) {}

0 commit comments

Comments
 (0)