Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |