| 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()}";
|
|
|