Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ namespace Microsoft.Macios.Generator.Availability;
/// The supported version of the platform. If null, that means that the user did not add a SupportedOSPlatform
/// attribute.
/// </summary>
public Version? SupportedVersion { get; }
public PlatformSupportVersion? SupportedVersion { get; }

readonly SortedDictionary<Version, string?> unsupported = new ();
readonly SortedDictionary<PlatformSupportVersion, string?> unsupported = new ();

/// <summary>
/// Dictionary that contains all the obsoleted versions and their optional data.
/// </summary>
public IReadOnlyDictionary<Version, string?> UnsupportedVersions => unsupported;
public IReadOnlyDictionary<PlatformSupportVersion, string?> UnsupportedVersions => unsupported;

readonly SortedDictionary<Version, (string? Message, string? Url)> obsoleted = new ();

Expand All @@ -53,21 +53,21 @@ public bool IsSupported {
// a platform is supported if:
// 1. The supported version is not null, either the default version or a specific one
// 2. The default version is not in the unsupported list
return SupportedVersion is not null && !unsupported.ContainsKey (defaultVersion);
return SupportedVersion is not null
&& !unsupported.ContainsKey (PlatformSupportVersion.ImplicitDefault)
&& !unsupported.ContainsKey (PlatformSupportVersion.ExplicitDefault);
}
}


/// <summary>
/// Returns if a version is the default version.
/// </summary>
/// <param name="version">Version being tested.</param>
/// <returns>True if the version is default.</returns>
public static bool IsDefaultVersion (Version version) => version == defaultVersion;


