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

Unified 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: Code review changes 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/version_constraint.dart ('k') | lib/src/version_union.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/version_range.dart
diff --git a/lib/src/version_range.dart b/lib/src/version_range.dart
index faffb4742335f9d207bc5a86a545a7b925a1405d..7a18edf0e83b71ea79ded95d08b7e0037b173f5f 100644
--- a/lib/src/version_range.dart
+++ b/lib/src/version_range.dart
@@ -6,6 +6,7 @@ library pub_semver.src.version_range;
import 'version.dart';
import 'version_constraint.dart';
+import 'version_union.dart';
/// Constrains versions to a fall within a given range.
///
@@ -99,8 +100,81 @@ class VersionRange implements VersionConstraint {
return true;
}
+ bool allowsAll(VersionConstraint other) {
+ if (other.isEmpty) return true;
+ if (other is Version) return allows(other);
+
+ if (other is VersionUnion) {
+ return other.constraints.every((constraint) => allowsAll(constraint));
+ }
+
+ if (other is VersionRange) {
+ if (min != null) {
+ if (other.min == null) return false;
+ if (min > other.min) return false;
+ if (min == other.min && !includeMin && other.includeMin) return false;
+ }
+
+ if (max != null) {
+ if (other.max == null) return false;
+ if (max < other.max) return false;
+ if (max == other.max && !includeMax && other.includeMax) return false;
+ }
+
+ return true;
+ }
+
+ throw new ArgumentError('Unknown VersionConstraint type $other.');
+ }
+
+ bool allowsAny(VersionConstraint other) {
+ if (other.isEmpty) return false;
+ if (other is Version) return allows(other);
+
+ if (other is VersionUnion) {
+ return other.constraints.any((constraint) => allowsAny(constraint));
+ }
+
+ 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 ]
Bob Nystrom 2015/05/06 17:30:58 <3 the art.
+ 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;
+ }
+
+ throw new ArgumentError('Unknown VersionConstraint type $other.');
+ }
+
VersionConstraint intersect(VersionConstraint other) {
if (other.isEmpty) return other;
+ if (other is VersionUnion) return other.intersect(this);
// A range and a Version just yields the version if it's in the range.
if (other is Version) {
@@ -162,6 +236,66 @@ class VersionRange implements VersionConstraint {
throw new ArgumentError('Unknown VersionConstraint type $other.');
}
+ VersionConstraint union(VersionConstraint other) {
+ if (other is Version) {
+ if (allows(other)) return this;
+
+ if (other == min) {
+ return new VersionRange(
+ min: this.min, max: this.max,
+ includeMin: true, includeMax: this.includeMax);
+ }
+
+ if (other == max) {
+ return new VersionRange(
+ min: this.min, max: this.max,
+ includeMin: this.includeMin, includeMax: true);
+ }
+
+ return new VersionConstraint.unionOf([this, other]);
+ }
+
+ if (other is VersionRange) {
+ // If the two ranges don't overlap, we won't be able to create a single
+ // VersionRange for both of them.
+ var edgesTouch = (max == other.min && (includeMax || other.includeMin)) ||
+ (min == other.max && (includeMin || other.includeMax));
+ if (!edgesTouch && !allowsAny(other)) {
+ return new VersionConstraint.unionOf([this, other]);
+ }
+
+ var unionMin = min;
+ var unionIncludeMin = includeMin;
+ var unionMax = max;
+ var unionIncludeMax = includeMax;
+
+ if (unionMin == null) {
+ // Do nothing.
+ } else if (other.min == null || other.min < min) {
+ unionMin = other.min;
+ unionIncludeMin = other.includeMin;
+ } else if (min == other.min && other.includeMin) {
+ // If the edges are the same but one is inclusive, make it inclusive.
+ unionIncludeMin = true;
+ }
+
+ if (unionMax == null) {
+ // Do nothing.
+ } else if (other.max == null || other.max > max) {
+ unionMax = other.max;
+ unionIncludeMax = other.includeMax;
+ } else if (max == other.max && other.includeMax) {
+ // If the edges are the same but one is inclusive, make it inclusive.
+ unionIncludeMax = true;
+ }
+
+ return new VersionRange(min: unionMin, max: unionMax,
+ includeMin: unionIncludeMin, includeMax: unionIncludeMax);
+ }
+
+ return new VersionConstraint.unionOf([this, other]);
+ }
+
String toString() {
var buffer = new StringBuffer();
« 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