OLD | NEW |
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.rule; | 5 library dart_style.src.rule.rule; |
6 | 6 |
7 import '../chunk.dart'; | 7 import '../chunk.dart'; |
8 import '../fast_hash.dart'; | 8 import '../fast_hash.dart'; |
9 | 9 |
10 /// A constraint that determines the different ways a related set of chunks may | 10 /// A constraint that determines the different ways a related set of chunks may |
(...skipping 23 matching lines...) Expand all Loading... |
34 /// In many cases, if a split occurs inside an expression, surrounding rules | 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 | 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. | 36 /// forces the entire argument list to also split. |
37 /// | 37 /// |
38 /// This tracks those relationships. If this rule splits, (sets its value to | 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 | 39 /// [fullySplitValue]) then all of the outer rules will also be set to their |
40 /// fully split value. | 40 /// fully split value. |
41 /// | 41 /// |
42 /// This contains all direct as well as transitive relationships. If A | 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. | 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>(); | 44 final Set<Rule> _outerRules = new Set<Rule>(); |
46 | 45 |
47 /// Adds [inner] as an inner rule of this rule if it cares about inner rules. | 46 /// Adds [inner] as an inner rule of this rule if it cares about inner rules. |
48 /// | 47 /// |
49 /// When an inner rule splits, it forces any surrounding outer rules to also | 48 /// When an inner rule splits, it forces any surrounding outer rules to also |
50 /// split. | 49 /// split. |
51 void contain(Rule inner) { | 50 void contain(Rule inner) { |
52 if (!splitsOnInnerRules) return; | 51 if (!splitsOnInnerRules) return; |
53 inner._outerRules.add(this); | 52 inner._outerRules.add(this); |
54 } | 53 } |
(...skipping 16 matching lines...) Expand all Loading... |
71 /// null to not constrain other. | 70 /// null to not constrain other. |
72 int constrain(int value, Rule other) { | 71 int constrain(int value, Rule other) { |
73 // By default, any implied rule will be fully split if this one is fully | 72 // By default, any implied rule will be fully split if this one is fully |
74 // split. | 73 // split. |
75 if (value == 0) return null; | 74 if (value == 0) return null; |
76 if (_outerRules.contains(other)) return other.fullySplitValue; | 75 if (_outerRules.contains(other)) return other.fullySplitValue; |
77 | 76 |
78 return null; | 77 return null; |
79 } | 78 } |
80 | 79 |
| 80 /// A protected method for subclasses to add the rules that they constrain |
| 81 /// to [rules]. |
| 82 /// |
| 83 /// Called by [Rule] the first time [constrainedRules] is accessed. |
| 84 void addConstrainedRules(Set<Rule> rules) {} |
| 85 |
| 86 /// Discards constraints on any rule that doesn't have an index. |
| 87 /// |
| 88 /// This is called by [LineSplitter] after it has indexed all of the in-use |
| 89 /// rules. A rule may end up with a constraint on a rule that's no longer |
| 90 /// used by any chunk. This can happen if the rule gets hardened, or if it |
| 91 /// simply never got used by a chunk. For example, a rule for splitting an |
| 92 /// empty list of metadata annotations. |
| 93 /// |
| 94 /// This removes all of those. |
| 95 void forgetUnusedRules() { |
| 96 _outerRules.retainWhere((rule) => rule.index != null); |
| 97 |
| 98 // Clear the cached ones too. |
| 99 _constrainedRules = null; |
| 100 _allConstrainedRules = null; |
| 101 } |
| 102 |
81 /// The other [Rule]s that this rule places immediate constraints on. | 103 /// The other [Rule]s that this rule places immediate constraints on. |
82 Iterable<Rule> get constrainedRules => _outerRules; | 104 Set<Rule> get constrainedRules { |
| 105 // Lazy initialize this on first use. Note: Assumes this is only called |
| 106 // after the chunks have been written and any constraints have been wired |
| 107 // up. |
| 108 if (_constrainedRules == null) { |
| 109 _constrainedRules = _outerRules.toSet(); |
| 110 addConstrainedRules(_constrainedRules); |
| 111 } |
| 112 |
| 113 return _constrainedRules; |
| 114 } |
| 115 Set<Rule> _constrainedRules; |
83 | 116 |
84 /// The transitive closure of all of the rules this rule places constraints | 117 /// The transitive closure of all of the rules this rule places constraints |
85 /// on, directly or indirectly, including itself. | 118 /// on, directly or indirectly, including itself. |
86 Set<Rule> get allConstrainedRules { | 119 Set<Rule> get allConstrainedRules { |
87 if (_allConstrainedRules == null) { | 120 if (_allConstrainedRules == null) { |
88 visit(Rule rule) { | 121 visit(Rule rule) { |
89 if (_allConstrainedRules.contains(rule)) return; | 122 if (_allConstrainedRules.contains(rule)) return; |
90 | 123 |
91 _allConstrainedRules.add(rule); | 124 _allConstrainedRules.add(rule); |
92 rule.constrainedRules.forEach(visit); | 125 rule.constrainedRules.forEach(visit); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 | 167 |
135 SimpleRule({int cost, bool splitsOnInnerRules}) | 168 SimpleRule({int cost, bool splitsOnInnerRules}) |
136 : cost = cost != null ? cost : Cost.normal, | 169 : cost = cost != null ? cost : Cost.normal, |
137 splitsOnInnerRules = | 170 splitsOnInnerRules = |
138 splitsOnInnerRules != null ? splitsOnInnerRules : true; | 171 splitsOnInnerRules != null ? splitsOnInnerRules : true; |
139 | 172 |
140 bool isSplit(int value, Chunk chunk) => value == 1; | 173 bool isSplit(int value, Chunk chunk) => value == 1; |
141 | 174 |
142 String toString() => "Simple${super.toString()}"; | 175 String toString() => "Simple${super.toString()}"; |
143 } | 176 } |
OLD | NEW |