Skip to content
Merged
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 @@ -116,11 +116,11 @@ public PlatformAvailability MergeWithParent (PlatformAvailability? parent)
// 1. If the parent has unsupported versions we will add them to the merge. If the kid has them, we will
// add them too
foreach (var (version, message) in parent.Value.unsupported) {
builder.AddUnsupportedVersion (version, message);
builder.AddUnsupportedVersion (new (version, SupportKind.Explicit), message);
}

foreach (var (version, message) in unsupported) {
builder.AddUnsupportedVersion (version, message);
builder.AddUnsupportedVersion (new (version, SupportKind.Explicit), message);
}

// 2. if supported in the platform, we will always pick the larges version between
Expand All @@ -130,7 +130,7 @@ public PlatformAvailability MergeWithParent (PlatformAvailability? parent)
? parent.Value.SupportedVersion
: SupportedVersion;
if (supportedVersion is not null)
builder.AddSupportedVersion (supportedVersion);
builder.AddSupportedVersion (new (supportedVersion, SupportKind.Explicit));

// similar to the unsupported versions, if the parent has obsolete ones, we will add them
foreach (var (version, obsoleteInfo) in parent.Value.obsoleted) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ readonly partial struct PlatformAvailability {
/// A writable PlatformAvailability accessor.
/// </summary>
public sealed class Builder {
static readonly PlatformSupportVersionComparer versionComparer = new ();
readonly ApplePlatform platform;
Version? supportedVersion;
readonly SortedDictionary<Version, string?> unsupported = new ();
PlatformSupportVersion? supportedVersion;
readonly SortedDictionary<PlatformSupportVersion, string?> unsupported = new (versionComparer);
readonly SortedDictionary<Version, (string? Message, string? Url)> obsoleted = new ();

/// <summary>
Expand All @@ -36,15 +37,16 @@ public sealed class Builder {
/// else the version is ignored.
/// </summary>
/// <param name="version">A new supported version.</param>
internal void AddSupportedVersion (Version version)
internal void AddSupportedVersion (PlatformSupportVersion version)
{
if (unsupported.ContainsKey (defaultVersion))
// platform is unsupported, do nothing
if (unsupported.ContainsKey (PlatformSupportVersion.ExplicitDefault))
// platform is explicitly unsupported, do nothing
return;

// update the supported version to the larges of the two
if (supportedVersion is null || version > supportedVersion)
supportedVersion = version;
supportedVersion = supportedVersion is null
? version
: PlatformSupportVersion.Max (version, supportedVersion.Value);
}

/// <summary>
Expand All @@ -57,32 +59,35 @@ public void Add (SupportedOSPlatformData supportedPlatform)
if (supportedPlatform.Platform != platform)
return;
// no version is present, therefore try to set the default one
AddSupportedVersion (supportedPlatform.Version);
AddSupportedVersion (new (supportedPlatform.Version, SupportKind.Explicit));
}

/// <summary>
/// Adds a new version to the list of unsupported versions. If the platform is unsupported, the version is ignored.
/// </summary>
/// <param name="version">The new unsupported version.</param>
/// <param name="message">The optional message of the unsupported version.</param>
internal void AddUnsupportedVersion (Version version, string? message)
internal void AddUnsupportedVersion (PlatformSupportVersion version, string? message)
{
// adding an unsupported version, due to the way the API is designed is more complicated. It can be
// that a selector/member is unsupported in more than one version, so we need to keep track of that
// the only time in which we make an exception is when we unsupported a platform (no version number)
// if that is the case, we will remove all unsupported versions and just un-support the platform
// ignore data from platforms that we do not care
if (version == defaultVersion) {
if (version == PlatformSupportVersion.ExplicitDefault) {
unsupported.Clear ();
unsupported [defaultVersion] = message;
unsupported [PlatformSupportVersion.ExplicitDefault] = message;
// we are unsupporting the platform! that means if we supported it or any version, that should be
// set back to null
supportedVersion = null;
} else {
// we have a version, that does not mean we do care about that data, first we want to check
// that we did not fully unsupported the platform, if that is the case, we ignore this version
if (unsupported.ContainsKey (defaultVersion))
if (unsupported.ContainsKey (PlatformSupportVersion.ExplicitDefault))
return;

// we implicitly unsupported the platform, remove that entry since we are adding a version
unsupported.Remove (PlatformSupportVersion.ImplicitDefault);
unsupported [version] = message;
}
}
Expand All @@ -95,7 +100,7 @@ public void Add (UnsupportedOSPlatformData unsupportedPlatform)
{
if (unsupportedPlatform.Platform != platform)
return;
AddUnsupportedVersion (unsupportedPlatform.Version, unsupportedPlatform.Message);
AddUnsupportedVersion (new (unsupportedPlatform.Version, SupportKind.Explicit), unsupportedPlatform.Message);
}


Expand Down Expand Up @@ -137,7 +142,11 @@ public void Add (ObsoletedOSPlatformData obsoletedPlatform)
/// <returns>A new readonly structure that contains the platform availability.</returns>
public PlatformAvailability ToImmutable ()
{
return new PlatformAvailability (platform, supportedVersion, unsupported, obsoleted);
var unsupportedCopy = new SortedDictionary<Version, string?> ();
foreach (var (version, message) in unsupported) {
unsupportedCopy.Add (version.Version, message);
}
return new PlatformAvailability (platform, supportedVersion?.Version, unsupportedCopy, obsoleted);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ public readonly record struct PlatformSupportVersion {
Kind = SupportKind.Explicit
};

/// <summary>
/// Initializes a new instance of the <see cref="PlatformSupportVersion"/> struct.
/// </summary>
/// <param name="version">The version number.</param>
/// <param name="kind">The kind of support.</param>
public PlatformSupportVersion (Version version, SupportKind kind)
{
Version = version;
Kind = kind;
}

/// <summary>
/// Initializes a new instance of the <see cref="PlatformSupportVersion"/> struct with an explicit support kind.
/// </summary>
/// <param name="version">The version number.</param>
public PlatformSupportVersion (Version version) : this (version, SupportKind.Explicit) { }

/// <summary>
/// Returns the platform support version with the highest precedence.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Collections.Generic;

namespace Microsoft.Macios.Generator.Availability;

/// <summary>
/// Compares two <see cref="PlatformSupportVersion"/> instances for sorting.
/// </summary>
public class PlatformSupportVersionComparer : IComparer<PlatformSupportVersion> {

/// <summary>
/// Compares two platform support versions and returns a value indicating whether one is less than, equal to, or greater than the other.
/// </summary>
/// <param name="x">The first object to compare.</param>
/// <param name="y">The second object to compare.</param>
/// <returns>A signed integer that indicates the relative values of x and y.</returns>
public int Compare (PlatformSupportVersion x, PlatformSupportVersion y)
{
int versionComparison = x.Version.CompareTo (y.Version);
if (versionComparison != 0) return versionComparison;
return x.Kind.CompareTo (y.Kind);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ internal void AddSupportedVersion (ApplePlatform platform, Version version)
if (!supportedPlatforms.Contains (platform))
return;
var builder = GetBuilder (platform);
builder.AddSupportedVersion (version);
builder.AddSupportedVersion (new (version, SupportKind.Explicit));
}

/// <summary>
Expand Down Expand Up @@ -118,7 +118,7 @@ internal void AddUnsupportedVersion (ApplePlatform platform, Version version, st
return;

var builder = GetBuilder (platform);
builder.AddUnsupportedVersion (version, message);
builder.AddUnsupportedVersion (new (version, SupportKind.Explicit), message);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public void EqualSamePlatformDifferentSupportedVersion ()
{
var leftBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.iOS);
var rightBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.TVOS);
leftBuilder.AddSupportedVersion (new Version (12, 0));
rightBuilder.AddSupportedVersion (new Version (10, 0));
leftBuilder.AddSupportedVersion (new (new Version (12, 0)));
rightBuilder.AddSupportedVersion (new (new Version (10, 0)));
var left = leftBuilder.ToImmutable ();
var right = rightBuilder.ToImmutable ();
Assert.False (left.Equals (right));
Expand All @@ -41,7 +41,7 @@ public void EqualsNullSupportedVersion ()
{
var leftBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.iOS);
var rightBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.TVOS);
leftBuilder.AddSupportedVersion (new Version (12, 0));
leftBuilder.AddSupportedVersion (new (new Version (12, 0)));
var left = leftBuilder.ToImmutable ();
var right = rightBuilder.ToImmutable ();
Assert.False (left.Equals (right));
Expand All @@ -55,9 +55,9 @@ public void EqualSamePlatformSameSupportedVersionDifferentUnsupportedVersion ()
{
var leftBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.iOS);
var rightBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.TVOS);
leftBuilder.AddSupportedVersion (new Version (12, 0));
leftBuilder.AddUnsupportedVersion (new Version (10, 0), "Unsupported");
rightBuilder.AddSupportedVersion (new Version (12, 0));
leftBuilder.AddSupportedVersion (new (new Version (12, 0)));
leftBuilder.AddUnsupportedVersion (new (new Version (10, 0)), "Unsupported");
rightBuilder.AddSupportedVersion (new (new Version (12, 0)));
var left = leftBuilder.ToImmutable ();
var right = rightBuilder.ToImmutable ();
Assert.False (left.Equals (right));
Expand All @@ -71,11 +71,11 @@ public void EqualsSamePlatformSamerSupportedVersionSameUnsupportedDiffObsolete (
{
var leftBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.iOS);
var rightBuilder = PlatformAvailability.CreateBuilder (ApplePlatform.TVOS);
leftBuilder.AddSupportedVersion (new Version (12, 0));
leftBuilder.AddUnsupportedVersion (new Version (10, 0), "Unsupported");
leftBuilder.AddSupportedVersion (new (new Version (12, 0)));
leftBuilder.AddUnsupportedVersion (new (new Version (10, 0)), "Unsupported");
leftBuilder.AddObsoletedVersion (new Version (12, 0), "Obsolete", null);
rightBuilder.AddSupportedVersion (new Version (12, 0));
rightBuilder.AddUnsupportedVersion (new Version (10, 0), "Unsupported");
rightBuilder.AddSupportedVersion (new (new Version (12, 0)));
rightBuilder.AddUnsupportedVersion (new (new Version (10, 0)), "Unsupported");
leftBuilder.AddObsoletedVersion (new Version (12, 0), "Obsolete", "url");
var left = leftBuilder.ToImmutable ();
var right = rightBuilder.ToImmutable ();
Expand Down
Loading