From 1b5fece6e077866e12863cb3fae95deb2d4d0e7c Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 10 Feb 2025 12:24:39 -0800 Subject: [PATCH] Skip any guarded platform that was suppressed by call site --- .../PlatformCompatibilityAnalyzer.cs | 20 ++++++------ ...tibilityAnalyzerTests.GuardedCallsTests.cs | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzer.cs index 14a403c754..2b71051189 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzer.cs @@ -57,8 +57,6 @@ public sealed partial class PlatformCompatibilityAnalyzer : DiagnosticAnalyzer private const string macOS = nameof(macOS); private const string OSX = nameof(OSX); private const string MacSlashOSX = "macOS/OSX"; - private const string ios = nameof(ios); - private const string maccatalyst = nameof(maccatalyst); private static readonly Version EmptyVersion = new(0, 0); internal static readonly DiagnosticDescriptor OnlySupportedCsReachable = DiagnosticDescriptorHelper.Create( @@ -638,16 +636,11 @@ static bool IsKnownValueGuarded( continue; } - // Skip maccatalyst check in case it was suppressed by callsite attribute - if (parent.AnalysisValues.Count == 1 && attributes.ContainsKey(ios) && !attributes.ContainsKey(maccatalyst)) + // Skip the platform check that was originally in the list and suppressed by callsite attributes + if (parent.AnalysisValues.Count == 1 && + IsPlatformSupportWasSuppresed((PlatformMethodValue)parent.AnalysisValues.First(), attributes, originalAttributes)) { - PlatformMethodValue parentValue = (PlatformMethodValue)parent.AnalysisValues.First(); - if (!parentValue.Negated && parentValue.PlatformName.Equals(maccatalyst, StringComparison.OrdinalIgnoreCase) && - originalAttributes.TryGetValue(maccatalyst, out Versions? macVersion) && - parentValue.Version.IsGreaterThanOrEqualTo(macVersion.SupportedFirst)) - { - continue; - } + continue; } } @@ -662,6 +655,11 @@ static bool IsKnownValueGuarded( return true; } + static bool IsPlatformSupportWasSuppresed(PlatformMethodValue parentValue, SmallDictionary attributes, SmallDictionary originalAttributes) + => !parentValue.Negated && !attributes.ContainsKey(parentValue.PlatformName) && + originalAttributes.TryGetValue(parentValue.PlatformName, out Versions? version) && + parentValue.Version.IsGreaterThanOrEqualTo(version.SupportedFirst); + static bool IsOnlySupportNeedsGuard(string platformName, SmallDictionary attributes, SmallDictionary csAttributes) => csAttributes.TryGetValue(platformName, out var versions) && AllowList(versions) && diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzerTests.GuardedCallsTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzerTests.GuardedCallsTests.cs index cf3d6f9ed4..27f1d5ac9a 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzerTests.GuardedCallsTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/InteropServices/PlatformCompatibilityAnalyzerTests.GuardedCallsTests.cs @@ -5398,6 +5398,37 @@ public void DoSomething() {} await VerifyAnalyzerCSAsync(source, msBuildPlatforms); } + [Fact, WorkItem(7530, "https://github.com/dotnet/roslyn-analyzers/issues/7530")] + public async Task OneOfCustomGuardsSuppressedByCallsite() + { + var source = @" +using System; +using System.Runtime.Versioning; +class TestType +{ + [SupportedOSPlatform(""macos15.0"")] + [SupportedOSPlatform(""tvos12.2"")] + private void GetFilter () + { + if (IsAtLeast) + DoSomething(); + + [|DoSomething()|]; // This call site is reachable on: 'macOS/OSX' 15.0 and later, 'tvos' 12.2 and later. 'TestType.DoSomething()' is only supported on: 'tvos' 15.0 and later. + } + + [SupportedOSPlatform(""tvos15.0"")] + [SupportedOSPlatform(""macos15.0"")] + public void DoSomething() {} + + [SupportedOSPlatformGuard (""macos15.0"")] + [SupportedOSPlatformGuard (""tvos15.0"")] + public bool IsAtLeast => false; +}"; + + string msBuildPlatforms = "build_property.TargetFramework=net8.0-maccatalyst12.0;\nbuild_property.TargetFrameworkIdentifier=.NETCoreApp\nbuild_property.TargetFrameworkVersion=v8.0"; + await VerifyAnalyzerCSAsync(source, msBuildPlatforms); + } + private readonly string TargetTypesForTest = @" namespace PlatformCompatDemo.SupportedUnupported {