PlatformAvailability (ApplePlatform platform, Version? supportedVersion,
SortedDictionary<Version, string?> unsupportedVersions,
PlatformAvailability (ApplePlatform platform, PlatformSupportVersion? supportedVersion,
SortedDictionary<PlatformSupportVersion, string?> unsupportedVersions,
SortedDictionary<Version, (string? Message, string? Url)> obsoletedVersions)
{
Platform = platform;
Expand Down Expand Up @@ -126,11 +126,9 @@ public PlatformAvailability MergeWithParent (PlatformAvailability? parent)
// 2. if supported in the platform, we will always pick the larges version between
// the two. Now, because we might be unsupported

var supportedVersion = (parent.Value.SupportedVersion > SupportedVersion)
? parent.Value.SupportedVersion
: SupportedVersion;
var supportedVersion = PlatformSupportVersion.Max (parent.Value.SupportedVersion, SupportedVersion);
if (supportedVersion is not null)
builder.AddSupportedVersion (new (supportedVersion, SupportKind.Explicit));
builder.AddSupportedVersion (supportedVersion.Value);

// similar to the unsupported versions, if the parent has obsolete ones, we will add them
foreach (var (version, obsoleteInfo) in parent.Value.obsoleted) {
Expand All @@ -148,7 +146,7 @@ public PlatformAvailability MergeWithParent (PlatformAvailability? parent)
public bool Equals (PlatformAvailability other)
{
var obsoleteComparer = new DictionaryComparer<Version, (string?, string?)> ();
var unsupportedComparer = new DictionaryComparer<Version, string?> ();
var unsupportedComparer = new DictionaryComparer<PlatformSupportVersion, string?> ();

var x = Equals (SupportedVersion, other.SupportedVersion);
return Platform == other.Platform &&
Expand Down Expand Up @@ -184,9 +182,9 @@ public override string ToString ()
{
var sb = new StringBuilder ("{ ");
sb.Append ($"Platform: '{Platform}', ");
sb.Append ($"Supported: '{SupportedVersion?.ToString ()}', ");
sb.Append ($"Supported: '{SupportedVersion?.Version.ToString ()}', ");
sb.Append ("Unsupported: [");
sb.AppendJoin (", ", unsupported.Select (v => $"'{v.Key}': '{v.Value?.ToString () ?? "null"}'"));
sb.AppendJoin (", ", unsupported.Select (v => $"'{v.Key.Version}': '{v.Value?.ToString () ?? "null"}'"));
sb.Append ("], Obsoleted: [");
sb.AppendJoin (", ", obsoleted.Select (v => $"'{v.Key}': ('{v.Value.Message?.ToString () ?? "null"}', '{v.Value.Url?.ToString () ?? "null"}')"));
sb.Append ("] }");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Microsoft.Macios.Generator.Availability;
/// <summary>
/// Represents a platform support version, combining a version number and a support kind.
/// </summary>
public readonly record struct PlatformSupportVersion {
public readonly record struct PlatformSupportVersion : IComparable<PlatformSupportVersion> {

/// <summary>
/// Gets the version number.
/// </summary>
Expand Down Expand Up @@ -60,12 +61,17 @@ public PlatformSupportVersion (Version version) : this (version, SupportKind.Exp
/// The platform support version with the highest precedence. If the kinds are the same, it returns the one with the greater version.
/// If the kinds are different, it returns the one with the higher kind value.
/// </returns>
public static PlatformSupportVersion Max (PlatformSupportVersion v1, PlatformSupportVersion v2)
public static PlatformSupportVersion? Max (PlatformSupportVersion? v1, PlatformSupportVersion? v2)
{
if (v1.Kind == v2.Kind) {
return v1.Version >= v2.Version ? v1 : v2;
if (v1 is null)
return v2;
if (v2 is null)
return v1;

if (v1.Value.Kind == v2.Value.Kind) {
return v1.Value.Version >= v2.Value.Version ? v1 : v2;
}
return (int) v1.Kind > (int) v2.Kind ? v1 : v2;
return (int) v1.Value.Kind > (int) v2.Value.Kind ? v1 : v2;
}

/// <summary>
Expand All @@ -77,11 +83,68 @@ public static PlatformSupportVersion Max (PlatformSupportVersion v1, PlatformSup
/// The platform support version with the lowest version if the kinds are the same.
/// If the kinds are different, it returns the one with the higher kind value.
/// </returns>
public static PlatformSupportVersion Min (PlatformSupportVersion v1, PlatformSupportVersion v2)
public static PlatformSupportVersion? Min (PlatformSupportVersion? v1, PlatformSupportVersion? v2)
{
if (v1.Kind == v2.Kind) {
return v1.Version <= v2.Version ? v1 : v2;
if (v1 is null)
return v2;
if (v2 is null)
return v1;
if (v1.Value.Kind == v2.Value.Kind) {
return v1.Value.Version <= v2.Value.Version ? v1 : v2;
}
return (int) v1.Kind > (int) v2.Kind ? v1 : v2;
return (int) v1.Value.Kind > (int) v2.Value.Kind ? v1 : v2;
}

/// <inheritdoc />
public int CompareTo (PlatformSupportVersion other)
{
var versionComparison = Version.CompareTo (other.Version);
if (versionComparison != 0)
return versionComparison;
return Kind.CompareTo (other.Kind);
}

/// <summary>
/// Compares two <see cref="PlatformSupportVersion"/> instances to determine if the left is less than the right.
/// </summary>
/// <param name="left">The first <see cref="PlatformSupportVersion"/> to compare.</param>
/// <param name="right">The second <see cref="PlatformSupportVersion"/> to compare.</param>
/// <returns><c>true</c> if the left instance is less than the right instance; otherwise, <c>false</c>.</returns>
public static bool operator < (PlatformSupportVersion left, PlatformSupportVersion right)
{
return left.CompareTo (right) < 0;
}

/// <summary>
/// Compares two <see cref="PlatformSupportVersion"/> instances to determine if the left is greater than the right.
/// </summary>
/// <param name="left">The first <see cref="PlatformSupportVersion"/> to compare.</param>
/// <param name="right">The second <see cref="PlatformSupportVersion"/> to compare.</param>
/// <returns><c>true</c> if the left instance is greater than the right instance; otherwise, <c>false</c>.</returns>
public static bool operator > (PlatformSupportVersion left, PlatformSupportVersion right)
{
return left.CompareTo (right) > 0;
}

/// <summary>
/// Compares two <see cref="PlatformSupportVersion"/> instances to determine if the left is less than or equal to the right.
/// </summary>
/// <param name="left">The first <see cref="PlatformSupportVersion"/> to compare.</param>
/// <param name="right">The second <see cref="PlatformSupportVersion"/> to compare.</param>
/// <returns><c>true</c> if the left instance is less than or equal to the right instance; otherwise, <c>false</c>.</returns>
public static bool operator <= (PlatformSupportVersion left, PlatformSupportVersion right)
{
return left.CompareTo (right) <= 0;
}

/// <summary>
/// Compares two <see cref="PlatformSupportVersion"/> instances to determine if the left is greater than or equal to the right.
/// </summary>
/// <param name="left">The first <see cref="PlatformSupportVersion"/> to compare.</param>
/// <param name="right">The second <see cref="PlatformSupportVersion"/> to compare.</param>
/// <returns><c>true</c> if the left instance is greater than or equal to the right instance; otherwise, <c>false</c>.</returns>
public static bool operator >= (PlatformSupportVersion left, PlatformSupportVersion right)
{
return left.CompareTo (right) >= 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ public static TabbedWriter<StringWriter> AppendMemberAvailability (this TabbedWr
foreach (var availability in allPlatformsAvailability.PlatformAvailabilities) {
var platformName = availability.Platform.AsString ().ToLower ();
if (availability.SupportedVersion is not null) {
var versionStr = (PlatformAvailability.IsDefaultVersion (availability.SupportedVersion))
var versionStr = (PlatformAvailability.IsDefaultVersion (availability.SupportedVersion.Value.Version))
? string.Empty
: availability.SupportedVersion.ToString ();
: availability.SupportedVersion.Value.Version.ToString ();
self.WriteLine ($"[SupportedOSPlatform (\"{platformName}{versionStr}\")]");
}

// loop over the unsupported versions of the platform
foreach (var (version, message) in availability.UnsupportedVersions) {
var versionStr = (PlatformAvailability.IsDefaultVersion (version)) ? string.Empty : version.ToString ();
var versionStr = (PlatformAvailability.IsDefaultVersion (version.Version)) ? string.Empty : version.Version.ToString ();
if (message is null) {
self.WriteLine ($"[UnsupportedOSPlatform (\"{platformName}{versionStr}\")]");
} else {
Expand Down Expand Up @@ -61,15 +61,15 @@ public static async Task<TabbedWriter<StreamWriter>> AppendMemberAvailabilityAsy
foreach (var availability in allPlatformsAvailability.PlatformAvailabilities) {
var platformName = availability.Platform.AsString ().ToLower ();
if (availability.SupportedVersion is not null) {
var versionStr = (PlatformAvailability.IsDefaultVersion (availability.SupportedVersion))
var versionStr = (PlatformAvailability.IsDefaultVersion (availability.SupportedVersion.Value.Version))
? string.Empty
: availability.SupportedVersion.ToString ();
: availability.SupportedVersion.Value.Version.ToString ();
await self.WriteLineAsync ($"[SupportedOSPlatform (\"{platformName}{versionStr}\")]");
}

// loop over the unsupported versions of the platform
foreach (var (version, message) in availability.UnsupportedVersions) {
var versionStr = (PlatformAvailability.IsDefaultVersion (version)) ? string.Empty : version.ToString ();
var versionStr = (PlatformAvailability.IsDefaultVersion (version.Version)) ? string.Empty : version.Version.ToString ();
if (message is null) {
await self.WriteLineAsync ($"[UnsupportedOSPlatform (\"{platformName}{versionStr}\")]");
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public void SupportPlatform (ApplePlatform platform, string attributePlatformNam
var attrData = new SupportedOSPlatformData (attributePlatformName);
builder.Add (attrData);
var availability = builder.ToImmutable ();
Assert.Equal (availability.SupportedVersion, new Version ());
Assert.NotNull (availability.SupportedVersion);
Assert.Equal (availability.SupportedVersion.Value.Version, new Version ());
}

[Theory]
Expand Down Expand Up @@ -52,7 +53,8 @@ public void SupportPlatformWithPlatformAttributeWithVersion (ApplePlatform platf
builder.Add (attrData);
var expectedVersion = Version.Parse (version);
var availability = builder.ToImmutable ();
Assert.Equal (expectedVersion, availability.SupportedVersion);
Assert.NotNull (availability.SupportedVersion);
Assert.Equal (expectedVersion, availability.SupportedVersion.Value.Version);
}

[Theory]
Expand All @@ -73,7 +75,8 @@ public void SupportPlatformAndThenAddHigherVersion (ApplePlatform platform, stri
var expectedVersion = Version.Parse (version);
// should be most specific version
var availability = builder.ToImmutable ();
Assert.Equal (expectedVersion, availability.SupportedVersion);
Assert.NotNull (availability.SupportedVersion);
Assert.Equal (expectedVersion, availability.SupportedVersion.Value.Version);
}

[Theory]
Expand All @@ -94,7 +97,8 @@ public void SupportPlatformSeveralVersionsPickHigherVersion (ApplePlatform platf

var expected = Version.Parse (expectedVersion);
var availability = builder.ToImmutable ();
Assert.Equal (expected, availability.SupportedVersion);
Assert.NotNull (availability.SupportedVersion);
Assert.Equal (expected, availability.SupportedVersion.Value.Version);
}

[Theory]
Expand All @@ -107,11 +111,10 @@ public void UnsupportPlatform (ApplePlatform platform, string attributePlatformN
var builder = PlatformAvailability.CreateBuilder (platform);
var attrData = new UnsupportedOSPlatformData (attributePlatformName);
builder.Add (attrData);
var defaultVersion = new Version ();
var availability = builder.ToImmutable ();
Assert.Contains (defaultVersion, availability.UnsupportedVersions.Keys);
Assert.Contains (PlatformSupportVersion.ExplicitDefault, availability.UnsupportedVersions.Keys);
Assert.Single (availability.UnsupportedVersions);
Assert.Null (availability.UnsupportedVersions [defaultVersion]);
Assert.Null (availability.UnsupportedVersions [PlatformSupportVersion.ExplicitDefault]);
}

[Theory]
Expand All @@ -124,11 +127,10 @@ public void UnsupportPlatformWithMessage (ApplePlatform platform, string attribu
var builder = PlatformAvailability.CreateBuilder (platform);
var attrData = new UnsupportedOSPlatformData (attributePlatformName, message);
builder.Add (attrData);
var defaultVersion = new Version ();
var availability = builder.ToImmutable ();
Assert.Contains (defaultVersion, availability.UnsupportedVersions.Keys);
Assert.Contains (PlatformSupportVersion.ExplicitDefault, availability.UnsupportedVersions.Keys);
Assert.Single (availability.UnsupportedVersions);
Assert.Equal (message, availability.UnsupportedVersions [defaultVersion]);
Assert.Equal (message, availability.UnsupportedVersions [PlatformSupportVersion.ExplicitDefault]);
}

[Theory]
Expand All @@ -145,11 +147,10 @@ public void UnsupportVersionAndPlatform (ApplePlatform platform, string attribut
var platformAttrData = new UnsupportedOSPlatformData (platform.AsString ().ToLower (), message);
builder.Add (versionAttrData);
builder.Add (platformAttrData);
var defaultVersion = new Version ();
var availability = builder.ToImmutable ();
Assert.Contains (defaultVersion, availability.UnsupportedVersions.Keys);
Assert.Contains (PlatformSupportVersion.ExplicitDefault, availability.UnsupportedVersions.Keys);
Assert.Single (availability.UnsupportedVersions);
Assert.Equal (message, availability.UnsupportedVersions [defaultVersion]);
Assert.Equal (message, availability.UnsupportedVersions [PlatformSupportVersion.ExplicitDefault]);
}

[Theory]
Expand Down Expand Up @@ -182,8 +183,8 @@ public void SupportAndUnsupportPlatform (ApplePlatform platform, string? message
var availability = builder.ToImmutable ();
Assert.Null (availability.SupportedVersion);
Assert.Single (availability.UnsupportedVersions);
Assert.Contains (new Version (), availability.UnsupportedVersions.Keys);
Assert.Equal (message, availability.UnsupportedVersions [new Version ()]);
Assert.Contains (PlatformSupportVersion.ExplicitDefault, availability.UnsupportedVersions.Keys);
Assert.Equal (message, availability.UnsupportedVersions [PlatformSupportVersion.ExplicitDefault]);
}

[Theory]
Expand Down Expand Up @@ -213,8 +214,8 @@ public void UnsupportSeveralVersionAndPlatform (ApplePlatform platform, string [

var availability = builder.ToImmutable ();
Assert.Single (availability.UnsupportedVersions);
Assert.Contains (new Version (), availability.UnsupportedVersions.Keys);
Assert.Equal (message, availability.UnsupportedVersions [new Version ()]);
Assert.Contains (PlatformSupportVersion.ExplicitDefault, availability.UnsupportedVersions.Keys);
Assert.Equal (message, availability.UnsupportedVersions [PlatformSupportVersion.ExplicitDefault]);
}

[Theory]
Expand All @@ -239,10 +240,13 @@ public void UnsupportedSeveralVersions (ApplePlatform platform, string [] versio
}

var availability = builder.ToImmutable ();
// get all the versions we added
var unsupported = availability.UnsupportedVersions.Keys
.Select (x => x.Version).ToArray ();
// assert that the version is present
foreach (var v in versions) {
var currentVersion = Version.Parse (v);
Assert.Contains (currentVersion, availability.UnsupportedVersions.Keys);
Assert.Contains (currentVersion, unsupported);
}
}

Expand Down
Loading