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

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

Issue 2045803002: Add VersionConstraint.difference(). (Closed) Base URL: git@github.com:dart-lang/pub_semver@master
Patch Set: Code review changes Created 4 years, 6 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
« no previous file with comments | « lib/src/version_constraint.dart ('k') | lib/src/version_union.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) 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 import 'utils.dart'; 5 import 'utils.dart';
6 import 'version.dart'; 6 import 'version.dart';
7 import 'version_constraint.dart'; 7 import 'version_constraint.dart';
8 import 'version_union.dart'; 8 import 'version_union.dart';
9 9
10 /// Constrains versions to a fall within a given range. 10 /// Constrains versions to a fall within a given range.
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 153
154 bool allowsAny(VersionConstraint other) { 154 bool allowsAny(VersionConstraint other) {
155 if (other.isEmpty) return false; 155 if (other.isEmpty) return false;
156 if (other is Version) return allows(other); 156 if (other is Version) return allows(other);
157 157
158 if (other is VersionUnion) { 158 if (other is VersionUnion) {
159 return other.ranges.any((constraint) => allowsAny(constraint)); 159 return other.ranges.any((constraint) => allowsAny(constraint));
160 } 160 }
161 161
162 if (other is VersionRange) { 162 if (other is VersionRange) {
163 // If neither range has a minimum, they'll overlap at some point. 163 return !strictlyLower(other, this) && !strictlyHigher(other, this);
164 //
165 // ... this ]
166 // ... other ]
167 if (min == null && other.min == null) return true;
168
169 // If this range has a lower minimum than the other range, it overlaps as
170 // long as its maximum is higher than or the same as the other range's
171 // minimum.
172 //
173 // [ this ] [ this ]
174 // [ other ] [ other ]
175 if (min == null || (other.min != null && min < other.min)) {
176 if (max == null) return true;
177 if (max > other.min) return true;
178 if (max < other.min) return false;
179 assert(max == other.min);
180 return includeMax && other.includeMin;
181 }
182
183 // If this range has a higher minimum than the other range, it overlaps as
184 // long as its minimum is lower than or the same as the other range's
185 // maximum.
186 //
187 // [ this ] [ this ]
188 // [ other ] [ other ]
189 if (other.max == null) return true;
190 if (min < other.max) return true;
191 if (min > other.max) return false;
192 assert(min == other.max);
193 return includeMin && other.includeMax;
194 } 164 }
195 165
196 throw new ArgumentError('Unknown VersionConstraint type $other.'); 166 throw new ArgumentError('Unknown VersionConstraint type $other.');
197 } 167 }
198 168
199 VersionConstraint intersect(VersionConstraint other) { 169 VersionConstraint intersect(VersionConstraint other) {
200 if (other.isEmpty) return other; 170 if (other.isEmpty) return other;
201 if (other is VersionUnion) return other.intersect(this); 171 if (other is VersionUnion) return other.intersect(this);
202 172
203 // A range and a Version just yields the version if it's in the range. 173 // A range and a Version just yields the version if it's in the range.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 unionIncludeMax = true; 283 unionIncludeMax = true;
314 } 284 }
315 285
316 return new VersionRange(min: unionMin, max: unionMax, 286 return new VersionRange(min: unionMin, max: unionMax,
317 includeMin: unionIncludeMin, includeMax: unionIncludeMax); 287 includeMin: unionIncludeMin, includeMax: unionIncludeMax);
318 } 288 }
319 289
320 return new VersionConstraint.unionOf([this, other]); 290 return new VersionConstraint.unionOf([this, other]);
321 } 291 }
322 292
293 VersionConstraint difference(VersionConstraint other) {
294 if (other.isEmpty) return this;
295
296 if (other is Version) {
297 if (!allows(other)) return this;
298
299 if (other == min) {
300 if (!includeMin) return this;
301 return new VersionRange(
302 min: min, max: max,
303 includeMin: false, includeMax: includeMax);
304 }
305
306 if (other == max) {
307 if (!includeMax) return this;
308 return new VersionRange(
309 min: min, max: max,
310 includeMin: includeMin, includeMax: false);
311 }
312
313 return new VersionUnion.fromRanges([
314 new VersionRange(
315 min: min, max: other,
316 includeMin: includeMin, includeMax: false),
317 new VersionRange(
318 min: other, max: max,
319 includeMin: false, includeMax: includeMax)
320 ]);
321 } else if (other is VersionRange) {
322 if (!allowsAny(other)) return this;
323
324 VersionConstraint before;
325 if (!allowsLower(this, other)) {
326 before = VersionConstraint.empty;
327 } else if (min == other.min) {
328 assert(includeMin && !other.includeMin);
329 assert(min != null);
330 before = min;
331 } else {
332 before = new VersionRange(
333 min: min, max: other.min,
334 includeMin: includeMin, includeMax: !other.includeMin);
335 }
336
337 VersionConstraint after;
338 if (!allowsHigher(this, other)) {
339 after = VersionConstraint.empty;
340 } else if (max == other.max) {
341 assert(includeMax && !other.includeMax);
342 assert(max != null);
343 after = max;
344 } else {
345 after = new VersionRange(
346 min: other.max, max: max,
347 includeMin: !other.includeMax, includeMax: includeMax);
348 }
349
350 if (before == VersionConstraint.empty) return after;
351 if (after == VersionConstraint.empty) return before;
352 return new VersionUnion.fromRanges([before, after]);
353 } else if (other is VersionUnion) {
354 var ranges = <VersionRange>[];
355 var current = this;
356
357 for (var range in other.ranges) {
358 // Skip any ranges that are strictly lower than [current].
359 if (strictlyLower(range, current)) continue;
360
361 // If we reach a range strictly higher than [current], no more ranges
362 // will be relevant so we can bail early.
363 if (strictlyHigher(range, current)) break;
364
365 var difference = current.difference(range);
366 if (difference is VersionUnion) {
367 // If [range] split [current] in half, we only need to continue
368 // checking future ranges against the latter half.
369 assert(difference.ranges.length == 2);
370 ranges.add(difference.ranges.first);
371 current = difference.ranges.last;
372 } else {
373 current = difference as VersionRange;
374 }
375 }
376
377 if (ranges.isEmpty) return current;
378 return new VersionUnion.fromRanges(ranges..add(current));
379 }
380
381 throw new ArgumentError('Unknown VersionConstraint type $other.');
382 }
383
323 int compareTo(VersionRange other) { 384 int compareTo(VersionRange other) {
324 if (min == null) { 385 if (min == null) {
325 if (other.min == null) return compareMax(this, other); 386 if (other.min == null) return _compareMax(other);
326 return -1; 387 return -1;
327 } else if (other.min == null) { 388 } else if (other.min == null) {
328 return 1; 389 return 1;
329 } 390 }
330 391
331 var result = min.compareTo(other.min); 392 var result = min.compareTo(other.min);
332 if (result != 0) return result; 393 if (result != 0) return result;
333 if (includeMin != other.includeMin) return includeMin ? -1 : 1; 394 if (includeMin != other.includeMin) return includeMin ? -1 : 1;
334 395
335 return compareMax(this, other); 396 return _compareMax(other);
397 }
398
399 /// Compares the maximum values of [this] and [other].
400 int _compareMax(VersionRange other) {
401 if (max == null) {
402 if (other.max == null) return 0;
403 return 1;
404 } else if (other.max == null) {
405 return -1;
406 }
407
408 var result = max.compareTo(other.max);
409 if (result != 0) return result;
410 if (includeMax != other.includeMax) return includeMax ? 1 : -1;
411 return 0;
336 } 412 }
337 413
338 String toString() { 414 String toString() {
339 var buffer = new StringBuffer(); 415 var buffer = new StringBuffer();
340 416
341 if (min != null) { 417 if (min != null) {
342 buffer.write(includeMin ? '>=' : '>'); 418 buffer.write(includeMin ? '>=' : '>');
343 buffer.write(min); 419 buffer.write(min);
344 } 420 }
345 421
346 if (max != null) { 422 if (max != null) {
347 if (min != null) buffer.write(' '); 423 if (min != null) buffer.write(' ');
348 buffer.write(includeMax ? '<=' : '<'); 424 buffer.write(includeMax ? '<=' : '<');
349 buffer.write(max); 425 buffer.write(max);
350 } 426 }
351 427
352 if (min == null && max == null) buffer.write('any'); 428 if (min == null && max == null) buffer.write('any');
353 return buffer.toString(); 429 return buffer.toString();
354 } 430 }
355 } 431 }
OLDNEW
« no previous file with comments | « lib/src/version_constraint.dart ('k') | lib/src/version_union.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698