@@ -20,7 +20,8 @@ import 'piece_factory.dart';
20
20
class DelimitedListBuilder {
21
21
final PieceFactory _visitor;
22
22
23
- late final Piece _leftBracket;
23
+ /// The opening bracket before the elements, if any.
24
+ Piece ? _leftBracket;
24
25
25
26
/// The list of elements in the list.
26
27
final List <ListElement > _elements = [];
@@ -29,83 +30,21 @@ class DelimitedListBuilder {
29
30
/// next piece.
30
31
final Set <ListElement > _blanksAfter = {};
31
32
32
- late final Piece _rightBracket;
33
+ /// The closing bracket after the elements, if any.
34
+ Piece ? _rightBracket;
33
35
34
- /// Whether this list should have a trailing comma if it splits.
35
- ///
36
- /// This is true for most lists but false for type parameters, type arguments,
37
- /// and switch values.
38
- final bool _trailingComma;
39
-
40
- /// The cost of splitting this list. Normally 1, but higher for some lists
41
- /// that look worse when split.
42
- final int _splitCost;
43
-
44
- /// Whether this list should have spaces inside the bracket when it doesn't
45
- /// split.
46
- ///
47
- /// This is false for most lists, but true for switch expression bodies:
48
- ///
49
- /// ```
50
- /// v = switch (e) { 1 => 'one', 2 => 'two' };
51
- /// // ^ ^
52
- /// ```
53
- final bool _spaceWhenUnsplit;
54
-
55
- /// Whether a split in the [_before] piece should force the list to split too.
56
- ///
57
- /// See [ListPiece._splitListIfBeforeSplits] for more details.
58
- final bool _splitListIfBeforeSplits;
36
+ final ListStyle _style;
59
37
60
38
/// The list of comments following the most recently written element before
61
39
/// any comma following the element.
62
40
CommentSequence _commentsBeforeComma = CommentSequence .empty;
63
41
64
42
/// Creates a new [DelimitedListBuilder] for an argument list, collection
65
43
/// literal, etc.
66
- DelimitedListBuilder (this ._visitor)
67
- : _trailingComma = true ,
68
- _splitCost = 1 ,
69
- _spaceWhenUnsplit = false ,
70
- _splitListIfBeforeSplits = false ;
71
-
72
- /// Creates a new [DelimitedListBuilder] for a switch expression body.
73
- DelimitedListBuilder .switchBody (this ._visitor)
74
- : _trailingComma = true ,
75
- _splitCost = 1 ,
76
- _spaceWhenUnsplit = true ,
77
- _splitListIfBeforeSplits = true ;
78
-
79
- /// Creates a new [DelimitedListBuilder] for the value part of a switch
80
- /// statement or expression:
81
- ///
82
- /// ```
83
- /// switch (value) { ... }
84
- /// // ^^^^^^^
85
- /// ```
86
- DelimitedListBuilder .switchValue (this ._visitor)
87
- : _trailingComma = false ,
88
- _splitCost = 2 ,
89
- _spaceWhenUnsplit = false ,
90
- _splitListIfBeforeSplits = false ;
91
-
92
- /// Creates a new [DelimitedListBuilder] for a type argument or type parameter
93
- /// list.
94
- DelimitedListBuilder .type (this ._visitor)
95
- : _trailingComma = false ,
96
- _splitCost = 2 ,
97
- _spaceWhenUnsplit = false ,
98
- _splitListIfBeforeSplits = false ;
99
-
100
- ListPiece build () => ListPiece (
101
- _leftBracket,
102
- _elements,
103
- _blanksAfter,
104
- _rightBracket,
105
- _splitCost,
106
- _trailingComma,
107
- _spaceWhenUnsplit,
108
- _splitListIfBeforeSplits);
44
+ DelimitedListBuilder (this ._visitor, [this ._style = const ListStyle ()]);
45
+
46
+ ListPiece build () =>
47
+ ListPiece (_leftBracket, _elements, _blanksAfter, _rightBracket, _style);
109
48
110
49
/// Adds the opening [bracket] to the built list.
111
50
///
@@ -163,24 +102,37 @@ class DelimitedListBuilder {
163
102
_rightBracket = _visitor.writer.pop ();
164
103
}
165
104
166
- /// Adds [element ] to the built list.
105
+ /// Adds [piece ] to the built list.
167
106
///
168
- /// Includes any comments that appear before element. Also includes the
169
- /// subsequent comma, if any, and any comments that precede the comma.
170
- void add (AstNode element) {
107
+ /// Use this when the piece is composed of more than one [AstNode] or [Token]
108
+ /// and [visit()] can't be used. When calling this, make sure to call
109
+ /// [addCommentsBefore()] for the first token in the [piece] .
110
+ ///
111
+ /// Assumes there is no comma after this piece.
112
+ void add (Piece piece) {
113
+ _elements.add (ListElement (piece));
114
+ _commentsBeforeComma = CommentSequence .empty;
115
+ }
116
+
117
+ /// Writes any comments appearing before [token] to the list.
118
+ void addCommentsBefore (Token token) {
171
119
// Handle comments between the preceding element and this one.
172
- var commentsBeforeElement = _visitor.takeCommentsBefore (element.beginToken );
120
+ var commentsBeforeElement = _visitor.takeCommentsBefore (token );
173
121
_addComments (commentsBeforeElement, hasElementAfter: true );
122
+ }
123
+
124
+ /// Adds [element] to the built list.
125
+ void visit (AstNode element) {
126
+ // Handle comments between the preceding element and this one.
127
+ addCommentsBefore (element.beginToken);
174
128
175
129
// Traverse the element itself.
176
130
_visitor.visit (element);
177
- _elements.add (ListElement (_visitor.writer.pop ()));
178
131
_visitor.writer.split ();
132
+ add (_visitor.writer.pop ());
179
133
180
134
var nextToken = element.endToken.next! ;
181
- if (nextToken.lexeme != ',' ) {
182
- _commentsBeforeComma = CommentSequence .empty;
183
- } else {
135
+ if (nextToken.lexeme == ',' ) {
184
136
_commentsBeforeComma = _visitor.takeCommentsBefore (nextToken);
185
137
}
186
138
}
@@ -256,7 +208,7 @@ class DelimitedListBuilder {
256
208
}
257
209
258
210
// Comments that are neither hanging nor leading are treated like their own
259
- // arguments .
211
+ // elements .
260
212
for (var i = 0 ; i < separateComments.length; i++ ) {
261
213
var comment = separateComments[i];
262
214
if (separateComments.linesBefore (i) > 1 && _elements.isNotEmpty) {
@@ -268,7 +220,7 @@ class DelimitedListBuilder {
268
220
_visitor.writer.split ();
269
221
}
270
222
271
- // Leading comments are written before the next argument .
223
+ // Leading comments are written before the next element .
272
224
for (var comment in leadingComments) {
273
225
_visitor.writer.writeComment (comment);
274
226
_visitor.writer.space ();
@@ -311,15 +263,15 @@ class DelimitedListBuilder {
311
263
CommentSequence leading
312
264
}) _splitCommaComments (CommentSequence commentsBeforeElement,
313
265
{required bool hasElementAfter}) {
314
- // If we're on the final comma after the last argument , the comma isn't
266
+ // If we're on the final comma after the last element , the comma isn't
315
267
// meaningful because there can't be leading comments after it.
316
268
if (! hasElementAfter) {
317
269
_commentsBeforeComma =
318
270
_commentsBeforeComma.concatenate (commentsBeforeElement);
319
271
commentsBeforeElement = CommentSequence .empty;
320
272
}
321
273
322
- // Edge case: A line comment on the same line as the preceding argument
274
+ // Edge case: A line comment on the same line as the preceding element
323
275
// but after the comma is treated as hanging.
324
276
if (commentsBeforeElement.isNotEmpty &&
325
277
commentsBeforeElement[0 ].type == CommentType .line &&
0 commit comments