-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Developers need more flexibility to annotate their code for platform supported/unsupported scenarios to reduce issues warnings noise #44922
Comments
Related: #47593 |
Conditionally-Supported Platform Annotations
Thanks, I think we can have more generalized attribute to support From the conditional platform support occurrences I found from Mark Windows-specific APIs design doc there is usually APIs are supported only on windows when a parameter is [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | System.AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public sealed class SupportedOSPlatformWhenAttribute : OSPlatformAttribute
{
public SupportedOSPlatformWhenAttribute(string platformName, string parameterName, string value) : base(platformName) { }
}
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | System.AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public sealed class UnsupportedOSPlatformUnlessAttribute : OSPlatformAttribute
{
public UnsupportedOSPlatformUnlessAttribute(string platformName, string parameterName, string value) : base(platformName) { }
}} Usage examples:
[SupportedOSPlatformWhen("windows", "mapName", "notnull")]
public static MemoryMappedFile CreateNew(string? mapName, long capacity) { throw null; }
void UsageSample ()
{
var mmf = MemoryMappedFile.CreateNew("testmap", 10000); // warns
var mmf2 = MemoryMappedFile.CreateNew(null, 10000); // not warn
}
public virtual PipeTransmissionMode ReadMode
{
get { ... }
[SupportedOSPlatformWhen("windows", "value", "Message")]
set { ... }
}
void UsageSample ()
{
var pipeStream = new PipeStream();
pipeStream.ReadMode = PipeTransmissionMode.Message; // warn
pipeStream.ReadMode = PipeTransmissionMode.Byte; // not warn
}
[UnsupportedOSPlatformUnless("browser", "millisecondsTimeout", "0")]
public bool Wait(int millisecondsTimeout)
{
return Wait(millisecondsTimeout, CancellationToken.None);
}
void UsageSample (SemaphoreSlim lock, int timeout)
{
lock.Wait(timeout); // warn
lock.Wait(timeout, CancellationToken.None); // warn
}
void UsageSample (SemaphoreSlim lock)
{
lock.Wait(0); // note warn
lock.Wait(0, CancellationToken.None); // not warn
} Note:
|
Platform-Guard Assertion Annotations
Based on the flow analysis API usage I think we do not need additional attributes for covering these, I propose to just add corresponding Example: 1. For #if !TARGET_BROWSER
[UnsupportedOSPlatform("browser")] // The analyzer would only evaluate an immediate attribute(s)
internal const bool IsThreadStartSupported = true;
#endif
protected internal override void QueueTask(Task task)
{
if (Thread.IsThreadStartSupported) // This will be evaluated same as `!OperatingSystem.IsBrowser()`
{
// Call unsupported on browser APIs safely
new Thread(s_longRunningThreadWork)
{
IsBackground = true,
Name = ".NET Long Running Task"
}.UnsafeStart(task);
}
}
[SupportedOSPlatform("windows10.0")]
public bool IsWindows10OrAbove()
{
return OperatingSystem.IsWindowsVersionAtLeast(10);
}
[SupportedOSPlatform("windows10.0")]
public bool Windows10OnlyAPI() { }
void Sample ()
{
if (IsWindows10OrAbove()) // work same as OperatingSystem.IsWindowsVersionAtLeast(10)
{
Windows10OnlyAPI();
}
}
[SupportedOSPlatform("windows")]
public partial class WindowsIdentity : System.Security.Claims.ClaimsIdentity, System.IDisposable, ...
{ ... }
void Sample ()
{
var identity = _negotiateState.GetIdentity();
if (identity is WindowsIdentity winIdentity) // work same as OperatingSystem.IsWindows()
{
ClaimsPrincipal user = new WindowsPrincipal(winIdentity);
}
} |
Notes from the last meeting:
|
Given the assessment @buyaa-n provided for "Conditionally-Supported Platform Attributes," I'm going to edit this story to remove that from scope. With the Platform-Guard attributes in place and in use, we can then mark this story as completed. |
The Platform Compatibility Analyzer was introduced in .NET 5.0, raising new diagnostics when APIs are referenced that are unsupported on targeted platforms. The analyzer relies on the
[SupportedOSPlatform]
and[UnsupportedOSPlatform]
attributes, which can be applied to assemblies, types, and members. These annotations only provide a mechanism for marking an API as entirely supported/unsupported--there is currently no way to annotate an API as partially or conditionally supported on a platform.Conditionally-Supported Platform Annotations
With a mechanism for marking an API as being conditionally supported/unsupported on a platform, we could improve annotations for APIs such as
MemoryMappedFile.CreateNew()
, where calls with a named memory mapped file (that is, a non-nullmapName
) are supported on Windows operating systems only.This could involve creating new attributes such as
[SupportedOSPlatformIfNull]
,[SupportedOSPlatformIfNotNull]
,[UnsupportedOSPlatformIfNull]
, and[UnsupportedOSPlatformIfNotNull]
. Occurrences of conditional platform support should be researched to determine what types of conditions need to be modeled in such attributes.Platform-Guard Assertion Annotations
The analyzer already recognizes platform guards using the methods on
OperatingSystem
, such asOperatingSystem.IsWindows
andOperatingSystem.IsWindowsVersionAtLeast
. However, the analyzer does not recognize other guard methods or even helper methods that assert platform guards. Expanding this support could involve creating new attributes that indicate that an API asserts platform checks the same way the APIs onOperatingSystem
do, potentially even conditionally.One example is in
Thread
, there is an internal field forIsThreadStartSupported
that indicates whether or not the current platform supports calls toThread.Start
, regardless of which platforms are targeted. Annotations could allow this to be modeled for the analyzer to warn ifThreat.Start
is called without first checking the correspondingIsThreadStartSupported
member.Additionally, it's expected that projects will commonly create helper methods that wrap around the
OperatingSystem
calls and these are not currently recognized through the flow analysis in the analyzer. Helper methods that perform platform assertion could be annotated to inform the analyzer that invocation or specific return values indicate platform support.Conditionally-Supported Platform Annotationsremoved from scopeThe text was updated successfully, but these errors were encountered: