Migrate to null safety (#52)
- Switch to a major version bump.
- Reformat `.travis.yml`. Indent list elements to the same position as
the containing key. This matches yaml style in other Google files.
- Update SDK constraints to use the `2.11.0` dev SDKs.
- Renames some variables with noise word "the" to match the field name
and avoid the shadowing with `this.`.
- Add override for analyzer package.
Co-authored-by: Nate Bosch <nbosch1@gmail.com>
diff --git a/.travis.yml b/.travis.yml
index 0e732d0..e40520c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,23 +1,12 @@
language: dart
dart:
- - dev
- - 2.0.0
+- dev
dart_task:
- - test
-
-matrix:
- include:
- # Only validate formatting using the dev release
- - dart: dev
- dart_task: dartfmt
- - dart: dev
- dart_task:
- dartanalyzer: --fatal-warnings --fatal-hints .
- - dart: 2.0.0
- dart_task:
- dartanalyzer: --fatal-warnings .
+- test: -p vm,chrome
+- dart_task: dartfmt
+- dartanalyzer: --fatal-infos .
# Only building master means that we don't run two builds for each pull request.
branches:
@@ -25,4 +14,4 @@
cache:
directories:
- - $HOME/.pub-cache
+ - $HOME/.pub-cache
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 63f7285..3719707 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
-# 1.4.5-dev
+# 2.0.0-nullsafety.0
+
+- Migrate to null safety.
+- `Version.primary` now throws `StateError` if the `versions` argument is empty.
# 1.4.4
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 60617f2..a9f714f 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -19,7 +19,7 @@
if (range1.min == null) return range2.min != null;
if (range2.min == null) return false;
- var comparison = range1.min.compareTo(range2.min);
+ var comparison = range1.min!.compareTo(range2.min!);
if (comparison == -1) return true;
if (comparison == 1) return false;
return range1.includeMin && !range2.includeMin;
@@ -30,7 +30,7 @@
if (range1.max == null) return range2.max != null;
if (range2.max == null) return false;
- var comparison = range1.max.compareTo(range2.max);
+ var comparison = range1.max!.compareTo(range2.max!);
if (comparison == 1) return true;
if (comparison == -1) return false;
return range1.includeMax && !range2.includeMax;
@@ -41,7 +41,7 @@
bool strictlyLower(VersionRange range1, VersionRange range2) {
if (range1.max == null || range2.min == null) return false;
- var comparison = range1.max.compareTo(range2.min);
+ var comparison = range1.max!.compareTo(range2.min!);
if (comparison == -1) return true;
if (comparison == 1) return false;
return !range1.includeMax || !range2.includeMin;
diff --git a/lib/src/version.dart b/lib/src/version.dart
index 314937d..552b498 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -92,8 +92,8 @@
@override
bool get includeMax => true;
- Version._(this.major, this.minor, this.patch, String preRelease, String build,
- this._text)
+ Version._(this.major, this.minor, this.patch, String? preRelease,
+ String? build, this._text)
: preRelease = preRelease == null ? [] : _splitParts(preRelease),
build = build == null ? [] : _splitParts(build) {
if (major < 0) throw ArgumentError('Major version must be non-negative.');
@@ -102,7 +102,8 @@
}
/// Creates a new [Version] object.
- factory Version(int major, int minor, int patch, {String pre, String build}) {
+ factory Version(int major, int minor, int patch,
+ {String? pre, String? build}) {
var text = '$major.$minor.$patch';
if (pre != null) text += '-$pre';
if (build != null) text += '+$build';
@@ -118,9 +119,9 @@
}
try {
- var major = int.parse(match[1]);
- var minor = int.parse(match[2]);
- var patch = int.parse(match[3]);
+ var major = int.parse(match[1]!);
+ var minor = int.parse(match[2]!);
+ var patch = int.parse(match[3]!);
var preRelease = match[5];
var build = match[8];
@@ -136,12 +137,11 @@
/// This is the highest-numbered stable (non-prerelease) version. If there
/// are no stable versions, it's just the highest-numbered version.
///
- /// If [versions] is empty, returns `null`.
+ /// If [versions] is empty, throws a [StateError].
static Version primary(List<Version> versions) {
- Version primary;
- for (var version in versions) {
- if (primary == null ||
- (!version.isPreRelease && primary.isPreRelease) ||
+ var primary = versions.first;
+ for (var version in versions.skip(1)) {
+ if ((!version.isPreRelease && primary.isPreRelease) ||
(version.isPreRelease == primary.isPreRelease && version > primary)) {
primary = version;
}
diff --git a/lib/src/version_constraint.dart b/lib/src/version_constraint.dart
index ac39b6b..6eb6c3a 100644
--- a/lib/src/version_constraint.dart
+++ b/lib/src/version_constraint.dart
@@ -57,16 +57,16 @@
if (text == 'any') return any;
// Try to parse and consume a version number.
- Version matchVersion() {
+ Version? matchVersion() {
var version = startVersion.firstMatch(text);
if (version == null) return null;
text = text.substring(version.end);
- return Version.parse(version[0]);
+ return Version.parse(version[0]!);
}
// Try to parse and consume a comparison operator followed by a version.
- VersionRange matchComparison() {
+ VersionRange? matchComparison() {
var comparison = startComparison.firstMatch(text);
if (comparison == null) return null;
@@ -97,7 +97,7 @@
}
// Try to parse the "^" operator followed by a version.
- VersionConstraint matchCompatibleWith() {
+ VersionConstraint? matchCompatibleWith() {
if (!text.startsWith(compatibleWithChar)) return null;
text = text.substring(compatibleWithChar.length);
@@ -120,9 +120,9 @@
var compatibleWith = matchCompatibleWith();
if (compatibleWith != null) return compatibleWith;
- Version min;
+ Version? min;
var includeMin = false;
- Version max;
+ Version? max;
var includeMax = false;
for (;;) {
@@ -137,7 +137,7 @@
}
if (newRange.min != null) {
- if (min == null || newRange.min > min) {
+ if (min == null || newRange.min! > min) {
min = newRange.min;
includeMin = newRange.includeMin;
} else if (newRange.min == min && !newRange.includeMin) {
@@ -146,7 +146,7 @@
}
if (newRange.max != null) {
- if (max == null || newRange.max < max) {
+ if (max == null || newRange.max! < max) {
max = newRange.max;
includeMax = newRange.includeMax;
} else if (newRange.max == max && !newRange.includeMax) {
diff --git a/lib/src/version_range.dart b/lib/src/version_range.dart
index 78cd6d0..a2a6327 100644
--- a/lib/src/version_range.dart
+++ b/lib/src/version_range.dart
@@ -25,7 +25,7 @@
///
/// This may be `null` in which case the range has no minimum end and allows
/// any version less than the maximum.
- final Version min;
+ final Version? min;
/// The maximum end of the range.
///
@@ -35,7 +35,7 @@
///
/// This may be `null` in which case the range has no maximum end and allows
/// any version greater than the minimum.
- final Version max;
+ final Version? max;
/// If `true` then [min] is allowed by the range.
final bool includeMin;
@@ -58,8 +58,8 @@
/// pre-release versions of an exclusive [max]. Otherwise, it will use the
/// default behavior for pre-release versions of [max].
factory VersionRange(
- {Version min,
- Version max,
+ {Version? min,
+ Version? max,
bool includeMin = false,
bool includeMax = false,
bool alwaysIncludeMaxPreRelease = false}) {
@@ -111,12 +111,12 @@
@override
bool allows(Version other) {
if (min != null) {
- if (other < min) return false;
+ if (other < min!) return false;
if (!includeMin && other == min) return false;
}
if (max != null) {
- if (other > max) return false;
+ if (other > max!) return false;
if (!includeMax && other == max) return false;
}
@@ -167,7 +167,7 @@
if (other is VersionRange) {
// Intersect the two ranges.
- Version intersectMin;
+ Version? intersectMin;
bool intersectIncludeMin;
if (allowsLower(this, other)) {
if (strictlyLower(this, other)) return VersionConstraint.empty;
@@ -179,7 +179,7 @@
intersectIncludeMin = includeMin;
}
- Version intersectMax;
+ Version? intersectMax;
bool intersectIncludeMax;
if (allowsHigher(this, other)) {
intersectMax = other.max;
@@ -199,7 +199,7 @@
// Because we already verified that the lower range isn't strictly
// lower, there must be some overlap.
assert(intersectIncludeMin && intersectIncludeMax);
- return intersectMin;
+ return intersectMin!;
}
// If we got here, there is an actual range.
@@ -251,7 +251,7 @@
return VersionConstraint.unionOf([this, other]);
}
- Version unionMin;
+ Version? unionMin;
bool unionIncludeMin;
if (allowsLower(this, other)) {
unionMin = min;
@@ -261,7 +261,7 @@
unionIncludeMin = other.includeMin;
}
- Version unionMax;
+ Version? unionMax;
bool unionIncludeMax;
if (allowsHigher(this, other)) {
unionMax = max;
@@ -326,7 +326,7 @@
} else if (other is VersionRange) {
if (!allowsAny(other)) return this;
- VersionRange before;
+ VersionRange? before;
if (!allowsLower(this, other)) {
before = null;
} else if (min == other.min) {
@@ -342,7 +342,7 @@
alwaysIncludeMaxPreRelease: true);
}
- VersionRange after;
+ VersionRange? after;
if (!allowsHigher(this, other)) {
after = null;
} else if (max == other.max) {
@@ -359,7 +359,7 @@
}
if (before == null && after == null) return VersionConstraint.empty;
- if (before == null) return after;
+ if (before == null) return after!;
if (after == null) return before;
return VersionUnion.fromRanges([before, after]);
} else if (other is VersionUnion) {
@@ -404,7 +404,7 @@
return 1;
}
- var result = min.compareTo(other.min);
+ var result = min!.compareTo(other.min!);
if (result != 0) return result;
if (includeMin != other.includeMin) return includeMin ? -1 : 1;
@@ -420,7 +420,7 @@
return -1;
}
- var result = max.compareTo(other.max);
+ var result = max!.compareTo(other.max!);
if (result != 0) return result;
if (includeMax != other.includeMax) return includeMax ? 1 : -1;
return 0;
@@ -430,10 +430,13 @@
String toString() {
var buffer = StringBuffer();
+ final min = this.min;
if (min != null) {
buffer..write(includeMin ? '>=' : '>')..write(min);
}
+ final max = this.max;
+
if (max != null) {
if (min != null) buffer.write(' ');
if (includeMax) {
diff --git a/lib/src/version_union.dart b/lib/src/version_union.dart
index 8a23522..24b82f4 100644
--- a/lib/src/version_union.dart
+++ b/lib/src/version_union.dart
@@ -50,19 +50,19 @@
// Because both lists of ranges are ordered by minimum version, we can
// safely move through them linearly here.
- ourRanges.moveNext();
- theirRanges.moveNext();
- while (ourRanges.current != null && theirRanges.current != null) {
+ var ourRangesMoved = ourRanges.moveNext();
+ var theirRangesMoved = theirRanges.moveNext();
+ while (ourRangesMoved && theirRangesMoved) {
if (ourRanges.current.allowsAll(theirRanges.current)) {
- theirRanges.moveNext();
+ theirRangesMoved = theirRanges.moveNext();
} else {
- ourRanges.moveNext();
+ ourRangesMoved = ourRanges.moveNext();
}
}
// If our ranges have allowed all of their ranges, we'll have consumed all
// of them.
- return theirRanges.current == null;
+ return !theirRangesMoved;
}
@override
@@ -72,9 +72,9 @@
// Because both lists of ranges are ordered by minimum version, we can
// safely move through them linearly here.
- ourRanges.moveNext();
- theirRanges.moveNext();
- while (ourRanges.current != null && theirRanges.current != null) {
+ var ourRangesMoved = ourRanges.moveNext();
+ var theirRangesMoved = theirRanges.moveNext();
+ while (ourRangesMoved && theirRangesMoved) {
if (ourRanges.current.allowsAny(theirRanges.current)) {
return true;
}
@@ -82,9 +82,9 @@
// Move the constraint with the lower max value forward. This ensures that
// we keep both lists in sync as much as possible.
if (allowsHigher(theirRanges.current, ourRanges.current)) {
- ourRanges.moveNext();
+ ourRangesMoved = ourRanges.moveNext();
} else {
- theirRanges.moveNext();
+ theirRangesMoved = theirRanges.moveNext();
}
}
@@ -99,9 +99,9 @@
// Because both lists of ranges are ordered by minimum version, we can
// safely move through them linearly here.
var newRanges = <VersionRange>[];
- ourRanges.moveNext();
- theirRanges.moveNext();
- while (ourRanges.current != null && theirRanges.current != null) {
+ var ourRangesMoved = ourRanges.moveNext();
+ var theirRangesMoved = theirRanges.moveNext();
+ while (ourRangesMoved && theirRangesMoved) {
var intersection = ourRanges.current.intersect(theirRanges.current);
if (!intersection.isEmpty) newRanges.add(intersection as VersionRange);
@@ -110,9 +110,9 @@
// we keep both lists in sync as much as possible, and that large ranges
// have a chance to match multiple small ranges that they contain.
if (allowsHigher(theirRanges.current, ourRanges.current)) {
- ourRanges.moveNext();
+ ourRangesMoved = ourRanges.moveNext();
} else {
- theirRanges.moveNext();
+ theirRangesMoved = theirRanges.moveNext();
}
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 78de107..dc2d6ac 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,16 +1,18 @@
name: pub_semver
-version: 1.4.5-dev
-
+version: 2.0.0-nullsafety.0
description: >-
Versions and version constraints implementing pub's versioning policy. This
is very similar to vanilla semver, with a few corner cases.
-homepage: https://github.com/dart-lang/pub_semver
+repository: https://github.com/dart-lang/pub_semver
environment:
- sdk: '>=2.0.0 <3.0.0'
+ sdk: '>=2.12.0-0 <3.0.0'
dependencies:
- collection: ^1.0.0
+ collection: ^1.15.0-nullsafety.2
dev_dependencies:
- test: ^1.0.0
+ test: ^1.16.0-nullsafety.1
+
+dependency_overrides:
+ analyzer: any
diff --git a/test/utils.dart b/test/utils.dart
index eb3358a..595415a 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -79,13 +79,13 @@
/// Gets a [Matcher] that validates that a [VersionConstraint] allows all
/// given versions.
Matcher allows(Version v1,
- [Version v2,
- Version v3,
- Version v4,
- Version v5,
- Version v6,
- Version v7,
- Version v8]) {
+ [Version? v2,
+ Version? v3,
+ Version? v4,
+ Version? v5,
+ Version? v6,
+ Version? v7,
+ Version? v8]) {
var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8);
return _VersionConstraintMatcher(versions, true);
}
@@ -93,25 +93,25 @@
/// Gets a [Matcher] that validates that a [VersionConstraint] allows none of
/// the given versions.
Matcher doesNotAllow(Version v1,
- [Version v2,
- Version v3,
- Version v4,
- Version v5,
- Version v6,
- Version v7,
- Version v8]) {
+ [Version? v2,
+ Version? v3,
+ Version? v4,
+ Version? v5,
+ Version? v6,
+ Version? v7,
+ Version? v8]) {
var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8);
return _VersionConstraintMatcher(versions, false);
}
List<Version> _makeVersionList(Version v1,
- [Version v2,
- Version v3,
- Version v4,
- Version v5,
- Version v6,
- Version v7,
- Version v8]) {
+ [Version? v2,
+ Version? v3,
+ Version? v4,
+ Version? v5,
+ Version? v6,
+ Version? v7,
+ Version? v8]) {
var versions = [v1];
if (v2 != null) versions.add(v2);
if (v3 != null) versions.add(v3);
diff --git a/test/version_test.dart b/test/version_test.dart
index 70d2779..6ff4b3e 100644
--- a/test/version_test.dart
+++ b/test/version_test.dart
@@ -371,10 +371,7 @@
});
test('empty', () {
- expect(
- _primary([]),
- isNull,
- );
+ expect(() => Version.primary([]), throwsStateError);
});
});
}