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 |