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

Side by Side Diff: packages/dart_style/lib/src/line_splitting/rule_set.dart

Issue 1521693002: Roll Observatory deps (charted -> ^0.3.0) (Closed) Base URL: https://chromium.googlesource.com/external/github.com/dart-lang/observatory_pub_packages.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
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.line_splitting.rule_set; 5 library dart_style.src.line_splitting.rule_set;
6 6
7 import '../rule/rule.dart'; 7 import '../rule/rule.dart';
8 8
9 /// An optimized data structure for storing a set of values for some rules. 9 /// An optimized data structure for storing a set of values for some rules.
10 /// 10 ///
11 /// This conceptually behaves roughly like a `Map<Rule, int>`, but is much 11 /// This conceptually behaves roughly like a `Map<Rule, int>`, but is much
12 /// faster since it avoids hashing. Instead, it assumes the line splitter has 12 /// faster since it avoids hashing. Instead, it assumes the line splitter has
13 /// provided an ordered list of [Rule]s and that each rule's [index] field has 13 /// provided an ordered list of [Rule]s and that each rule's [index] field has
14 /// been set to point to the rule in the list. 14 /// been set to point to the rule in the list.
15 /// 15 ///
16 /// Internally, this then just stores the values in a sparse list whose indices 16 /// Internally, this then just stores the values in a sparse list whose indices
17 /// are the indices of the rules. 17 /// are the indices of the rules.
18 class RuleSet { 18 class RuleSet {
19 List<int> _values; 19 List<int> _values;
20 20
21 RuleSet(int numRules) : this._(new List(numRules)); 21 RuleSet(int numRules) : this._(new List(numRules));
22 22
23 RuleSet._(this._values); 23 RuleSet._(this._values);
24 24
25 /// Returns `true` of [rule] is bound in this set. 25 /// Returns `true` of [rule] is bound in this set.
26 bool contains(Rule rule) => _values[rule.index] != null; 26 bool contains(Rule rule) {
27 // Treat hardened rules as implicitly bound.
28 if (rule.isHardened) return true;
27 29
28 /// Gets the bound value for [rule] or `0` if it is not bound. 30 return _values[rule.index] != null;
31 }
32
33 /// Gets the bound value for [rule] or [Rule.unsplit] if it is not bound.
29 int getValue(Rule rule) { 34 int getValue(Rule rule) {
35 // Hardened rules are implicitly bound.
36 if (rule.isHardened) return rule.fullySplitValue;
37
30 var value = _values[rule.index]; 38 var value = _values[rule.index];
31 if (value != null) return value; 39 if (value != null) return value;
32 40
33 return 0; 41 return Rule.unsplit;
34 } 42 }
35 43
36 /// Invokes [callback] for each rule in [rules] with the rule's value, which 44 /// Invokes [callback] for each rule in [rules] with the rule's value, which
37 /// will be `null` if it is not bound. 45 /// will be `null` if it is not bound.
38 void forEach(List<Rule> rules, callback(Rule rule, int value)) { 46 void forEach(List<Rule> rules, callback(Rule rule, int value)) {
39 var i = 0; 47 var i = 0;
40 for (var rule in rules) { 48 for (var rule in rules) {
41 var value = _values[i]; 49 var value = _values[i];
42 if (value != null) callback(rule, value); 50 if (value != null) callback(rule, value);
43 i++; 51 i++;
44 } 52 }
45 } 53 }
46 54
47 /// Creates a new [RuleSet] with the same bound rule values as this one. 55 /// Creates a new [RuleSet] with the same bound rule values as this one.
48 RuleSet clone() => new RuleSet._(_values.toList(growable: false)); 56 RuleSet clone() => new RuleSet._(_values.toList(growable: false));
49 57
50 /// Binds [rule] to [value] then checks to see if that violates any 58 /// Binds [rule] to [value] then checks to see if that violates any
51 /// constraints. 59 /// constraints.
52 /// 60 ///
53 /// Returns `true` if all constraints between the bound rules are valid. Even 61 /// Returns `true` if all constraints between the bound rules are valid. Even
54 /// if not, this still modifies the [RuleSet]. 62 /// if not, this still modifies the [RuleSet].
55 /// 63 ///
56 /// If an unbound rule gets constrained to `-1` (meaning it must split, but 64 /// If an unbound rule gets constrained to `-1` (meaning it must split, but
57 /// can split any way it wants), invokes [onSplitRule] with it. 65 /// can split any way it wants), invokes [onSplitRule] with it.
58 bool tryBind(List<Rule> rules, Rule rule, int value, onSplitRule(Rule rule)) { 66 bool tryBind(List<Rule> rules, Rule rule, int value, onSplitRule(Rule rule)) {
67 assert(!rule.isHardened);
68
59 _values[rule.index] = value; 69 _values[rule.index] = value;
60 70
61 // Test this rule against the other rules being bound. 71 // Test this rule against the other rules being bound.
62 for (var other in rules) { 72 for (var other in rule.constrainedRules) {
63 if (rule == other) continue; 73 var otherValue;
74 // Hardened rules are implicitly bound.
75 if (other.isHardened) {
76 otherValue = other.fullySplitValue;
77 } else {
78 otherValue = _values[other.index];
79 }
64 80
65 var otherValue = _values[other.index];
66 var constraint = rule.constrain(value, other); 81 var constraint = rule.constrain(value, other);
67 82
68 if (otherValue == null) { 83 if (otherValue == null) {
69 // The other rule is unbound, so see if we can constrain it eagerly to 84 // The other rule is unbound, so see if we can constrain it eagerly to
70 // a value now. 85 // a value now.
71 if (constraint == -1) { 86 if (constraint == Rule.mustSplit) {
72 // If we know the rule has to split and there's only one way it can, 87 // If we know the rule has to split and there's only one way it can,
73 // just bind that. 88 // just bind that.
74 if (other.numValues == 2) { 89 if (other.numValues == 2) {
75 if (!tryBind(rules, other, 1, onSplitRule)) return false; 90 if (!tryBind(rules, other, 1, onSplitRule)) return false;
76 } else { 91 } else {
77 onSplitRule(other); 92 onSplitRule(other);
78 } 93 }
79 } else if (constraint != null) { 94 } else if (constraint != null) {
80 // Bind the other rule to its value and recursively propagate its 95 // Bind the other rule to its value and recursively propagate its
81 // constraints. 96 // constraints.
82 if (!tryBind(rules, other, constraint, onSplitRule)) return false; 97 if (!tryBind(rules, other, constraint, onSplitRule)) return false;
83 } 98 }
84 } else { 99 } else {
85 // It's already bound, so see if the new rule's constraint disallows 100 // It's already bound, so see if the new rule's constraint disallows
86 // that value. 101 // that value.
87 if (constraint == -1) { 102 if (constraint == Rule.mustSplit) {
88 if (otherValue == 0) return false; 103 if (otherValue == Rule.unsplit) return false;
89 } else if (constraint != null) { 104 } else if (constraint != null) {
90 if (otherValue != constraint) return false; 105 if (otherValue != constraint) return false;
91 } 106 }
92 107
93 // See if the other rule's constraint allows us to use this value. 108 // See if the other rule's constraint allows us to use this value.
94 constraint = other.constrain(otherValue, rule); 109 constraint = other.constrain(otherValue, rule);
95 if (constraint == -1) { 110 if (constraint == Rule.mustSplit) {
96 if (value == 0) return false; 111 if (value == Rule.unsplit) return false;
97 } else if (constraint != null) { 112 } else if (constraint != null) {
98 if (value != constraint) return false; 113 if (value != constraint) return false;
99 } 114 }
100 } 115 }
101 } 116 }
102 117
103 return true; 118 return true;
104 } 119 }
105 120
106 String toString() => 121 String toString() =>
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 var result = []; 163 var result = [];
149 for (var i = 0; i < _columns.length; i++) { 164 for (var i = 0; i < _columns.length; i++) {
150 if (_columns[i] != null) { 165 if (_columns[i] != null) {
151 result.add("$i:${_columns[i]}"); 166 result.add("$i:${_columns[i]}");
152 } 167 }
153 } 168 }
154 169
155 return result.join(" "); 170 return result.join(" ");
156 } 171 }
157 } 172 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698