| Index: lib/src/version_range.dart
|
| diff --git a/lib/src/version_range.dart b/lib/src/version_range.dart
|
| index a8d60698f8d594c9cf9747a509a4a3618af2314a..ffa50ab6b7b55d141d6de2d161ce21475e6208a3 100644
|
| --- a/lib/src/version_range.dart
|
| +++ b/lib/src/version_range.dart
|
| @@ -160,37 +160,7 @@ class VersionRange implements Comparable<VersionRange>, VersionConstraint {
|
| }
|
|
|
| if (other is VersionRange) {
|
| - // If neither range has a minimum, they'll overlap at some point.
|
| - //
|
| - // ... this ]
|
| - // ... other ]
|
| - if (min == null && other.min == null) return true;
|
| -
|
| - // If this range has a lower minimum than the other range, it overlaps as
|
| - // long as its maximum is higher than or the same as the other range's
|
| - // minimum.
|
| - //
|
| - // [ this ] [ this ]
|
| - // [ other ] [ other ]
|
| - if (min == null || (other.min != null && min < other.min)) {
|
| - if (max == null) return true;
|
| - if (max > other.min) return true;
|
| - if (max < other.min) return false;
|
| - assert(max == other.min);
|
| - return includeMax && other.includeMin;
|
| - }
|
| -
|
| - // If this range has a higher minimum than the other range, it overlaps as
|
| - // long as its minimum is lower than or the same as the other range's
|
| - // maximum.
|
| - //
|
| - // [ this ] [ this ]
|
| - // [ other ] [ other ]
|
| - if (other.max == null) return true;
|
| - if (min < other.max) return true;
|
| - if (min > other.max) return false;
|
| - assert(min == other.max);
|
| - return includeMin && other.includeMax;
|
| + return !strictlyLower(other, this) && !strictlyHigher(other, this);
|
| }
|
|
|
| throw new ArgumentError('Unknown VersionConstraint type $other.');
|
| @@ -320,9 +290,100 @@ class VersionRange implements Comparable<VersionRange>, VersionConstraint {
|
| return new VersionConstraint.unionOf([this, other]);
|
| }
|
|
|
| + VersionConstraint difference(VersionConstraint other) {
|
| + if (other.isEmpty) return this;
|
| +
|
| + if (other is Version) {
|
| + if (!allows(other)) return this;
|
| +
|
| + if (other == min) {
|
| + if (!includeMin) return this;
|
| + return new VersionRange(
|
| + min: min, max: max,
|
| + includeMin: false, includeMax: includeMax);
|
| + }
|
| +
|
| + if (other == max) {
|
| + if (!includeMax) return this;
|
| + return new VersionRange(
|
| + min: min, max: max,
|
| + includeMin: includeMin, includeMax: false);
|
| + }
|
| +
|
| + return new VersionUnion.fromRanges([
|
| + new VersionRange(
|
| + min: min, max: other,
|
| + includeMin: includeMin, includeMax: false),
|
| + new VersionRange(
|
| + min: other, max: max,
|
| + includeMin: false, includeMax: includeMax)
|
| + ]);
|
| + } else if (other is VersionRange) {
|
| + if (!allowsAny(other)) return this;
|
| +
|
| + VersionConstraint before;
|
| + if (!allowsLower(this, other)) {
|
| + before = VersionConstraint.empty;
|
| + } else if (min == other.min) {
|
| + assert(includeMin && !other.includeMin);
|
| + assert(min != null);
|
| + before = min;
|
| + } else {
|
| + before = new VersionRange(
|
| + min: min, max: other.min,
|
| + includeMin: includeMin, includeMax: !other.includeMin);
|
| + }
|
| +
|
| + VersionConstraint after;
|
| + if (!allowsHigher(this, other)) {
|
| + after = VersionConstraint.empty;
|
| + } else if (max == other.max) {
|
| + assert(includeMax && !other.includeMax);
|
| + assert(max != null);
|
| + after = max;
|
| + } else {
|
| + after = new VersionRange(
|
| + min: other.max, max: max,
|
| + includeMin: !other.includeMax, includeMax: includeMax);
|
| + }
|
| +
|
| + if (before == VersionConstraint.empty) return after;
|
| + if (after == VersionConstraint.empty) return before;
|
| + return new VersionUnion.fromRanges([before, after]);
|
| + } else if (other is VersionUnion) {
|
| + var ranges = <VersionRange>[];
|
| + var current = this;
|
| +
|
| + for (var range in other.ranges) {
|
| + // Skip any ranges that are strictly lower than [current].
|
| + if (strictlyLower(range, current)) continue;
|
| +
|
| + // If we reach a range strictly higher than [current], no more ranges
|
| + // will be relevant so we can bail early.
|
| + if (strictlyHigher(range, current)) break;
|
| +
|
| + var difference = current.difference(range);
|
| + if (difference is VersionUnion) {
|
| + // If [range] split [current] in half, we only need to continue
|
| + // checking future ranges against the latter half.
|
| + assert(difference.ranges.length == 2);
|
| + ranges.add(difference.ranges.first);
|
| + current = difference.ranges.last;
|
| + } else {
|
| + current = difference as VersionRange;
|
| + }
|
| + }
|
| +
|
| + if (ranges.isEmpty) return current;
|
| + return new VersionUnion.fromRanges(ranges..add(current));
|
| + }
|
| +
|
| + throw new ArgumentError('Unknown VersionConstraint type $other.');
|
| + }
|
| +
|
| int compareTo(VersionRange other) {
|
| if (min == null) {
|
| - if (other.min == null) return compareMax(this, other);
|
| + if (other.min == null) return _compareMax(other);
|
| return -1;
|
| } else if (other.min == null) {
|
| return 1;
|
| @@ -332,7 +393,22 @@ class VersionRange implements Comparable<VersionRange>, VersionConstraint {
|
| if (result != 0) return result;
|
| if (includeMin != other.includeMin) return includeMin ? -1 : 1;
|
|
|
| - return compareMax(this, other);
|
| + return _compareMax(other);
|
| + }
|
| +
|
| + /// Compares the maximum values of [this] and [other].
|
| + int _compareMax(VersionRange other) {
|
| + if (max == null) {
|
| + if (other.max == null) return 0;
|
| + return 1;
|
| + } else if (other.max == null) {
|
| + return -1;
|
| + }
|
| +
|
| + var result = max.compareTo(other.max);
|
| + if (result != 0) return result;
|
| + if (includeMax != other.includeMax) return includeMax ? 1 : -1;
|
| + return 0;
|
| }
|
|
|
| String toString() {
|
|
|