| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library dart_style.src.rule.rule; | |
| 6 | |
| 7 import '../chunk.dart'; | |
| 8 import '../fast_hash.dart'; | |
| 9 | |
| 10 /// A constraint that determines the different ways a related set of chunks may | |
| 11 /// be split. | |
| 12 abstract class Rule extends FastHash { | |
| 13 /// The number of different states this rule can be in. | |
| 14 /// | |
| 15 /// Each state determines which set of chunks using this rule are split and | |
| 16 /// which aren't. Values range from zero to one minus this. Value zero | |
| 17 /// always means "no chunks are split" and increasing values by convention | |
| 18 /// mean increasingly undesirable splits. | |
| 19 int get numValues; | |
| 20 | |
| 21 /// The rule value that forces this rule into its maximally split state. | |
| 22 /// | |
| 23 /// By convention, this is the highest of the range of allowed values. | |
| 24 int get fullySplitValue => numValues - 1; | |
| 25 | |
| 26 int get cost => Cost.normal; | |
| 27 | |
| 28 /// During line splitting [LineSplitter] sets this to the index of this | |
| 29 /// rule in its list of rules. | |
| 30 int index; | |
| 31 | |
| 32 /// The other [Rule]s that "surround" this one (and care about that fact). | |
| 33 /// | |
| 34 /// In many cases, if a split occurs inside an expression, surrounding rules | |
| 35 /// also want to split too. For example, a split in the middle of an argument | |
| 36 /// forces the entire argument list to also split. | |
| 37 /// | |
| 38 /// This tracks those relationships. If this rule splits, (sets its value to | |
| 39 /// [fullySplitValue]) then all of the outer rules will also be set to their | |
| 40 /// fully split value. | |
| 41 /// | |
| 42 /// This contains all direct as well as transitive relationships. If A | |
| 43 /// contains B which contains C, C's outerRules contains both B and A. | |
| 44 Iterable<Rule> get outerRules => _outerRules; | |
| 45 final Set<Rule> _outerRules = new Set<Rule>(); | |
| 46 | |
| 47 /// Adds [inner] as an inner rule of this rule if it cares about inner rules. | |
| 48 /// | |
| 49 /// When an inner rule splits, it forces any surrounding outer rules to also | |
| 50 /// split. | |
| 51 void contain(Rule inner) { | |
| 52 if (!splitsOnInnerRules) return; | |
| 53 inner._outerRules.add(this); | |
| 54 } | |
| 55 | |
| 56 /// Whether this rule cares about rules that it contains. | |
| 57 /// | |
| 58 /// If `true` then inner rules will constrain this one and force it to split | |
| 59 /// when they split. Otherwise, it can split independently of any contained | |
| 60 /// rules. | |
| 61 bool get splitsOnInnerRules => true; | |
| 62 | |
| 63 bool isSplit(int value, Chunk chunk); | |
| 64 | |
| 65 /// Given that this rule has [value], determine if [other]'s value should be | |
| 66 /// constrained. | |
| 67 /// | |
| 68 /// Allows relationships between rules like "if I split, then this should | |
| 69 /// split too". Returns a non-negative value to force [other] to take that | |
| 70 /// value. Returns -1 to allow [other] to take any non-zero value. Returns | |
| 71 /// null to not constrain other. | |
| 72 int constrain(int value, Rule other) { | |
| 73 // By default, any implied rule will be fully split if this one is fully | |
| 74 // split. | |
| 75 if (value == 0) return null; | |
| 76 if (_outerRules.contains(other)) return other.fullySplitValue; | |
| 77 | |
| 78 return null; | |
| 79 } | |
| 80 | |
| 81 String toString() => "$id"; | |
| 82 } | |
| 83 | |
| 84 /// A rule that always splits a chunk. | |
| 85 class HardSplitRule extends Rule { | |
| 86 int get numValues => 1; | |
| 87 | |
| 88 /// It's always going to be applied, so there's no point in penalizing it. | |
| 89 /// | |
| 90 /// Also, this avoids doubled counting in literal blocks where there is both | |
| 91 /// a split in the outer chunk containing the block and the inner hard split | |
| 92 /// between the elements or statements. | |
| 93 int get cost => 0; | |
| 94 | |
| 95 /// It's always split anyway. | |
| 96 bool get splitsOnInnerRules => false; | |
| 97 | |
| 98 bool isSplit(int value, Chunk chunk) => true; | |
| 99 | |
| 100 String toString() => "Hard"; | |
| 101 } | |
| 102 | |
| 103 /// A basic rule that has two states: unsplit or split. | |
| 104 class SimpleRule extends Rule { | |
| 105 /// Two values: 0 is unsplit, 1 is split. | |
| 106 int get numValues => 2; | |
| 107 | |
| 108 final int cost; | |
| 109 | |
| 110 final bool splitsOnInnerRules; | |
| 111 | |
| 112 SimpleRule({int cost, bool splitsOnInnerRules}) | |
| 113 : cost = cost != null ? cost : Cost.normal, | |
| 114 splitsOnInnerRules = | |
| 115 splitsOnInnerRules != null ? splitsOnInnerRules : true; | |
| 116 | |
| 117 bool isSplit(int value, Chunk chunk) => value == 1; | |
| 118 | |
| 119 String toString() => "Simple${super.toString()}"; | |
| 120 } | |
| OLD | NEW |