Repository navigation
Conversation
Decode OperatingSystem.IsApplePlatform as macOS, MacCatalyst, iOS, or tvOS instead of a fictitious ApplePlatform OS. Preserve existing builtin guard registration and flow-analysis negation. Add C# and VB regressions for allow lists, deny lists, each Apple platform, Windows, watchOS, and negation. Document builtin guard test setup. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ee6e48ad-6898-45d7-98ed-9850afb3bd30
|
Azure Pipelines: Successfully started running 2 pipeline(s). 1 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Restore AGENTS.md to the original baseline as requested, preserving IsApplePlatform analyzer changes and regression tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ee6e48ad-6898-45d7-98ed-9850afb3bd30
| { | ||
| if (invokedPlatformCheckMethod.Name == IsApplePlatform) | ||
| { | ||
| infosBuilder.Add(new PlatformMethodValue("macos", EmptyVersion, negated: false)); |
There was a problem hiding this comment.
With the latest changes in dotnet/runtime#135475, should this rather depend on the list of Apple platforms on the IsApplePlatform API instead of duplicating it here?
There was a problem hiding this comment.
I removed the hardcoded platform list and no longer use the name-based guard decoder for IsApplePlatform(). It now bypasses that path and uses the existing TryParseGuardAttributes fallback to read the platforms directly from the API's annotations. Added regression tests to verify this and preserve the iOS/MacCatalyst relationship.
Should the tests for this API use .NET 12 reference assemblies (once the runtime change is merged) so that they test the actual user experience? |
Route IsApplePlatform through the existing guard attribute decoder instead of inferring a platform from its name or hardcoding the Apple platform set. Preserve iOS/MacCatalyst relationships and cover metadata-driven guards in regression tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Once dotnet/runtime#135475 is merged and a reference pack containing the API is available, I'll switch the C# and VB API-usage tests to .NET 12 reference assemblies and remove their |
Summary
Teach the platform compatibility analyzer (CA1416) to recognize
OperatingSystem.IsApplePlatform()through theSupportedOSPlatformGuardattributes on the API, rather than duplicating the Apple platform list in the analyzer.This supports the annotated public API in dotnet/runtime#135475 and addresses #56576 (comment). The API currently declares macOS, iOS, tvOS, and MacCatalyst. The analyzer reads those declarations from the method symbol in the analyzed compilation; no runtime reflection or execution is involved.
This PR changes only the analyzer and its tests. It adds no public API.
Problem
The existing convention treats static, parameterless Boolean
OperatingSystem.Is*methods as checks for an individual platform. ForIsApplePlatform(), strippingIsproduces a fictitiousApplePlatforminstead of the platform union declared by its attributes.Simply adding attributes does not avoid this inference: the known-guard invocation path first decodes the method name and then merges guard attributes. In addition,
CheckDependentPlatformsinterprets the attributes as relationships involving the inferred platform. Applying that logic to the aggregate guard can overwrite existing iOS/MacCatalyst relationships.The original version of this PR hardcoded four platform values. This revision removes that duplication and reuses the existing attribute-driven path.
Implementation
IsApplePlatformfromNameAndParametersValid, so it is neither decoded as a single-platform name nor passed toCheckDependentPlatforms.OperationVisitorhandle the method through its existingTryParseGuardAttributesfallback. That reads the API's attributes, parses their platform names and versions, and merges supported guards with OR semantics.IsApplePlatformcase fromPlatformMethodValue.TryDecode.IsIOS()unchanged, including their supplemental platform attributes and relationships.Returning false from
NameAndParametersValidkeepsIsApplePlatformout of_platformCheckMethods. WhenVisitInvocation_NonLambdaOrDelegateOrLocalFunctionvisits the call, the membership check fails and execution takes theelsebranch that callsTryParseGuardAttributes. The method is still analyzed, not ignored; only name-based decoding and dependency inference are bypassed.With the current API annotations, the positive branch is reachable on any of the four declared Apple platforms, and the negative branch excludes all four. An API called in the positive branch must be safe throughout that platform set. Windows and watchOS remain outside the set.
Only the method identity is special-cased; the platform set is defined by the referenced API's annotations, not by an analyzer-maintained list.
Regression test setup
The existing test helpers use reference assemblies without
OperatingSystem.IsApplePlatform(), so the C# and Visual Basic tests provide a source stub with the API's actual guard attributes. Stub methods throwNotImplementedException; the test code is compiled and analyzed, not executed.The tests configure the supported-platform list as
macos,maccatalyst,ios,tvos,watchos,windows. Windows and watchOS serve as negative controls. Diagnostic markers assert both required warnings and required suppression.Test coverage
Five test methods produce 13 Apple-guard cases:
else: APIs supported across the whole Apple set, partial support, unsupported Apple platforms, and Windows/watchOS controls.IsIOS(),IsMacCatalyst(), or their combined conditions.Validation
Analyzer solution build:
Result: passed, 0 warnings, 0 errors.
Platform compatibility test class, rerun on the final patch:
Result: 351 total, 349 passed, 2 existing skipped tests, 0 failed on Windows ARM64.
Before the production fix, the same runner with
--filter "FullyQualifiedName~IsApplePlatform_"executed 13 cases against the original hardcoded implementation: 7 failed and 6 passed. The failures were the six metadata-driven cases and the iOS/MacCatalyst relationship regression. All 13 pass after the fix.git diff --checkalso passed. The full SDK test suite was not run.Note
This PR description and the latest implementation update were prepared with GitHub Copilot.