Index: packages/dart_style/lib/src/rule/argument.dart |
diff --git a/packages/dart_style/lib/src/rule/argument.dart b/packages/dart_style/lib/src/rule/argument.dart |
index 813bfb1087dba662b5bf0bbfaaf10fa54ab317ee..ed7758a3e216377e42a5c02dc7bb417a19bf33a8 100644 |
--- a/packages/dart_style/lib/src/rule/argument.dart |
+++ b/packages/dart_style/lib/src/rule/argument.dart |
@@ -9,8 +9,23 @@ import 'rule.dart'; |
/// Base class for a rule that handles argument or parameter lists. |
abstract class ArgumentRule extends Rule { |
+ /// The chunks prior to each positional argument. |
+ final List<Chunk> _arguments = []; |
+ |
/// The rule used to split collections in the argument list, if any. |
- final Rule _collectionRule; |
+ Rule _collectionRule; |
+ |
+ /// The number of leading collection arguments. |
+ /// |
+ /// This and [_trailingCollections] cannot both be positive. If every |
+ /// argument is a collection, this will be [_arguments.length] and |
+ /// [_trailingCollections] will be 0. |
+ final int _leadingCollections; |
+ |
+ /// The number of trailing collections. |
+ /// |
+ /// This and [_leadingCollections] cannot both be positive. |
+ final int _trailingCollections; |
/// If true, then inner rules that are written will force this rule to split. |
/// |
@@ -21,11 +36,26 @@ abstract class ArgumentRule extends Rule { |
/// Don't split when an inner collection rule splits. |
bool get splitsOnInnerRules => _trackInnerRules; |
- /// Creates a new rule for a positional argument list. |
- /// |
- /// If [_collectionRule] is given, it is the rule used to split the |
- /// collections in the list. |
- ArgumentRule(this._collectionRule); |
+ ArgumentRule(this._collectionRule, this._leadingCollections, |
+ this._trailingCollections); |
+ |
+ void addConstrainedRules(Set<Rule> rules) { |
+ super.addConstrainedRules(rules); |
+ if (_collectionRule != null) rules.add(_collectionRule); |
+ } |
+ |
+ void forgetUnusedRules() { |
+ super.forgetUnusedRules(); |
+ if (_collectionRule != null && _collectionRule.index == null) { |
+ _collectionRule = null; |
+ } |
+ } |
+ |
+ /// Remembers [chunk] as containing the split that occurs right before an |
+ /// argument in the list. |
+ void beforeArgument(Chunk chunk) { |
+ _arguments.add(chunk); |
+ } |
/// Called before a collection argument is written. |
/// |
@@ -46,28 +76,37 @@ abstract class ArgumentRule extends Rule { |
/// Base class for a rule for handling positional argument lists. |
abstract class PositionalRule extends ArgumentRule { |
- /// The chunks prior to each positional argument. |
- final List<Chunk> _arguments = []; |
- |
/// If there are named arguments following these positional ones, this will |
/// be their rule. |
Rule _namedArgsRule; |
/// Creates a new rule for a positional argument list. |
/// |
- /// If [collectionRule] is given, it is the rule used to split the collection |
+ /// If [_collectionRule] is given, it is the rule used to split the collection |
/// arguments in the list. |
- PositionalRule(Rule collectionRule) : super(collectionRule); |
+ PositionalRule( |
+ Rule collectionRule, int leadingCollections, int trailingCollections) |
+ : super(collectionRule, leadingCollections, trailingCollections); |
- /// Remembers [chunk] as containing the split that occurs right before an |
- /// argument in the list. |
- void beforeArgument(Chunk chunk) { |
- _arguments.add(chunk); |
+ void addConstrainedRules(Set<Rule> rules) { |
+ super.addConstrainedRules(rules); |
+ if (_namedArgsRule != null) rules.add(_namedArgsRule); |
} |
- /// Remembers that [rule] is the [NamedArgsRule] immediately following this |
+ void forgetUnusedRules() { |
+ super.forgetUnusedRules(); |
+ if (_namedArgsRule != null && _namedArgsRule.index == null) { |
+ _namedArgsRule = null; |
+ } |
+ } |
+ |
+ /// Remembers that [rule] is the [Rule] immediately following this positional |
/// positional argument list. |
- void setNamedArgsRule(NamedRule rule) { |
+ /// |
+ /// This is normally a [NamedRule] but [PositionalRule] is also used for the |
+ /// property accesses at the beginning of a call chain, in which case this |
+ /// is just a [SimpleRule]. |
+ void setNamedArgsRule(Rule rule) { |
_namedArgsRule = rule; |
} |
@@ -104,20 +143,16 @@ class SinglePositionalRule extends PositionalRule { |
/// internally without forcing a split before the argument. |
final bool splitsOnInnerRules; |
- bool hack = false; |
- |
/// Creates a new rule for a positional argument list. |
/// |
/// If [collectionRule] is given, it is the rule used to split the |
/// collections in the list. If [splitsOnInnerRules] is `true`, then we will |
/// split before the argument if the argument itself contains a split. |
SinglePositionalRule(Rule collectionRule, {bool splitsOnInnerRules}) |
- : super(collectionRule), |
+ : super(collectionRule, 0, 0), |
splitsOnInnerRules = |
splitsOnInnerRules != null ? splitsOnInnerRules : false; |
- bool isSplit(int value, Chunk chunk) => value == 1; |
- |
int constrain(int value, Rule other) { |
var constrained = super.constrain(value, other); |
if (constrained != null) return constrained; |
@@ -125,10 +160,10 @@ class SinglePositionalRule extends PositionalRule { |
if (other != _collectionRule) return null; |
// If we aren't splitting any args, we can split the collection. |
- if (value == 0) return null; |
+ if (value == Rule.unsplit) return null; |
// We are splitting before a collection, so don't let it split internally. |
- return 0; |
+ return Rule.unsplit; |
} |
String toString() => "1Pos${super.toString()}"; |
@@ -152,18 +187,6 @@ class SinglePositionalRule extends PositionalRule { |
/// splits before all of the non-collection arguments, but does not split |
/// before the collections, so that they can split internally. |
class MultiplePositionalRule extends PositionalRule { |
- /// The number of leading collection arguments. |
- /// |
- /// This and [_trailingCollections] cannot both be positive. If every |
- /// argument is a collection, this will be [_arguments.length] and |
- /// [_trailingCollections] will be 0. |
- final int _leadingCollections; |
- |
- /// The number of trailing collections. |
- /// |
- /// This and [_leadingCollections] cannot both be positive. |
- final int _trailingCollections; |
- |
int get numValues { |
// Can split before any one argument, none, or all. |
var result = 2 + _arguments.length; |
@@ -181,15 +204,12 @@ class MultiplePositionalRule extends PositionalRule { |
} |
MultiplePositionalRule( |
- Rule collectionRule, this._leadingCollections, this._trailingCollections) |
- : super(collectionRule); |
+ Rule collectionRule, int leadingCollections, int trailingCollections) |
+ : super(collectionRule, leadingCollections, trailingCollections); |
String toString() => "*Pos${super.toString()}"; |
- bool isSplit(int value, Chunk chunk) { |
- // Don't split at all. |
- if (value == 0) return false; |
- |
+ bool isSplitAtValue(int value, Chunk chunk) { |
// Split only before the first argument. Keep the entire argument list |
// together on the next line. |
if (value == 1) return chunk == _arguments.first; |
@@ -224,17 +244,22 @@ class MultiplePositionalRule extends PositionalRule { |
var constrained = super.constrain(value, other); |
if (constrained != null) return constrained; |
+ // Decide how to constrain the collection rule. |
if (other != _collectionRule) return null; |
+ // If all of the collections are in the named arguments, [_collectionRule] |
+ // will not be null, but we don't have to handle it. |
+ if (_leadingCollections == 0 && _trailingCollections == 0) return null; |
+ |
// If we aren't splitting any args, we can split the collection. |
- if (value == 0) return null; |
+ if (value == Rule.unsplit) return null; |
// Split only before the first argument. |
if (value == 1) { |
if (_leadingCollections > 0) { |
// We are splitting before a collection, so don't let it split |
// internally. |
- return 0; |
+ return Rule.unsplit; |
} else { |
// The split is outside of the collections so they can split or not. |
return null; |
@@ -245,8 +270,10 @@ class MultiplePositionalRule extends PositionalRule { |
// arguments, don't allow them to split. |
if (value <= _arguments.length) { |
var argument = _arguments.length - value + 1; |
- if (argument < _leadingCollections) return 0; |
- if (argument >= _arguments.length - _trailingCollections) return 0; |
+ if (argument < _leadingCollections || |
+ argument >= _arguments.length - _trailingCollections) { |
+ return Rule.unsplit; |
+ } |
return null; |
} |
@@ -255,55 +282,53 @@ class MultiplePositionalRule extends PositionalRule { |
// play when we do want to split the collection, so force that here. |
if (value == _arguments.length + 1) return 1; |
- // Split before all of the arguments, even the collection, so don't let |
- // them split. |
- return 0; |
+ // Split before all of the arguments, even the collections. We'll allow |
+ // them to split but indent their bodies if they do. |
+ return null; |
} |
} |
/// Splitting rule for a list of named arguments or parameters. Its values mean: |
/// |
-/// * 0: Do not split at all. |
-/// * 1: Split only before first argument. |
-/// * 2: Split before all arguments, including the first. |
+/// * Do not split at all. |
+/// * Split only before first argument. |
+/// * Split before all arguments. |
class NamedRule extends ArgumentRule { |
- /// The chunk prior to the first named argument. |
- Chunk _first; |
- |
int get numValues => 3; |
- NamedRule(Rule collectionRule) : super(collectionRule); |
+ NamedRule( |
+ Rule collectionRule, int leadingCollections, int trailingCollections) |
+ : super(collectionRule, leadingCollections, trailingCollections); |
- void beforeArguments(Chunk chunk) { |
- assert(_first == null); |
- _first = chunk; |
- } |
- |
- bool isSplit(int value, Chunk chunk) { |
- switch (value) { |
- case 0: |
- return false; |
- case 1: |
- return chunk == _first; |
- case 2: |
- return true; |
- } |
+ bool isSplitAtValue(int value, Chunk chunk) { |
+ // Move all arguments to the second line as a unit. |
+ if (value == 1) return chunk == _arguments.first; |
- throw "unreachable"; |
+ // Otherwise, split before all arguments. |
+ return true; |
} |
int constrain(int value, Rule other) { |
var constrained = super.constrain(value, other); |
if (constrained != null) return constrained; |
+ // Decide how to constrain the collection rule. |
if (other != _collectionRule) return null; |
+ // If all of the collections are in the named arguments, [_collectionRule] |
+ // will not be null, but we don't have to handle it. |
+ if (_leadingCollections == 0 && _trailingCollections == 0) return null; |
+ |
// If we aren't splitting any args, we can split the collection. |
- if (value == 0) return null; |
+ if (value == Rule.unsplit) return null; |
- // Split before all of the arguments, even the collections, so don't let |
- // them split. |
- return 0; |
+ // Split only before the first argument. Don't allow the collections to |
+ // split. |
+ if (value == 1) return Rule.unsplit; |
+ |
+ // Split before all of the arguments, even the collections. We'll allow |
+ // them to split but indent their bodies if they do. |
+ return null; |
} |
String toString() => "Named${super.toString()}"; |