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

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

Issue 1492683002: Change the way hard splits are handled. (Closed) Base URL: https://github.com/dart-lang/dart_style.git@master
Patch Set: Created 5 years 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/rule/metadata.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.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
11 /// be split. 11 /// be split.
12 abstract class Rule extends FastHash { 12 class Rule extends FastHash {
13 /// Rule value that splits no chunks. 13 /// Rule value that splits no chunks.
14 /// 14 ///
15 /// Every rule is required to treat this value as fully unsplit. 15 /// Every rule is required to treat this value as fully unsplit.
16 static const unsplit = 0; 16 static const unsplit = 0;
17 17
18 /// Rule constraint value that means "any value as long as something splits". 18 /// Rule constraint value that means "any value as long as something splits".
19 /// 19 ///
20 /// It disallows [unsplit] but allows any other value. 20 /// It disallows [unsplit] but allows any other value.
21 static const mustSplit = -1; 21 static const mustSplit = -1;
22 22
23 /// The number of different states this rule can be in. 23 /// The number of different states this rule can be in.
24 /// 24 ///
25 /// Each state determines which set of chunks using this rule are split and 25 /// Each state determines which set of chunks using this rule are split and
26 /// which aren't. Values range from zero to one minus this. Value zero 26 /// which aren't. Values range from zero to one minus this. Value zero
27 /// always means "no chunks are split" and increasing values by convention 27 /// always means "no chunks are split" and increasing values by convention
28 /// mean increasingly undesirable splits. 28 /// mean increasingly undesirable splits.
29 int get numValues; 29 ///
30 /// By default, a rule has two values: fully unsplit and fully split.
31 int get numValues => 2;
30 32
31 /// The rule value that forces this rule into its maximally split state. 33 /// The rule value that forces this rule into its maximally split state.
32 /// 34 ///
33 /// By convention, this is the highest of the range of allowed values. 35 /// By convention, this is the highest of the range of allowed values.
34 int get fullySplitValue => numValues - 1; 36 int get fullySplitValue => numValues - 1;
35 37
36 int get cost => Cost.normal; 38 final int cost;
37 39
38 /// During line splitting [LineSplitter] sets this to the index of this 40 /// During line splitting [LineSplitter] sets this to the index of this
39 /// rule in its list of rules. 41 /// rule in its list of rules.
40 int index; 42 int index;
41 43
44 /// If `true`, the rule has been "hardened" meaning it's been placed into a
45 /// permanent "must fully split" state.
46 bool get isHardened => _isHardened;
47 bool _isHardened = false;
48
42 /// The other [Rule]s that "surround" this one (and care about that fact). 49 /// The other [Rule]s that "surround" this one (and care about that fact).
43 /// 50 ///
44 /// In many cases, if a split occurs inside an expression, surrounding rules 51 /// In many cases, if a split occurs inside an expression, surrounding rules
45 /// also want to split too. For example, a split in the middle of an argument 52 /// also want to split too. For example, a split in the middle of an argument
46 /// forces the entire argument list to also split. 53 /// forces the entire argument list to also split.
47 /// 54 ///
48 /// This tracks those relationships. If this rule splits, (sets its value to 55 /// This tracks those relationships. If this rule splits, (sets its value to
49 /// [fullySplitValue]) then all of the outer rules will also be set to their 56 /// [fullySplitValue]) then all of the outer rules will also be set to their
50 /// fully split value. 57 /// fully split value.
51 /// 58 ///
(...skipping 10 matching lines...) Expand all
62 inner._outerRules.add(this); 69 inner._outerRules.add(this);
63 } 70 }
64 71
65 /// Whether this rule cares about rules that it contains. 72 /// Whether this rule cares about rules that it contains.
66 /// 73 ///
67 /// If `true` then inner rules will constrain this one and force it to split 74 /// If `true` then inner rules will constrain this one and force it to split
68 /// when they split. Otherwise, it can split independently of any contained 75 /// when they split. Otherwise, it can split independently of any contained
69 /// rules. 76 /// rules.
70 bool get splitsOnInnerRules => true; 77 bool get splitsOnInnerRules => true;
71 78
72 bool isSplit(int value, Chunk chunk); 79 Rule([int cost]) : cost = cost ?? Cost.normal;
80
81 /// Creates a new rule that is already fully split.
82 Rule.hard() : cost = 0 {
83 // Set the cost to zero since it will always be applied, so there's no
84 // point in penalizing it.
85 //
86 // Also, this avoids doubled counting in literal blocks where there is both
87 // a split in the outer chunk containing the block and the inner hard split
88 // between the elements or statements.
89 harden();
90 }
91
92 /// Fixes this rule into a "fully split" state.
93 void harden() {
94 _isHardened = true;
95 }
96
97 /// Returns `true` if [chunk] should split when this rule has [value].
98 bool isSplit(int value, Chunk chunk) {
99 if (_isHardened) return true;
100
101 if (value == Rule.unsplit) return false;
102
103 // Let the subclass decide.
104 return isSplitAtValue(value, chunk);
105 }
106
107 /// Subclasses can override this to determine which values split which chunks.
108 ///
109 /// By default, this assumes every chunk splits.
110 bool isSplitAtValue(value, chunk) => true;
73 111
74 /// Given that this rule has [value], determine if [other]'s value should be 112 /// Given that this rule has [value], determine if [other]'s value should be
75 /// constrained. 113 /// constrained.
76 /// 114 ///
77 /// Allows relationships between rules like "if I split, then this should 115 /// Allows relationships between rules like "if I split, then this should
78 /// split too". Returns a non-negative value to force [other] to take that 116 /// split too". Returns a non-negative value to force [other] to take that
79 /// value. Returns -1 to allow [other] to take any non-zero value. Returns 117 /// value. Returns -1 to allow [other] to take any non-zero value. Returns
80 /// null to not constrain other. 118 /// null to not constrain other.
81 int constrain(int value, Rule other) { 119 int constrain(int value, Rule other) {
82 // By default, any containing rule will be fully split if this one is split. 120 // By default, any containing rule will be fully split if this one is split.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 visit(this); 177 visit(this);
140 } 178 }
141 179
142 return _allConstrainedRules; 180 return _allConstrainedRules;
143 } 181 }
144 182
145 Set<Rule> _allConstrainedRules; 183 Set<Rule> _allConstrainedRules;
146 184
147 String toString() => "$id"; 185 String toString() => "$id";
148 } 186 }
149
150 /// A rule that always splits a chunk.
151 class HardSplitRule extends Rule {
152 int get numValues => 1;
153
154 /// It's always going to be applied, so there's no point in penalizing it.
155 ///
156 /// Also, this avoids doubled counting in literal blocks where there is both
157 /// a split in the outer chunk containing the block and the inner hard split
158 /// between the elements or statements.
159 int get cost => 0;
160
161 /// It's always split anyway.
162 bool get splitsOnInnerRules => false;
163
164 bool isSplit(int value, Chunk chunk) => true;
165
166 String toString() => "Hard";
167 }
168
169 /// A basic rule that has two states: unsplit or split.
170 class SimpleRule extends Rule {
171 /// Two values: 0 is unsplit, 1 is split.
172 int get numValues => 2;
173
174 final int cost;
175
176 SimpleRule([int cost]) : cost = cost != null ? cost : Cost.normal;
177
178 bool isSplit(int value, Chunk chunk) => value != Rule.unsplit;
179
180 String toString() => "Simple${super.toString()}";
181 }
OLDNEW
« no previous file with comments | « lib/src/rule/metadata.dart ('k') | lib/src/source_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698