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