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

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

Issue 1127783002: Add more set-like version constraint operations. (Closed) Base URL: git@github.com:dart-lang/pub_semver@master
Patch Set: merge Created 5 years, 7 months 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 pub_semver.src.version_range; 5 library pub_semver.src.version_range;
6 6
7 import 'version.dart'; 7 import 'version.dart';
8 import 'version_constraint.dart'; 8 import 'version_constraint.dart';
9 import 'version_union.dart';
9 10
10 /// Constrains versions to a fall within a given range. 11 /// Constrains versions to a fall within a given range.
11 /// 12 ///
12 /// If there is a minimum, then this only allows versions that are at that 13 /// If there is a minimum, then this only allows versions that are at that
13 /// minimum or greater. If there is a maximum, then only versions less than 14 /// minimum or greater. If there is a maximum, then only versions less than
14 /// that are allowed. In other words, this allows `>= min, < max`. 15 /// that are allowed. In other words, this allows `>= min, < max`.
15 class VersionRange implements VersionConstraint { 16 class VersionRange implements VersionConstraint {
16 /// The minimum end of the range. 17 /// The minimum end of the range.
17 /// 18 ///
18 /// If [includeMin] is `true`, this will be the minimum allowed version. 19 /// If [includeMin] is `true`, this will be the minimum allowed version.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 !max.isPreRelease && other.isPreRelease && 93 !max.isPreRelease && other.isPreRelease &&
93 other.major == max.major && other.minor == max.minor && 94 other.major == max.major && other.minor == max.minor &&
94 other.patch == max.patch) { 95 other.patch == max.patch) {
95 return false; 96 return false;
96 } 97 }
97 } 98 }
98 99
99 return true; 100 return true;
100 } 101 }
101 102
103 bool allowsAll(VersionConstraint other) {
104 if (other.isEmpty) return true;
105 if (other is Version) return allows(other);
Bob Nystrom 2015/05/05 20:49:09 All these type checks make me think it might be cl
nweiz 2015/05/05 22:52:33 That seems like a lot more conceptual overhead, an
106
107 if (other is VersionUnion) {
108 return other.constraints.every((constraint) => allowsAll(constraint));
109 }
110
111 if (other is VersionRange) {
112 if (min != null) {
113 if (other.min == null) return false;
114 if (min > other.min) return false;
115 if (min == other.min && !includeMin && other.includeMin) return false;
116 }
117
118 if (max != null) {
119 if (other.max == null) return false;
120 if (max < other.max) return false;
121 if (max == other.max && !includeMax && other.includeMax) return false;
122 }
123
124 return true;
125 }
126
127 throw new ArgumentError('Unknown VersionConstraint type $other.');
128 }
129
130 bool allowsAny(VersionConstraint other) {
131 if (other.isEmpty) return false;
132 if (other is Version) return allows(other);
133
134 if (other is VersionUnion) {
135 return other.constraints.any((constraint) => allowsAny(constraint));
136 }
137
138 if (other is VersionRange) {
139 if (min == null || (other.min != null && min < other.min)) {
140 if (other.min == null) return true;
Bob Nystrom 2015/05/05 20:49:09 How about hoisting this out of the outer loop? It'
nweiz 2015/05/05 22:52:33 Done.
141 if (max == null) return true;
142 if (max > other.min) return true;
143 if (max < other.min) return false;
144 assert(max == other.min);
145 return includeMax && other.includeMin;
146 }
147
148 if (other.max == null) return true;
149 if (min < other.max) return true;
150 if (min > other.max) return false;
151 assert(min == other.max);
152 return includeMin && other.includeMax;
153 }
154
155 throw new ArgumentError('Unknown VersionConstraint type $other.');
156 }
157
102 VersionConstraint intersect(VersionConstraint other) { 158 VersionConstraint intersect(VersionConstraint other) {
103 if (other.isEmpty) return other; 159 if (other.isEmpty) return other;
160 if (other is VersionUnion) return other.intersect(this);
104 161
105 // A range and a Version just yields the version if it's in the range. 162 // A range and a Version just yields the version if it's in the range.
106 if (other is Version) { 163 if (other is Version) {
107 return allows(other) ? other : VersionConstraint.empty; 164 return allows(other) ? other : VersionConstraint.empty;
108 } 165 }
109 166
110 if (other is VersionRange) { 167 if (other is VersionRange) {
111 // Intersect the two ranges. 168 // Intersect the two ranges.
112 var intersectMin = min; 169 var intersectMin = min;
113 var intersectIncludeMin = includeMin; 170 var intersectIncludeMin = includeMin;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 } 212 }
156 213
157 // If we got here, there is an actual range. 214 // If we got here, there is an actual range.
158 return new VersionRange(min: intersectMin, max: intersectMax, 215 return new VersionRange(min: intersectMin, max: intersectMax,
159 includeMin: intersectIncludeMin, includeMax: intersectIncludeMax); 216 includeMin: intersectIncludeMin, includeMax: intersectIncludeMax);
160 } 217 }
161 218
162 throw new ArgumentError('Unknown VersionConstraint type $other.'); 219 throw new ArgumentError('Unknown VersionConstraint type $other.');
163 } 220 }
164 221
222 VersionConstraint union(VersionConstraint other) {
223 if (other is Version) {
224 if (allows(other)) return this;
225
226 if (other == min) {
227 return new VersionRange(
228 min: this.min, max: this.max,
229 includeMin: true, includeMax: this.includeMax);
230 }
231
232 if (other == max) {
233 return new VersionRange(
234 min: this.min, max: this.max,
235 includeMin: this.includeMin, includeMax: true);
236 }
237 }
238
239 if (other is VersionRange) {
240 // If the two ranges don't overlap, we won't be able to create a single
241 // VersionRange for both of them.
242 var edgesTouch = max == other.min && (includeMax || other.includeMin);
Bob Nystrom 2015/05/05 20:49:09 What about the other order: other.max == min && (
nweiz 2015/05/05 22:52:34 Done.
243 if (max != null && other.min != null && max <= other.min && !edgesTouch) {
244 return new VersionConstraint.unionOf([this, other]);
245 }
246
247 var unionMin = min;
248 var unionIncludeMin = includeMin;
249 var unionMax = max;
250 var unionIncludeMax = includeMax;
251
252 if (unionMin == null) {
253 // Do nothing.
254 } else if (other.min == null || other.min < unionMin) {
Bob Nystrom 2015/05/05 20:49:09 I think it's a bit easier to read if you use "min"
nweiz 2015/05/05 22:52:34 I was mirroring intersect(), but sure.
255 unionMin = other.min;
256 unionIncludeMin = other.includeMin;
257 } else if (unionMin == other.min && other.includeMin) {
Bob Nystrom 2015/05/05 20:49:09 ...and here. That way the reader doesn't have to s
nweiz 2015/05/05 22:52:33 Done.
258 // If the edges are the same but one is inclusive, make it inclusive.
259 unionIncludeMin = true;
260 }
261
262 if (unionMax == null) {
263 // Do nothing.
264 } else if (other.max == null || other.max > unionMax) {
265 unionMax = other.max;
266 unionIncludeMax = other.includeMax;
267 } else if (unionMax == other.max && other.includeMax) {
268 // If the edges are the same but one is inclusive, make it inclusive.
269 unionIncludeMax = true;
270 }
271
272 return new VersionRange(min: unionMin, max: unionMax,
273 includeMin: unionIncludeMin, includeMax: unionIncludeMax);
274 }
275
276 return new VersionConstraint.unionOf([this, other]);
277 }
278
165 String toString() { 279 String toString() {
166 var buffer = new StringBuffer(); 280 var buffer = new StringBuffer();
167 281
168 if (min != null) { 282 if (min != null) {
169 buffer.write(includeMin ? '>=' : '>'); 283 buffer.write(includeMin ? '>=' : '>');
170 buffer.write(min); 284 buffer.write(min);
171 } 285 }
172 286
173 if (max != null) { 287 if (max != null) {
174 if (min != null) buffer.write(' '); 288 if (min != null) buffer.write(' ');
175 buffer.write(includeMax ? '<=' : '<'); 289 buffer.write(includeMax ? '<=' : '<');
176 buffer.write(max); 290 buffer.write(max);
177 } 291 }
178 292
179 if (min == null && max == null) buffer.write('any'); 293 if (min == null && max == null) buffer.write('any');
180 return buffer.toString(); 294 return buffer.toString();
181 } 295 }
182 } 296 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698