in Python/Product/VSInterpreters/PackageManager/PackageVersion.cs [202:309]
public int CompareTo(PackageVersion other) {
Exception error;
if (!Validate(out error)) {
throw error;
}
if (!other.Validate(out error)) {
throw new ArgumentException("Invalid version", "other", error);
}
int c = Epoch.CompareTo(other.Epoch);
if (c != 0) {
return c;
}
if (Release != null && other.Release != null) {
for (int i = 0; i < Release.Count || i < other.Release.Count; ++i) {
c = Release.ElementAtOrDefault(i).CompareTo(other.Release.ElementAtOrDefault(i));
if (c != 0) {
return c;
}
}
} else if (Release == null) {
// No release, so we sort earlier if other has one
return other.Release == null ? 0 : -1;
} else {
// We have a release and other doesn't, so we sort later
return 1;
}
if (PreReleaseName != other.PreReleaseName) {
// Regular comparison mishandles None
if (PreReleaseName == PackageVersionPreReleaseName.None) {
return 1;
} else if (other.PreReleaseName == PackageVersionPreReleaseName.None) {
return -1;
}
// Neither value is None, so CompareTo will be correct
return PreReleaseName.CompareTo(other.PreReleaseName);
}
c = PreRelease.CompareTo(other.PreRelease);
if (c != 0) {
return c;
}
c = PostRelease.CompareTo(other.PostRelease);
if (c != 0) {
return c;
}
c = DevRelease.CompareTo(other.DevRelease);
if (c != 0) {
if (DevRelease == 0 || other.DevRelease == 0) {
// When either DevRelease is zero, the sort order needs to
// be reversed.
return -c;
}
return c;
}
if (string.IsNullOrEmpty(LocalVersion)) {
if (string.IsNullOrEmpty(other.LocalVersion)) {
// No local versions, so we are equal
return 0;
}
// other has a local version, so we sort earlier
return -1;
} else if (string.IsNullOrEmpty(other.LocalVersion)) {
// we have a local version, so we sort later
return 1;
}
var lv1 = LocalVersion.Split('.');
var lv2 = other.LocalVersion.Split('.');
for (int i = 0; i < lv1.Length || i < lv2.Length; ++i) {
if (i >= lv1.Length) {
// other has a longer local version, so we sort earlier
return -1;
} else if (i >= lv2.Length) {
// we have a longer local version, so we sort later
return 1;
}
var p1 = lv1[i];
var p2 = lv2[i];
int i1, i2;
if (int.TryParse(p1, NumberStyles.Integer, CultureInfo.InvariantCulture, out i1)) {
if (int.TryParse(p2, NumberStyles.Integer, CultureInfo.InvariantCulture, out i2)) {
c = i1.CompareTo(i2);
} else {
// we have a number and other doesn't, so we sort later
return 1;
}
} else if (int.TryParse(p2, NumberStyles.Integer, CultureInfo.InvariantCulture, out i2)) {
// other has a number and we don't, so we sort earlier
return -1;
} else {
c = string.Compare(p1, p2, StringComparison.OrdinalIgnoreCase);
}
if (c != 0) {
return c;
}
}
// After all that, we are equal!
return 0;
}