Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: lib/src/rule/argument.dart

Issue 1252323003: Allow arguments before and after block-formatted functions. (Closed) Base URL: https://github.com/dart-lang/dart_style.git@master
Patch Set: Update pubspec and changelog. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/src/chunk.dart ('k') | lib/src/source_visitor.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart_style.src.rule.argument; 5 library dart_style.src.rule.argument;
6 6
7 import '../chunk.dart'; 7 import '../chunk.dart';
8 import 'rule.dart'; 8 import 'rule.dart';
9 9
10 /// Base class for a rule that handles argument or parameter lists. 10 /// Base class for a rule that handles argument or parameter lists.
11 abstract class ArgumentRule extends Rule { 11 abstract class ArgumentRule extends Rule {
12 /// The rule used to split block arguments in the argument list, if any. 12 /// The rule used to split collections in the argument list, if any.
13 final Rule _blockRule; 13 final Rule _collectionRule;
14 14
15 /// If true, then inner rules that are written will force this rule to split. 15 /// If true, then inner rules that are written will force this rule to split.
16 /// 16 ///
17 /// Temporarily disabled while writing block arguments so that they can be 17 /// Temporarily disabled while writing collectio arguments so that they can be
18 /// multi-line without forcing the whole argument list to split. 18 /// multi-line without forcing the whole argument list to split.
19 bool _trackInnerRules = true; 19 bool _trackInnerRules = true;
20 20
21 /// Don't split when an inner block rule splits. 21 /// Don't split when an inner collection rule splits.
22 bool get splitsOnInnerRules => _trackInnerRules; 22 bool get splitsOnInnerRules => _trackInnerRules;
23 23
24 /// Creates a new rule for a positional argument list. 24 /// Creates a new rule for a positional argument list.
25 /// 25 ///
26 /// If [_blockRule] is given, it is the rule used to split the block 26 /// If [_collectionRule] is given, it is the rule used to split the
27 /// arguments in the list. 27 /// collections in the list.
28 ArgumentRule(this._blockRule); 28 ArgumentRule(this._collectionRule);
29 29
30 /// Called before a block argument is written. 30 /// Called before a collection argument is written.
31 /// 31 ///
32 /// Disables tracking inner rules while a block argument is being written. 32 /// Disables tracking inner rules while a collection argument is written.
33 void beforeBlockArgument() { 33 void beforeCollection() {
34 assert(_trackInnerRules == true); 34 assert(_trackInnerRules == true);
35 _trackInnerRules = false; 35 _trackInnerRules = false;
36 } 36 }
37 37
38 /// Called after a block argument is complete. 38 /// Called after a collection argument is complete.
39 /// 39 ///
40 /// Re-enables tracking inner rules after a block argument is complete. 40 /// Re-enables tracking inner rules.
41 void afterBlockArgument() { 41 void afterCollection() {
42 assert(_trackInnerRules == false); 42 assert(_trackInnerRules == false);
43 _trackInnerRules = true; 43 _trackInnerRules = true;
44 } 44 }
45 } 45 }
46 46
47 /// Base class for a rule for handling positional argument lists. 47 /// Base class for a rule for handling positional argument lists.
48 abstract class PositionalRule extends ArgumentRule { 48 abstract class PositionalRule extends ArgumentRule {
49 /// The chunks prior to each positional argument. 49 /// The chunks prior to each positional argument.
50 final List<Chunk> _arguments = []; 50 final List<Chunk> _arguments = [];
51 51
52 /// If there are named arguments following these positional ones, this will 52 /// If there are named arguments following these positional ones, this will
53 /// be their rule. 53 /// be their rule.
54 Rule _namedArgsRule; 54 Rule _namedArgsRule;
55 55
56 /// Creates a new rule for a positional argument list. 56 /// Creates a new rule for a positional argument list.
57 /// 57 ///
58 /// If [blockRule] is given, it is the rule used to split the block arguments 58 /// If [collectionRule] is given, it is the rule used to split the collection
59 /// in the list. 59 /// arguments in the list.
60 PositionalRule(Rule blockRule) : super(blockRule); 60 PositionalRule(Rule collectionRule) : super(collectionRule);
61 61
62 /// Remembers [chunk] as containing the split that occurs right before an 62 /// Remembers [chunk] as containing the split that occurs right before an
63 /// argument in the list. 63 /// argument in the list.
64 void beforeArgument(Chunk chunk) { 64 void beforeArgument(Chunk chunk) {
65 _arguments.add(chunk); 65 _arguments.add(chunk);
66 } 66 }
67 67
68 /// Remembers that [rule] is the [NamedArgsRule] immediately following this 68 /// Remembers that [rule] is the [NamedArgsRule] immediately following this
69 /// positional argument list. 69 /// positional argument list.
70 void setNamedArgsRule(NamedRule rule) { 70 void setNamedArgsRule(NamedRule rule) {
(...skipping 18 matching lines...) Expand all
89 // Otherwise, if there is any split in the positional arguments, don't 89 // Otherwise, if there is any split in the positional arguments, don't
90 // allow the named arguments on the same line as them. 90 // allow the named arguments on the same line as them.
91 if (value != 0) return -1; 91 if (value != 0) return -1;
92 } 92 }
93 93
94 return null; 94 return null;
95 } 95 }
96 } 96 }
97 97
98 /// Split rule for a call with a single positional argument (which may or may 98 /// Split rule for a call with a single positional argument (which may or may
99 /// not be a block argument.) 99 /// not be a collection argument.)
100 class SinglePositionalRule extends PositionalRule { 100 class SinglePositionalRule extends PositionalRule {
101 int get numValues => 2; 101 int get numValues => 2;
102 102
103 /// If there is only a single argument, allow it to split internally without 103 /// If there is only a single non-collection argument, allow it to split
104 /// forcing a split before the argument. 104 /// internally without forcing a split before the argument.
105 bool get splitsOnInnerRules => false; 105 final bool splitsOnInnerRules;
106
107 bool hack = false;
106 108
107 /// Creates a new rule for a positional argument list. 109 /// Creates a new rule for a positional argument list.
108 /// 110 ///
109 /// If [blockRule] is given, it is the rule used to split the block arguments 111 /// If [collectionRule] is given, it is the rule used to split the
110 /// in the list. If [isSingleArgument] is `true`, then the argument list will 112 /// collections in the list. If [splitsOnInnerRules] is `true`, then we will
111 /// only contain a single argument. 113 /// split before the argument if the argument itself contains a split.
112 SinglePositionalRule(Rule blockRule) : super(blockRule); 114 SinglePositionalRule(Rule collectionRule, {bool splitsOnInnerRules})
115 : super(collectionRule),
116 splitsOnInnerRules = splitsOnInnerRules
117 != null
118 ? splitsOnInnerRules : false;
113 119
114 bool isSplit(int value, Chunk chunk) => value == 1; 120 bool isSplit(int value, Chunk chunk) => value == 1;
115 121
116 int constrain(int value, Rule other) { 122 int constrain(int value, Rule other) {
117 var constrained = super.constrain(value, other); 123 var constrained = super.constrain(value, other);
118 if (constrained != null) return constrained; 124 if (constrained != null) return constrained;
119 125
120 if (other != _blockRule) return null; 126 if (other != _collectionRule) return null;
121 127
122 // If we aren't splitting any args, we can split the block. 128 // If we aren't splitting any args, we can split the collection.
123 if (value == 0) return null; 129 if (value == 0) return null;
124 130
125 // We are splitting before a block, so don't let it split internally. 131 // We are splitting before a collection, so don't let it split internally.
126 return 0; 132 return 0;
127 } 133 }
128 134
129 String toString() => "1Pos${super.toString()}"; 135 String toString() => "1Pos${super.toString()}";
130 } 136 }
131 137
132 /// Split rule for a call with more than one positional argument. 138 /// Split rule for a call with more than one positional argument.
133 /// 139 ///
134 /// The number of values is based on the number of arguments and whether or not 140 /// The number of values is based on the number of arguments and whether or not
135 /// there are bodies. The first two values are always: 141 /// there are bodies. The first two values are always:
136 /// 142 ///
137 /// * 0: Do not split at all. 143 /// * 0: Do not split at all.
138 /// * 1: Split only before the first argument. 144 /// * 1: Split only before the first argument.
139 /// 145 ///
140 /// Then there is a value for each argument, to split before that argument. 146 /// Then there is a value for each argument, to split before that argument.
141 /// These values work back to front. So, for a two-argument list, value 2 splits 147 /// These values work back to front. So, for a two-argument list, value 2 splits
142 /// after the second argument and value 3 splits after the first. 148 /// after the second argument and value 3 splits after the first.
143 /// 149 ///
144 /// Then there is a value that splits before every argument. 150 /// Then there is a value that splits before every argument.
145 /// 151 ///
146 /// Finally, if there are block arguments, there is another value that splits 152 /// Finally, if there are collection arguments, there is another value that
147 /// before all of the non-block arguments, but does not split before the block 153 /// splits before all of the non-collection arguments, but does not split
148 /// ones, so that they can split internally. 154 /// before the collections, so that they can split internally.
149 class MultiplePositionalRule extends PositionalRule { 155 class MultiplePositionalRule extends PositionalRule {
150 /// The number of leading block arguments. 156 /// The number of leading collection arguments.
151 /// 157 ///
152 /// This and [_trailingBlocks] cannot both be positive. If every argument is 158 /// This and [_trailingCollections] cannot both be positive. If every
153 /// a block, this will be [_arguments.length] and [_trailingBlocks] will be 0. 159 /// argument is a collection, this will be [_arguments.length] and
154 final int _leadingBlocks; 160 /// [_trailingCollections] will be 0.
161 final int _leadingCollections;
155 162
156 /// The number of trailing block arguments. 163 /// The number of trailing collections.
157 /// 164 ///
158 /// This and [_leadingBlocks] cannot both be positive. 165 /// This and [_leadingCollections] cannot both be positive.
159 final int _trailingBlocks; 166 final int _trailingCollections;
160 167
161 int get numValues { 168 int get numValues {
162 // Can split before any one argument, none, or all. 169 // Can split before any one argument, none, or all.
163 var result = 2 + _arguments.length; 170 var result = 2 + _arguments.length;
164 171
165 // When there are block arguments, there are two ways we can split on "all" 172 // When there are collection arguments, there are two ways we can split on
166 // arguments: 173 // "all" arguments:
167 // 174 //
168 // - Split on just the non-block arguments, and force the block arguments 175 // - Split on just the non-collection arguments, and force the collection
169 // to split internally. 176 // arguments to split internally.
170 // - Split on all of them including the block arguments, and do not allow 177 // - Split on all of them including the collection arguments, and do not
171 // the block arguments to split internally. 178 // allow the collection arguments to split internally.
172 if (_leadingBlocks > 0 || _trailingBlocks > 0) result++; 179 if (_leadingCollections > 0 || _trailingCollections > 0) result++;
173 180
174 return result; 181 return result;
175 } 182 }
176 183
177 MultiplePositionalRule( 184 MultiplePositionalRule(
178 Rule blockRule, this._leadingBlocks, this._trailingBlocks) 185 Rule collectionRule, this._leadingCollections, this._trailingCollections)
179 : super(blockRule); 186 : super(collectionRule);
180 187
181 String toString() => "*Pos${super.toString()}"; 188 String toString() => "*Pos${super.toString()}";
182 189
183 bool isSplit(int value, Chunk chunk) { 190 bool isSplit(int value, Chunk chunk) {
184 // Don't split at all. 191 // Don't split at all.
185 if (value == 0) return false; 192 if (value == 0) return false;
186 193
187 // Split only before the first argument. Keep the entire argument list 194 // Split only before the first argument. Keep the entire argument list
188 // together on the next line. 195 // together on the next line.
189 if (value == 1) return chunk == _arguments.first; 196 if (value == 1) return chunk == _arguments.first;
190 197
191 // Split before a single argument. Try later arguments before earlier ones 198 // Split before a single argument. Try later arguments before earlier ones
192 // to try to keep as much on the first line as possible. 199 // to try to keep as much on the first line as possible.
193 if (value <= _arguments.length) { 200 if (value <= _arguments.length) {
194 var argument = _arguments.length - value + 1; 201 var argument = _arguments.length - value + 1;
195 return chunk == _arguments[argument]; 202 return chunk == _arguments[argument];
196 } 203 }
197 204
198 // Only split before the non-block arguments. Note that we consider this 205 // Only split before the non-collection arguments.
199 // case to correctly prefer this over the latter case because function
200 // block arguments always split internally. Preferring this case ensures we
201 // avoid:
202 //
203 // function( // <-- :(
204 // () {
205 // ...
206 // }),
207 // argument,
208 // ...
209 // argument;
210 if (value == _arguments.length + 1) { 206 if (value == _arguments.length + 1) {
211 for (var i = 0; i < _leadingBlocks; i++) { 207 for (var i = 0; i < _leadingCollections; i++) {
212 if (chunk == _arguments[i]) return false; 208 if (chunk == _arguments[i]) return false;
213 } 209 }
214 210
215 for (var i = _arguments.length - _trailingBlocks; 211 for (var i = _arguments.length - _trailingCollections;
216 i < _arguments.length; 212 i < _arguments.length;
217 i++) { 213 i++) {
218 if (chunk == _arguments[i]) return false; 214 if (chunk == _arguments[i]) return false;
219 } 215 }
220 216
221 return true; 217 return true;
222 } 218 }
223 219
224 // Split before all of the arguments, even the block ones. 220 // Split before all of the arguments, even the collections.
225 return true; 221 return true;
226 } 222 }
227 223
228 int constrain(int value, Rule other) { 224 int constrain(int value, Rule other) {
229 var constrained = super.constrain(value, other); 225 var constrained = super.constrain(value, other);
230 if (constrained != null) return constrained; 226 if (constrained != null) return constrained;
231 227
232 if (other != _blockRule) return null; 228 if (other != _collectionRule) return null;
233 229
234 // If we aren't splitting any args, we can split the block. 230 // If we aren't splitting any args, we can split the collection.
235 if (value == 0) return null; 231 if (value == 0) return null;
236 232
237 // Split only before the first argument. 233 // Split only before the first argument.
238 if (value == 1) { 234 if (value == 1) {
239 if (_leadingBlocks > 0) { 235 if (_leadingCollections > 0) {
240 // We are splitting before a block, so don't let it split internally. 236 // We are splitting before a collection, so don't let it split
237 // internally.
241 return 0; 238 return 0;
242 } else { 239 } else {
243 // The split is outside of the blocks so they can split or not. 240 // The split is outside of the collections so they can split or not.
244 return null; 241 return null;
245 } 242 }
246 } 243 }
247 244
248 // Split before a single argument. If it's in the middle of the block 245 // Split before a single argument. If it's in the middle of the collection
249 // arguments, don't allow them to split. 246 // arguments, don't allow them to split.
250 if (value <= _arguments.length) { 247 if (value <= _arguments.length) {
251 var argument = _arguments.length - value + 1; 248 var argument = _arguments.length - value + 1;
252 if (argument < _leadingBlocks) return 0; 249 if (argument < _leadingCollections) return 0;
253 if (argument >= _arguments.length - _trailingBlocks) return 0; 250 if (argument >= _arguments.length - _trailingCollections) return 0;
254 251
255 return null; 252 return null;
256 } 253 }
257 254
258 // Only split before the non-block arguments. This case only comes into 255 // Only split before the non-collection arguments. This case only comes into
259 // play when we do want to split the blocks, so force that here. 256 // play when we do want to split the collection, so force that here.
260 if (value == _arguments.length + 1) return 1; 257 if (value == _arguments.length + 1) return 1;
261 258
262 // Split before all of the arguments, even the block ones, so don't let 259 // Split before all of the arguments, even the collection, so don't let
263 // them split. 260 // them split.
264 return 0; 261 return 0;
265 } 262 }
266 } 263 }
267 264
268 /// Splitting rule for a list of named arguments or parameters. Its values mean: 265 /// Splitting rule for a list of named arguments or parameters. Its values mean:
269 /// 266 ///
270 /// * 0: Do not split at all. 267 /// * 0: Do not split at all.
271 /// * 1: Split only before first argument. 268 /// * 1: Split only before first argument.
272 /// * 2: Split before all arguments, including the first. 269 /// * 2: Split before all arguments, including the first.
273 class NamedRule extends ArgumentRule { 270 class NamedRule extends ArgumentRule {
274 /// The chunk prior to the first named argument. 271 /// The chunk prior to the first named argument.
275 Chunk _first; 272 Chunk _first;
276 273
277 int get numValues => 3; 274 int get numValues => 3;
278 275
279 NamedRule(Rule blockRule) : super(blockRule); 276 NamedRule(Rule collectionRule) : super(collectionRule);
280 277
281 void beforeArguments(Chunk chunk) { 278 void beforeArguments(Chunk chunk) {
282 assert(_first == null); 279 assert(_first == null);
283 _first = chunk; 280 _first = chunk;
284 } 281 }
285 282
286 bool isSplit(int value, Chunk chunk) { 283 bool isSplit(int value, Chunk chunk) {
287 switch (value) { 284 switch (value) {
288 case 0: 285 case 0:
289 return false; 286 return false;
290 case 1: 287 case 1:
291 return chunk == _first; 288 return chunk == _first;
292 case 2: 289 case 2:
293 return true; 290 return true;
294 } 291 }
295 292
296 throw "unreachable"; 293 throw "unreachable";
297 } 294 }
298 295
299 int constrain(int value, Rule other) { 296 int constrain(int value, Rule other) {
300 var constrained = super.constrain(value, other); 297 var constrained = super.constrain(value, other);
301 if (constrained != null) return constrained; 298 if (constrained != null) return constrained;
302 299
303 if (other != _blockRule) return null; 300 if (other != _collectionRule) return null;
304 301
305 // If we aren't splitting any args, we can split the block. 302 // If we aren't splitting any args, we can split the collection.
306 if (value == 0) return null; 303 if (value == 0) return null;
307 304
308 // Split before all of the arguments, even the block ones, so don't let 305 // Split before all of the arguments, even the collections, so don't let
309 // them split. 306 // them split.
310 return 0; 307 return 0;
311 } 308 }
312 309
313 String toString() => "Named${super.toString()}"; 310 String toString() => "Named${super.toString()}";
314 } 311 }
OLDNEW
« no previous file with comments | « lib/src/chunk.dart ('k') | lib/src/source_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698