difference method
override
Returns a VersionConstraint that allows Versions allowed by this but
not other
.
Implementation
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,
alwaysIncludeMaxPreRelease: true);
}
if (other == max) {
if (!includeMax) return this;
return new VersionRange(
min: min,
max: max,
includeMin: includeMin,
includeMax: false,
alwaysIncludeMaxPreRelease: true);
}
return new VersionUnion.fromRanges([
new VersionRange(
min: min,
max: other,
includeMin: includeMin,
includeMax: false,
alwaysIncludeMaxPreRelease: true),
new VersionRange(
min: other,
max: max,
includeMin: false,
includeMax: includeMax,
alwaysIncludeMaxPreRelease: true)
]);
} else if (other is VersionRange) {
if (!allowsAny(other)) return this;
VersionRange before;
if (!allowsLower(this, other)) {
before = null;
} 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,
alwaysIncludeMaxPreRelease: true);
}
VersionRange after;
if (!allowsHigher(this, other)) {
after = null;
} 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,
alwaysIncludeMaxPreRelease: true);
}
if (before == null && after == null) return VersionConstraint.empty;
if (before == null) return after;
if (after == null) 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.isEmpty) {
return VersionConstraint.empty;
} else 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.');
}