Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add OSPlatform.macOS, make OSPlatform.Equal use OrdinalIgnoreCaseComparison #39064

Closed
wants to merge 11 commits into from
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ public enum Architecture
public static System.Runtime.InteropServices.OSPlatform Browser { get { throw null; } }
public static System.Runtime.InteropServices.OSPlatform FreeBSD { get { throw null; } }
public static System.Runtime.InteropServices.OSPlatform iOS { get { throw null; } }
public static System.Runtime.InteropServices.OSPlatform macOS { get { throw null; } }
public static System.Runtime.InteropServices.OSPlatform Linux { get { throw null; } }
public static System.Runtime.InteropServices.OSPlatform OSX { get { throw null; } }
public static System.Runtime.InteropServices.OSPlatform tvOS { get { throw null; } }
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.ComponentModel;

namespace System.Runtime.InteropServices
{
public readonly struct OSPlatform : IEquatable<OSPlatform>
@@ -15,7 +17,10 @@ namespace System.Runtime.InteropServices

public static OSPlatform Linux { get; } = new OSPlatform("LINUX");

public static OSPlatform OSX { get; } = new OSPlatform("OSX");
public static OSPlatform macOS { get; } = new OSPlatform("MACOS");

[EditorBrowsable(EditorBrowsableState.Never)] // https://github.com/dotnet/runtime/issues/33331#issuecomment-650326500
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this link really useful for context? It points to several screens of API review notes, and it does not say much useful about the OSX.

Should this rather say "// superseded by macOS" ?

public static OSPlatform OSX { get; } = macOS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example

void Foo (OSPlatform osp)
{
	if (osp.ToString() == "OSX")
		return;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, then we should add the macOS/OSX magic to ToString() too

Copy link
Member

@jkotas jkotas Jul 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we should be changing the string identifier for OSX/macOS. It should stay as OSX. OSX is hardcoded in many places that are hard/impossible to fix, like NuGet RIDs. We are not gaining much by changing it ad-hoc in subset of places. If we want to change it, it should be done everywhere and it should be a feature on its own.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this during the Design Review meeting today and got a direction on how to address this breaking change risk while still handling equivalence. The comments are posted on #33331, but at a high-level, OSPlatform should not try to handle equivalence between platforms itself; instead, the RuntimeInformation.IsOSPlatform should handle it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static OSPlatform OSX { get; } = macOS;
public static OSPlatform OSX => macOS;


public static OSPlatform iOS { get; } = new OSPlatform("IOS");

@@ -30,7 +35,7 @@ private OSPlatform(string osPlatform)
if (osPlatform == null) throw new ArgumentNullException(nameof(osPlatform));
if (osPlatform.Length == 0) throw new ArgumentException(SR.Argument_EmptyValue, nameof(osPlatform));

_osPlatform = osPlatform;
_osPlatform = osPlatform.Equals("OSX", StringComparison.OrdinalIgnoreCase) ? "MACOS" : osPlatform;
}

public static OSPlatform Create(string osPlatform)
@@ -40,17 +45,12 @@ public static OSPlatform Create(string osPlatform)

public bool Equals(OSPlatform other)
{
return Equals(other._osPlatform);
}

internal bool Equals(string? other)
{
return string.Equals(_osPlatform, other, StringComparison.Ordinal);
return string.Equals(_osPlatform, other._osPlatform, StringComparison.OrdinalIgnoreCase);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is motivating this change? This will make this API quite a bit more expensive.

}

public override bool Equals(object? obj)
{
return obj is OSPlatform && Equals((OSPlatform)obj);
return obj is OSPlatform osPlatform && Equals(osPlatform);
}

public override int GetHashCode()
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;
using Xunit;

namespace System.Runtime.InteropServices.RuntimeInformationTests
@@ -13,10 +12,10 @@ public void CheckLinux()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("LINUX")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("linux")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("linux")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
@@ -25,15 +24,20 @@ public void CheckLinux()
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.watchOS));
}

[Fact, PlatformSpecific(TestPlatforms.NetBSD)] // Tests RuntimeInformation OS platform
public void CheckNetBSD()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("LINUX")));
@@ -44,32 +48,60 @@ public void CheckNetBSD()
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.watchOS));
}

[Fact, PlatformSpecific(TestPlatforms.OSX)] // Tests RuntimeInformation OS platform
public void CheckOSX()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("osx")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("macos")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("OSX")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("osx")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("mac")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("MACOSX")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.watchOS));
}

[Fact, PlatformSpecific(TestPlatforms.Android)]
public void CheckAndroid()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Android));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Browser));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.watchOS));
}

[Fact, PlatformSpecific(TestPlatforms.iOS)] // Tests RuntimeInformation OS platform
public void CheckiOS()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("iOS")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
@@ -82,13 +114,17 @@ public void CheckiOS()
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
}

[Fact, PlatformSpecific(TestPlatforms.tvOS)] // Tests RuntimeInformation OS platform
public void ChecktvOS()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("TVOS")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("tvOS")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
@@ -101,26 +137,11 @@ public void ChecktvOS()
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
}

[Fact, PlatformSpecific(TestPlatforms.Android)] // Tests RuntimeInformation OS platform
public void CheckAndroid()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("osx")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("mac")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("MACOSX")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
}

[Fact, PlatformSpecific(TestPlatforms.Browser)] // Tests RuntimeInformation OS platform
public void CheckBrowser()
@@ -139,30 +160,40 @@ public void CheckBrowser()
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
}

[Fact, PlatformSpecific(TestPlatforms.Windows)] // Tests RuntimeInformation OS platform
public void CheckWindows()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("WINDOWS")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("windows")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("NetBSD")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("netbsd")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("windows")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("Windows NT")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.watchOS));

}

[Fact, PlatformSpecific(TestPlatforms.FreeBSD)] // Tests RuntimeInformation OS platform
public void CheckFreeBSD()
{
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("FREEBSD")));
Assert.True(RuntimeInformation.IsOSPlatform(OSPlatform.Create("freebsd")));

Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("DARWIN")));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Create("LINUX")));
@@ -173,6 +204,11 @@ public void CheckFreeBSD()
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.OSX));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.macOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.iOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.tvOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.watchOS));
Assert.False(RuntimeInformation.IsOSPlatform(OSPlatform.Android));
}

[Fact]
@@ -213,5 +249,26 @@ public void CheckOSPlatform()
Assert.Equal(0, defaultObj.GetHashCode());
Assert.Equal(defaultObj.GetHashCode(), conObj.GetHashCode());
}

[Fact]
public void PlatformNamesAreComparedUsingOrdinalIgnoreCase()
{
Assert.Equal(OSPlatform.Create("ab"), OSPlatform.Create("ab"));
Assert.Equal(OSPlatform.Create("AB"), OSPlatform.Create("AB"));
Assert.Equal(OSPlatform.Create("AB"), OSPlatform.Create("ab"));
Assert.Equal(OSPlatform.Create("aB"), OSPlatform.Create("Ab"));
}

[Fact]
public void OSX_equals_macOS()
{
Assert.Equal(OSPlatform.OSX, OSPlatform.macOS);
Assert.Equal(OSPlatform.OSX, OSPlatform.Create("macOS"));
Assert.Equal(OSPlatform.Create("OSX"), OSPlatform.macOS);
Assert.Equal(OSPlatform.Create("OSX"), OSPlatform.Create("macOS"));
Assert.Equal(OSPlatform.Create("osx"), OSPlatform.Create("macOS"));
Assert.Equal(OSPlatform.Create("osx"), OSPlatform.Create("macos"));
Assert.Equal(OSPlatform.Create("OSX"), OSPlatform.Create("macos"));
}
}
}