From a434970d9dba0b9f8fda231e4158811e73878c8d Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Fri, 17 Jul 2020 19:54:08 -0700 Subject: [PATCH 1/9] Add spec for platform exclusion --- .../platform-exclusion/platform-exclusion.md | 217 ++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 accepted/2020/platform-exclusion/platform-exclusion.md diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md new file mode 100644 index 000000000..d1eed399f --- /dev/null +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -0,0 +1,217 @@ +# Annotating APIs as unsupported on specific platforms + +**PM** [Immo Landwerth](https://github.com/terrajobst) + +For .NET 5, we're building a feature which [annotates platform-specific +APIs][platform-checks]. The goal is to provide warnings when developers +accidentally call platform-specific APIs, thus limiting their ability to run on +multiple platforms, or if the code might run on earlier platform that doesn't +support the called API yet. + +This feature made the following assumption: + +* An unmarked API is considered to work on all OS platforms. +* An API marked with `[MinimumOSPlatform("...")]` is considered only portable to + the specified OS platforms (please note that the attribute can be applied + multiple times). + +This approach works well for cases where the API is really calling an +OS-specific API. Good examples include the Windows Registry or Apple-specific +graphic APIs. This is very different from browser support for specific HTML and +CSS features: those generally aren't browser specific, which is why browser +checks never worked well for the web. But for OS specific APIs, asking whether +you're actually running on that OS is very workable. The only fragile aspect +here is getting the version number right, but the analyzer enforces that. + +However, this approach doesn't work well for APIs that represent concepts that +aren't OS specific, such as threading or I/O. This is a problem for OS platforms +that are more constrained, such as Blazor Web Assembly, which runs in a browser +sandbox and thus can't freely create threads or open random files on disk. + +One could, in principle, apply the `[MinimumOSPlatform("...")]` attribute for +all other OS platforms that do support them, but this has several downsides: + +1. The so marked APIs are now considered platform-specific, which means that + just calling the API from portable code will now always be flagged by the + analyzer. +2. Every time .NET adds another operating system all call sides guarding calls + to these APIs now also have to check for this new OS. + +In this spec, we're proposing a mechanism by which we can mark APIs as +unsupported. + +## Scenarios and User Experience + +* Building a Blazor Web Assembly app + - Using an API that is unsupported will be flagged by the analyzer. +* Building a class library + - Building a regular class library (targeting `netstandard` or `net5.0`) + will not complain about APIs that are unsupported in Blazor. +* Building a class library for use in Blazor Web Assembly + - Developer can modify the project file to explicitly indicate that they + want to see issues with APIs that are unsupported in Blazor. + +## Requirements + +### Goals + +* Be able to mark APIs that are unsupported on a particular OS +* Allows platforms to be considered supported by default with the ability to add + or remove platforms from the project file and SDK. +* Blazor Web Assembly is only considered supported when building a Blazor Web + Assembly app. For regular class libraries (`netstandard` or `net5.0`) the + default assumes that it's not supported and thus won't generate any warnings. + However, the developer must still be able to manually include Blazor Web + Assembly manually. +* The annotations for unsupported APIs can express that an API was only + unsupported for a specific version. + +### Non-Goals + +## Design + +### Attribute + +```C# +namespace System.Runtime.Versioning +{ + // Rename RemovedInOSPlatformAttribute to + // UnsupportedOSPlatformAttribute + [AttributeUsage(AttributeTargets.Assembly | + AttributeTargets.Class | + AttributeTargets.Constructor | + AttributeTargets.Event | + AttributeTargets.Method | + AttributeTargets.Module | + AttributeTargets.Property | + AttributeTargets.Struct, + AllowMultiple=true, Inherited=false)] + public sealed class UnsupportedOSPlatformAttribute : OSPlatformAttribute + { + public UnsupportedOSPlatformAttribute(string platformName); + } +``` + +The semantics of this attribute are as follows: + +* Marks an assembly, module, or API as unsupported on a given OS platform. +* The `platformName` can contain no version number, a single version number, or + a range: + - `browser`. Marks the API as unsupported on all version of `browser`. This + will be used for APIs that can't be supported on a particular OS platform. + - `ios14.0`. Marks the API as unsupported starting with iOS 14.0. This will + be used for OS platform APIs that were removed/disabled. + - `windows0.0-10.0.19041`. Marks the API as unsupported for 10.0.19041 and + earlier. This will be used for APIs that were unsupported before but can + be supported starting with a later version of the OS. This is different + from applying `[MinimumOSPlatform("windows10.0.19041")]` in that the + presence of this attribute doesn't cause the API to be considered + unsupported on other platforms. + +### Analyzer behavior + +The existing analyzer that handles `[MinimumOSPlatform]` will be modified to +handle `[UnsupportedOSPlatform]` (previously named `[RemovedInOSPlatform]`) +with the semantics listed above. + +Let's look at a few examples of annotations what the corresponding guard clauses +are that would prevent the analyzer from flagging usage of the API. + +```C# +// The API is supported everywhere except when running in a browser +[UnsupportedOSPlatform("browser")] +public extern void Api(); + +public void Api_Usage() +{ + if (!RuntimeInformation.IsOSPlatform("browser")) + { + Api(); + } +} +``` + +```C# +// On Windows, the API was unsupported up to and including version 10.0.19041. +// The API is considered supported everywhere else without constraints. +[UnsupportedOSPlatform("windows0.0-10.0.19041")] +public extern void Api(); + +public void Api_Usage() +{ + if (!RuntimeInformation.IsOSPlatformOrEarlier("windows10.0.19041")) + { + Api(); + } +} +``` + +```C# +// The API is only supported on iOS. There, it started to be supported in +// version 12.0 and stopped being supported in version 14. +[MinimumOSPlatform("iOS12.0")] +[UnsupportedOSPlatform("ios14.0")] +public extern void Api(); + +public void Api_Usage() +{ + if (RuntimeInformation.IsOSPlatformOrLater("iOS12.0") && + RuntimeInformation.IsOSPlatformOrEarlier("ios14.0")) + { + Api(); + } +} +``` + +### Hardcoded APIs in the analyzer + +### Build configuration for platforms + +In order to indicate which platforms the analyzer should by warn about, we're +adding some metadata to MSBuild: + +```XML + + + + + + + +``` + +The targets of the Blazor Web Assembly SDK would initialize this as follows: + +```XML + + + + +``` + +These items needs to be passed to invocation of CSC the analyzer configuration. +AFAIK they only supported properties today, but we can have a target that +converts these items into a semicolon separated list of platforms. + +Using items instead of a property makes it easier for the developer to add or +remove from the set: + +When building a class library that is also supposed to also work in Blazor Web Assembly, +a developer can add the following to their project file: + +```XML + + + +``` + +This design also enables library developers to suppress warnings for platforms +that are normally supported by default: + +```XML + + + +``` + +[platform-checks]: ../platform-check/platform-checks.md From 873a02192126686c32d7f7e7685c8185eafe09bd Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Tue, 21 Jul 2020 17:28:06 -0700 Subject: [PATCH 2/9] Apply Jeff's feedback --- accepted/2020/platform-exclusion/platform-exclusion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index d1eed399f..1bda232c3 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -34,7 +34,7 @@ all other OS platforms that do support them, but this has several downsides: 1. The so marked APIs are now considered platform-specific, which means that just calling the API from portable code will now always be flagged by the analyzer. -2. Every time .NET adds another operating system all call sides guarding calls +2. Every time .NET adds another operating system all call sites guarding calls to these APIs now also have to check for this new OS. In this spec, we're proposing a mechanism by which we can mark APIs as From c1a259c6d0373cc0b2b883c9fca6ee1e4b376a50 Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Tue, 21 Jul 2020 17:28:23 -0700 Subject: [PATCH 3/9] Replace Web Assembly with WebAssembly --- .../platform-exclusion/platform-exclusion.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index 1bda232c3..746902930 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -25,7 +25,7 @@ here is getting the version number right, but the analyzer enforces that. However, this approach doesn't work well for APIs that represent concepts that aren't OS specific, such as threading or I/O. This is a problem for OS platforms -that are more constrained, such as Blazor Web Assembly, which runs in a browser +that are more constrained, such as Blazor WebAssembly, which runs in a browser sandbox and thus can't freely create threads or open random files on disk. One could, in principle, apply the `[MinimumOSPlatform("...")]` attribute for @@ -42,12 +42,12 @@ unsupported. ## Scenarios and User Experience -* Building a Blazor Web Assembly app +* Building a Blazor WebAssembly app - Using an API that is unsupported will be flagged by the analyzer. * Building a class library - Building a regular class library (targeting `netstandard` or `net5.0`) will not complain about APIs that are unsupported in Blazor. -* Building a class library for use in Blazor Web Assembly +* Building a class library for use in Blazor WebAssembly - Developer can modify the project file to explicitly indicate that they want to see issues with APIs that are unsupported in Blazor. @@ -58,11 +58,11 @@ unsupported. * Be able to mark APIs that are unsupported on a particular OS * Allows platforms to be considered supported by default with the ability to add or remove platforms from the project file and SDK. -* Blazor Web Assembly is only considered supported when building a Blazor Web - Assembly app. For regular class libraries (`netstandard` or `net5.0`) the +* Blazor WebAssembly is only considered supported when building a Blazor + WebAssembly app. For regular class libraries (`netstandard` or `net5.0`) the default assumes that it's not supported and thus won't generate any warnings. - However, the developer must still be able to manually include Blazor Web - Assembly manually. + However, the developer must still be able to manually include Blazor + WebAssembly manually. * The annotations for unsupported APIs can express that an API was only unsupported for a specific version. @@ -180,7 +180,7 @@ adding some metadata to MSBuild: ``` -The targets of the Blazor Web Assembly SDK would initialize this as follows: +The targets of the Blazor WebAssembly SDK would initialize this as follows: ```XML @@ -196,8 +196,8 @@ converts these items into a semicolon separated list of platforms. Using items instead of a property makes it easier for the developer to add or remove from the set: -When building a class library that is also supposed to also work in Blazor Web Assembly, -a developer can add the following to their project file: +When building a class library that is also supposed to also work in Blazor +WebAssembly, a developer can add the following to their project file: ```XML From d44ff81d15f577110872a00a7dcfa17acab057fe Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Tue, 21 Jul 2020 17:35:29 -0700 Subject: [PATCH 4/9] Address Alexander's feedback --- accepted/2020/platform-exclusion/platform-exclusion.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index 746902930..8f108fd72 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -167,7 +167,7 @@ public void Api_Usage() ### Build configuration for platforms -In order to indicate which platforms the analyzer should by warn about, we're +In order to indicate which platforms the analyzer should warn about, we're adding some metadata to MSBuild: ```XML @@ -189,15 +189,15 @@ The targets of the Blazor WebAssembly SDK would initialize this as follows: ``` -These items needs to be passed to invocation of CSC the analyzer configuration. -AFAIK they only supported properties today, but we can have a target that +These items needs to be passed to the invocation CSC as analyzer configuration. +AFAIK the only supported properties today, but we can have a target that converts these items into a semicolon separated list of platforms. Using items instead of a property makes it easier for the developer to add or remove from the set: -When building a class library that is also supposed to also work in Blazor -WebAssembly, a developer can add the following to their project file: +When building a class library that is supposed to also work in the browser, a +developer can add the following to their project file: ```XML From 930970e2d07a54da51afe6d1f2ecb9dd840fd1c9 Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Mon, 27 Jul 2020 18:53:39 -0700 Subject: [PATCH 5/9] Update spec to unify the [MinimumOSPlatform] and [UnsupportedOSPlatform] --- .../platform-exclusion/platform-exclusion.md | 232 +++++++++++++++--- 1 file changed, 193 insertions(+), 39 deletions(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index 8f108fd72..433d7d611 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -42,14 +42,44 @@ unsupported. ## Scenarios and User Experience -* Building a Blazor WebAssembly app - - Using an API that is unsupported will be flagged by the analyzer. -* Building a class library - - Building a regular class library (targeting `netstandard` or `net5.0`) - will not complain about APIs that are unsupported in Blazor. -* Building a class library for use in Blazor WebAssembly - - Developer can modify the project file to explicitly indicate that they - want to see issues with APIs that are unsupported in Blazor. +### Building a Blazor WebAssembly app + +Abelina is building a Blazor WebAssembly app. She's copy & pasting some code +from here ASP.NET Core web app that calls into an LDAP service using +`System.DirectoryServices.Protocols`. + +When doing so, she receives the following warning: + +> "LdapConnection" isn't supported for platform "browser" + +After doing some further reading Abelina decided to put the LDAP functionality +behind a web API that she calls from her Blazor WebAssembly app. + +### Building a class library + +Darrell works with Abelina and is tasked with moving some of the LDAP +functionality into a .NET Standard class library so that they can share the code +between their .NET Framework desktop app and their ASP.NET Core web API. + +When he compiles the class library he gets no warnings about unsupported Blazor +APIs. + +### Building a class library for use in Blazor WebAssembly + +Abelina and Darrel decide to centralize some of the functionality they use for +Razor views, specifically around URI and string processing. + +When consuming this library from Blazor WebAssembly they observe a +`PlatformNotSupported` exception. Upon further analysis, it seems they had a +dependency on `System.Drawing` that they weren't aware off. To avoid this, they +decide to enable the analyzer to check for APIs that are unsupported when +running inside a browser: + +```xml + + + +``` ## Requirements @@ -58,61 +88,169 @@ unsupported. * Be able to mark APIs that are unsupported on a particular OS * Allows platforms to be considered supported by default with the ability to add or remove platforms from the project file and SDK. -* Blazor WebAssembly is only considered supported when building a Blazor - WebAssembly app. For regular class libraries (`netstandard` or `net5.0`) the - default assumes that it's not supported and thus won't generate any warnings. - However, the developer must still be able to manually include Blazor +* By default, Blazor WebAssembly is only considered supported when building a + Blazor WebAssembly app. For regular class libraries (`netstandard` or + `net5.0`) the default assumes that it's not supported and thus won't generate + any warnings. However, the developer must still be able to include Blazor WebAssembly manually. * The annotations for unsupported APIs can express that an API was only unsupported for a specific version. ### Non-Goals +* Allowing to express that APIs are unsupported in specific versions of the .NET + platform. + ## Design ### Attribute +The spec for [platform-checks] propose a set of attributes, specifically: + +* `MinimumOSPlatform` +* `ObsoletedInOSPlatform` +* `RemovedInOSPlatform` + +We suggest to rename `MinimumOSPlatform` to `SupportedOSPlatform` and +`RemovedInOSPlatform` to `UnsupportedOSPlatform`. + ```C# namespace System.Runtime.Versioning { - // Rename RemovedInOSPlatformAttribute to - // UnsupportedOSPlatformAttribute [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Constructor | + AttributeTargets.Enum | + AttributeTargets.Event | + AttributeTargets.Field | + AttributeTargets.Method | + AttributeTargets.Module | + AttributeTargets.Property | + AttributeTargets.Struct, + AllowMultiple = true, Inherited = false)] + public sealed class SupportedOSPlatformAttribute : OSPlatformAttribute + { + public SupportedOSPlatformAttribute(string platformName); + } + + [AttributeUsage(AttributeTargets.Assembly | + AttributeTargets.Class | + AttributeTargets.Constructor | + AttributeTargets.Enum | AttributeTargets.Event | + AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Module | AttributeTargets.Property | AttributeTargets.Struct, - AllowMultiple=true, Inherited=false)] + AllowMultiple = true, Inherited = false)] public sealed class UnsupportedOSPlatformAttribute : OSPlatformAttribute { public UnsupportedOSPlatformAttribute(string platformName); } +} ``` -The semantics of this attribute are as follows: - -* Marks an assembly, module, or API as unsupported on a given OS platform. -* The `platformName` can contain no version number, a single version number, or - a range: - - `browser`. Marks the API as unsupported on all version of `browser`. This - will be used for APIs that can't be supported on a particular OS platform. - - `ios14.0`. Marks the API as unsupported starting with iOS 14.0. This will - be used for OS platform APIs that were removed/disabled. - - `windows0.0-10.0.19041`. Marks the API as unsupported for 10.0.19041 and - earlier. This will be used for APIs that were unsupported before but can - be supported starting with a later version of the OS. This is different - from applying `[MinimumOSPlatform("windows10.0.19041")]` in that the - presence of this attribute doesn't cause the API to be considered - unsupported on other platforms. +The semantics of these new attributes are as follows: + +* An API that doesn't have any of these attributes is considered supported by + all platforms. +* If either `[SupportedOSPlatform]` or `[UnsupportedOSPlatform]` attributes are + present, we group all attributes by OS platform identifier: + - **Allow list**. If the lowest version for each OS platform is a + `[SupportedOSPlatform]` attribute, the API is considered to *only* be + supported by the listed platforms and unsupported by all other platforms. + - **Deny list**. If the lowest version for each OS platform is a + `[UnsupportedOSPlatform]` attribute, then the API is considered to *only* + be unsupported by the listed platforms and supported by all other + platforms. + - **Inconsistent list**. If for some platforms the lowest version attribute + is `[SupportedOSPlatform]` while for others it is + `[UnsupportedOSPlatform]`, the analyzer will produce a warning on the API + definition because the API is attributed inconsistently. +* Both attributes can be instantiated without version numbers. This means the + version number is assumed to be `0.0`. This simplifies guard clauses, see + examples below for more details. +* `[ObsoletedInOSPlatform]` continuous to require a version number. +* `[ObsoletedInOSPlatform]` by itself doesn't imply support. However, it doesn't + make sense to apply `[ObsoletedInOSPlatform]` unless that platform is + supported. + +These semantics result in intuitive attribute applications with flexible rules. + +Let's consider the example where in .NET 5 we mark an API as being unsupported +in `Windows`. This will look as follows: + +```C# +[UnsupportedOSPlatform("windows")] +public void DoesNotWorkOnWindows(); +``` + +Now let's say that in .NET 6 we made the API work in Windows, but only on +Windows `10.0.1903`. We'd update the API as follows: + +```C# +[UnsupportedOSPlatform("windows")] +[SupportedOSPlatform("windows10.0.1903")] +public void DoesNotWorkOnWindows(); +``` + +The presence of `SupportedOSPlatform` still makes no claim for other platforms +because the lowest version for Windows says the API is unsupported for Windows. + +Similar to [platform-checks] this model still allows for OS vendors to obsolete +and remove APIs: + +```C# +[UnsupportedOSPlatform("windows")] +[SupportedOSPlatform("windows10.0.1903")] +[ObsoletedInOSPlatform("windows10.0.1909")] +[SupportedOSPlatform("windows10.0.2004")] +public void DoesNotWorkOnWindows(); +``` + +This describes an API that is supported by all platforms, except for Windows. +And on Windows, it's supported for Windows 10 1903 and 1909. + +Platform-specific APIs like the iOS and Android bindings are still expressible +the same way: + +```C# +[SupportedOSPlatform("ios12.0")] +[ObsoletedInOSPlatform("ios13.0")] +[UnsupportedOSPlatform("ios14.0")] +[SupportedOSPlatform("ipados13.0")] +public void OnlyWorksOniOS(); +``` + +This API is considered to only work on iOS and iPadOS because the lowest version +starts with `[SupportedOSPlatform]`. ### Analyzer behavior -The existing analyzer that handles `[MinimumOSPlatform]` will be modified to -handle `[UnsupportedOSPlatform]` (previously named `[RemovedInOSPlatform]`) -with the semantics listed above. +The existing analyzer that handles `[MinimumOSPlatform]` and +`[RemovedInOSPlatform]` will be modified to handle the new +`[SupportedOSPlatform]` and `[UnsupportedOSPlatform]` attributes instead, +following the semantics as outlined above. + +We'll change the analyzer to consider these two guard clauses as equivalent: + +```C# +if (RuntimeInformation.IsPlatform(OSPlatform.Windows)) +{ + WindowsSpecificApi(); +} + +if (RuntimeInformation.IsPlatformOrLater("windows0.0")) +{ + WindowsSpecificApi(); +} +``` + +The primary benefit for doing this is to support all the code that was written +since .NET Standard introduced the OS check APIs, which peopled used primarily +to guard Windows-specific APIs which are part of the otherwise OS-neutral +`netstandard` and `net5.0` TFMs. Let's look at a few examples of annotations what the corresponding guard clauses are that would prevent the analyzer from flagging usage of the API. @@ -132,14 +270,32 @@ public void Api_Usage() ``` ```C# -// On Windows, the API was unsupported up to and including version 10.0.19041. +// On Windows, the API was unsupported until version 10.0.19041. // The API is considered supported everywhere else without constraints. -[UnsupportedOSPlatform("windows0.0-10.0.19041")] +[UnsupportedOSPlatform("windows")] +[SupportedOSPlatform("windows10.0.19041")] public extern void Api(); public void Api_Usage() { - if (!RuntimeInformation.IsOSPlatformOrEarlier("windows10.0.19041")) + if (!RuntimeInformation.IsOSPlatform("windows") || + RuntimeInformation.IsOSPlatformOrLater("windows10.0.19041")) + { + Api(); + } +} +``` + +```C# +// The API is only supported on Windows. It doesn't say which version, which +// means it effectively says since dawn of time. We'll use this to annotate +// Windows-specific APIs that will work on any version that can run .NET. +[SupportedOSPlatform("windows")] +public extern void Api(); + +public void Api_Usage() +{ + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Api(); } @@ -149,7 +305,7 @@ public void Api_Usage() ```C# // The API is only supported on iOS. There, it started to be supported in // version 12.0 and stopped being supported in version 14. -[MinimumOSPlatform("iOS12.0")] +[SupportedOSPlatform("iOS12.0")] [UnsupportedOSPlatform("ios14.0")] public extern void Api(); @@ -163,8 +319,6 @@ public void Api_Usage() } ``` -### Hardcoded APIs in the analyzer - ### Build configuration for platforms In order to indicate which platforms the analyzer should warn about, we're From 4bba51dc19fab125cd48e162c4932cd553172913 Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Tue, 28 Jul 2020 14:39:50 -0700 Subject: [PATCH 6/9] Don't use non-existent APIs --- accepted/2020/platform-exclusion/platform-exclusion.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index 433d7d611..5ff9dc353 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -262,7 +262,7 @@ public extern void Api(); public void Api_Usage() { - if (!RuntimeInformation.IsOSPlatform("browser")) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Browser)) { Api(); } @@ -278,7 +278,7 @@ public extern void Api(); public void Api_Usage() { - if (!RuntimeInformation.IsOSPlatform("windows") || + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatformOrLater("windows10.0.19041")) { Api(); From 3321a6442e6e866b76fe5e4b2089671d1f7007ea Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Tue, 28 Jul 2020 15:03:59 -0700 Subject: [PATCH 7/9] Update accepted/2020/platform-exclusion/platform-exclusion.md Co-authored-by: Jeff Handley --- accepted/2020/platform-exclusion/platform-exclusion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index 5ff9dc353..4b3b4baee 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -205,7 +205,7 @@ and remove APIs: [UnsupportedOSPlatform("windows")] [SupportedOSPlatform("windows10.0.1903")] [ObsoletedInOSPlatform("windows10.0.1909")] -[SupportedOSPlatform("windows10.0.2004")] +[UnsupportedOSPlatform("windows10.0.2004")] public void DoesNotWorkOnWindows(); ``` From 2aa70d1f8bdcb157fcd20c3b5eb9f591edfc0c19 Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Tue, 28 Jul 2020 15:04:27 -0700 Subject: [PATCH 8/9] Update accepted/2020/platform-exclusion/platform-exclusion.md Co-authored-by: Jeff Handley --- accepted/2020/platform-exclusion/platform-exclusion.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index 4b3b4baee..f2ad49763 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -210,7 +210,8 @@ public void DoesNotWorkOnWindows(); ``` This describes an API that is supported by all platforms, except for Windows. -And on Windows, it's supported for Windows 10 1903 and 1909. +And on Windows, it's supported for Windows 10 1903 and 1909, but it was +obsoleted in 1909 and then became unsupported again in 2004. Platform-specific APIs like the iOS and Android bindings are still expressible the same way: From 071dfd6ce0b039965e5dc08af9d7b354a66b2464 Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Tue, 28 Jul 2020 15:07:43 -0700 Subject: [PATCH 9/9] Fix spelling iOS --- accepted/2020/platform-exclusion/platform-exclusion.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/accepted/2020/platform-exclusion/platform-exclusion.md b/accepted/2020/platform-exclusion/platform-exclusion.md index f2ad49763..377992a67 100644 --- a/accepted/2020/platform-exclusion/platform-exclusion.md +++ b/accepted/2020/platform-exclusion/platform-exclusion.md @@ -306,14 +306,14 @@ public void Api_Usage() ```C# // The API is only supported on iOS. There, it started to be supported in // version 12.0 and stopped being supported in version 14. -[SupportedOSPlatform("iOS12.0")] +[SupportedOSPlatform("ios12.0")] [UnsupportedOSPlatform("ios14.0")] public extern void Api(); public void Api_Usage() { - if (RuntimeInformation.IsOSPlatformOrLater("iOS12.0") && - RuntimeInformation.IsOSPlatformOrEarlier("ios14.0")) + if (RuntimeInformation.IsOSPlatformOrLater("ios12.0") && + !RuntimeInformation.IsOSPlatformOrLater("ios14.0")) { Api(); }