| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 'package:collection/collection.dart'; | 5 import 'package:collection/collection.dart'; |
| 6 | 6 |
| 7 import 'utils.dart'; | 7 import 'utils.dart'; |
| 8 import 'version.dart'; | 8 import 'version.dart'; |
| 9 import 'version_constraint.dart'; | 9 import 'version_constraint.dart'; |
| 10 import 'version_range.dart'; | 10 import 'version_range.dart'; |
| 11 | 11 |
| 12 /// A version constraint representing a union of multiple disjoint version | 12 /// A version constraint representing a union of multiple disjoint version |
| 13 /// ranges. | 13 /// ranges. |
| 14 /// | 14 /// |
| 15 /// An instance of this will only be created if the version can't be represented | 15 /// An instance of this will only be created if the version can't be represented |
| 16 /// as a non-compound value. | 16 /// as a non-compound value. |
| 17 class VersionUnion implements VersionConstraint { | 17 class VersionUnion implements VersionConstraint { |
| 18 /// The constraints that compose this union. | 18 /// The constraints that compose this union. |
| 19 /// | 19 /// |
| 20 /// This list has two invariants: | 20 /// This list has two invariants: |
| 21 /// | 21 /// |
| 22 /// * Its contents are sorted from lowest to highest matched versions. | 22 /// * Its contents are sorted using the standard ordering of [VersionRange]s. |
| 23 /// * Its contents are disjoint and non-adjacent. In other words, for any two | 23 /// * Its contents are disjoint and non-adjacent. In other words, for any two |
| 24 /// constraints next to each other in the list, there's some version between | 24 /// constraints next to each other in the list, there's some version between |
| 25 /// those constraints that they don't match. | 25 /// those constraints that they don't match. |
| 26 final List<VersionRange> ranges; | 26 final List<VersionRange> ranges; |
| 27 | 27 |
| 28 bool get isEmpty => false; | 28 bool get isEmpty => false; |
| 29 | 29 |
| 30 bool get isAny => false; | 30 bool get isAny => false; |
| 31 | 31 |
| 32 /// Creates a union from a list of ranges with no pre-processing. | 32 /// Creates a union from a list of ranges with no pre-processing. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 | 67 |
| 68 // Because both lists of ranges are ordered by minimum version, we can | 68 // Because both lists of ranges are ordered by minimum version, we can |
| 69 // safely move through them linearly here. | 69 // safely move through them linearly here. |
| 70 ourRanges.moveNext(); | 70 ourRanges.moveNext(); |
| 71 theirRanges.moveNext(); | 71 theirRanges.moveNext(); |
| 72 while (ourRanges.current != null && theirRanges.current != null) { | 72 while (ourRanges.current != null && theirRanges.current != null) { |
| 73 if (ourRanges.current.allowsAny(theirRanges.current)) { | 73 if (ourRanges.current.allowsAny(theirRanges.current)) { |
| 74 return true; | 74 return true; |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Move the constraint with the higher max value forward. This ensures | 77 // Move the constraint with the lower max value forward. This ensures that |
| 78 // that we keep both lists in sync as much as possible. | 78 // we keep both lists in sync as much as possible. |
| 79 if (compareMax(ourRanges.current, theirRanges.current) < 0) { | 79 if (compareMax(ourRanges.current, theirRanges.current) < 0) { |
| 80 ourRanges.moveNext(); | 80 ourRanges.moveNext(); |
| 81 } else { | 81 } else { |
| 82 theirRanges.moveNext(); | 82 theirRanges.moveNext(); |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 | 85 |
| 86 return false; | 86 return false; |
| 87 } | 87 } |
| 88 | 88 |
| 89 VersionConstraint intersect(VersionConstraint other) { | 89 VersionConstraint intersect(VersionConstraint other) { |
| 90 var ourRanges = ranges.iterator; | 90 var ourRanges = ranges.iterator; |
| 91 var theirRanges = _rangesFor(other).iterator; | 91 var theirRanges = _rangesFor(other).iterator; |
| 92 | 92 |
| 93 // Because both lists of ranges are ordered by minimum version, we can | 93 // Because both lists of ranges are ordered by minimum version, we can |
| 94 // safely move through them linearly here. | 94 // safely move through them linearly here. |
| 95 var newRanges = <VersionRange>[]; | 95 var newRanges = <VersionRange>[]; |
| 96 ourRanges.moveNext(); | 96 ourRanges.moveNext(); |
| 97 theirRanges.moveNext(); | 97 theirRanges.moveNext(); |
| 98 while (ourRanges.current != null && theirRanges.current != null) { | 98 while (ourRanges.current != null && theirRanges.current != null) { |
| 99 var intersection = ourRanges.current | 99 var intersection = ourRanges.current |
| 100 .intersect(theirRanges.current); | 100 .intersect(theirRanges.current); |
| 101 | 101 |
| 102 if (!intersection.isEmpty) newRanges.add(intersection); | 102 if (!intersection.isEmpty) newRanges.add(intersection); |
| 103 | 103 |
| 104 // Move the constraint with the higher max value forward. This ensures | 104 // Move the constraint with the lower max value forward. This ensures that |
| 105 // that we keep both lists in sync as much as possible, and that large | 105 // we keep both lists in sync as much as possible, and that large ranges |
| 106 // ranges have a chance to match multiple small ranges that they contain. | 106 // have a chance to match multiple small ranges that they contain. |
| 107 if (compareMax(ourRanges.current, theirRanges.current) < 0) { | 107 if (compareMax(ourRanges.current, theirRanges.current) < 0) { |
| 108 ourRanges.moveNext(); | 108 ourRanges.moveNext(); |
| 109 } else { | 109 } else { |
| 110 theirRanges.moveNext(); | 110 theirRanges.moveNext(); |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 | 113 |
| 114 if (newRanges.isEmpty) return VersionConstraint.empty; | 114 if (newRanges.isEmpty) return VersionConstraint.empty; |
| 115 if (newRanges.length == 1) return newRanges.single; | 115 if (newRanges.length == 1) return newRanges.single; |
| 116 | 116 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 132 | 132 |
| 133 bool operator ==(other) { | 133 bool operator ==(other) { |
| 134 if (other is! VersionUnion) return false; | 134 if (other is! VersionUnion) return false; |
| 135 return const ListEquality().equals(ranges, other.ranges); | 135 return const ListEquality().equals(ranges, other.ranges); |
| 136 } | 136 } |
| 137 | 137 |
| 138 int get hashCode => const ListEquality().hash(ranges); | 138 int get hashCode => const ListEquality().hash(ranges); |
| 139 | 139 |
| 140 String toString() => ranges.join(" or "); | 140 String toString() => ranges.join(" or "); |
| 141 } | 141 } |
| OLD | NEW |