dotnet / roslyn-analyzers

MIT License
1.59k stars 466 forks source link

Assembly-level SupportedOSPlatform doesn't exclude other platforms/lower versions #6934

Open dotMorten opened 1 year ago

dotMorten commented 1 year ago

Analyzer

Diagnostic ID: CA1416: Validate platform compatibility

Analyzer source

SDK: Built-in CA analyzers in .NET 5 SDK or later

Version: SDK 7.0.400

Describe the bug

Assembly-level SupportedOSPlatformAttribute is handled differently than the same attribute at a member-level. Where on a member-level it only supports the platforms specified, assembly-level also required UnsupportedOSPlatformAttribute to be set to opt out of platform support.

Steps To Reproduce

  1. Create a new .NET MAUI project
  2. Create a .NET 6/7 Class Library, and reference it in the MAUI project
  3. Add the following to the class library:

    [assembly: System.Runtime.Versioning.SupportedOSPlatform("iOS15.0")]
    [assembly: System.Runtime.Versioning.SupportedOSPlatform("MacCatalyst15.0")]
    [assembly: System.Runtime.Versioning.SupportedOSPlatform("Android26.0")]
    [assembly: System.Runtime.Versioning.SupportedOSPlatform("Windows10.0.19041.0")]
    namespace ClassLibrary1
    {
    public static class Class1
    {
        public static void TestImplicit() { }
    
        [System.Runtime.Versioning.SupportedOSPlatform("iOS15.0")]
        [System.Runtime.Versioning.SupportedOSPlatform("Android26.0")]
        [System.Runtime.Versioning.SupportedOSPlatform("Windows10.0.19041.0")]
        public static void TestExplicit() {  }
    }
    }
  4. In the .NET MAUI project add this code:
    ClassLibrary1.Class1.TestImplicit(); // No platform warning
    ClassLibrary1.Class1.TestExplicit(); // This gets a platform warning
  5. Notice that only the second call gets a CA1416 warning.
  6. Next add [assembly: System.Runtime.Versioning.UnsupportedOSPlatform("")] to the class library, and notice that both methods does not behave similarly.

Expected behavior

Assembly-level and member-level attributes should behave the same way.

Actual behavior

Assembly-level SupportedOSPlatformAttribute must also have unsupported platforms explicitly specified.

Additional context

Instead of unsupporting an empty platform string, you could also add specific platforms but the list, but there's really no good way to get an exhaustive future-proof list, but the empty-string approach isn't documented as valid:

System.Runtime.Versioning.UnsupportedOSPlatform("Windows")]
System.Runtime.Versioning.UnsupportedOSPlatform("Android")]
System.Runtime.Versioning.UnsupportedOSPlatform("iOS")]
System.Runtime.Versioning.UnsupportedOSPlatform("Linux")]
System.Runtime.Versioning.UnsupportedOSPlatform("Tizen")]
dotMorten commented 1 year ago

/cc @buyaa-n who worked the most on the analyzer.

buyaa-n commented 1 year ago
  1. In the .NET MAUI project add this code:
    ClassLibrary1.Class1.TestImplicit(); // No platform warning
    ClassLibrary1.Class1.TestExplicit(); // This gets a platform warning

What platform the project was targeting? Or what platform attribute the call site has? What was the warning message on the 2nd row?

dotMorten commented 1 year ago

Here's the project you get from following the above 1-4 repro-steps: AnalyzerRepro.zip

What was the warning message on the 2nd row?

CA1416: Validate platform compatibility

2>E:\sources.tmp\AnalyzerRepro\AnalyzerRepro\MauiProgram.cs(10,13,10,48): warning CA1416: This call site is reachable on: 'MacCatalyst' 13.1 and later. 'Class1.TestExplicit()' is only supported on: 'Android' 26.0 and later, 'iOS' 15.0 and later, 'maccatalyst' 15.0 and later, 'Windows' 10.0.19041.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
2>E:\sources.tmp\AnalyzerRepro\AnalyzerRepro\MauiProgram.cs(10,13,10,48): warning CA1416: This call site is reachable on: 'iOS' 11.0 and later, 'maccatalyst' 11.0 and later. 'Class1.TestExplicit()' is only supported on: 'Android' 26.0 and later, 'iOS' 15.0 and later, 'maccatalyst' 15.0 and later, 'Windows' 10.0.19041.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
2>E:\sources.tmp\AnalyzerRepro\AnalyzerRepro\MauiProgram.cs(10,13,10,48): warning CA1416: This call site is reachable on: 'Android' 21.0 and later. 'Class1.TestExplicit()' is only supported on: 'Android' 26.0 and later, 'iOS' 15.0 and later, 'maccatalyst' 15.0 and later, 'Windows' 10.0.19041.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)
2>E:\sources.tmp\AnalyzerRepro\AnalyzerRepro\MauiProgram.cs(10,13,10,48): warning CA1416: This call site is reachable on: 'Windows' 10.0.17763.0 and later. 'Class1.TestExplicit()' is only supported on: 'Android' 26.0 and later, 'iOS' 15.0 and later, 'maccatalyst' 15.0 and later, 'Windows' 10.0.19041.0 and later. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1416)