Skip to content

[xtro] Report extra/unknown managed selectors with no native declaration. Fixes #26053.#26135

Open
rolfbjarne wants to merge 2 commits into
mainfrom
dev/rolf/issue-26053-xtro-unknown-selectors
Open

[xtro] Report extra/unknown managed selectors with no native declaration. Fixes #26053.#26135
rolfbjarne wants to merge 2 commits into
mainfrom
dev/rolf/issue-26053-xtro-unknown-selectors

Conversation

@rolfbjarne

Copy link
Copy Markdown
Member

xtro only validated selectors native → managed (!missing-selector!). It never flagged the reverse: a managed [Export] selector with no matching native declaration in the current SDK headers. When Apple removes or privatizes a selector, the managed binding becomes stale but xtro stayed silent, and introspection can't detect a privatized-but-still-implemented selector (a respondsToSelector: call still returns true).

This adds a reverse check to SelectorCheck that reports !unknown-selector! for a managed Type::selector when selector is not part of the effective set of selectors for the native class Type, which is:

  • the selectors declared directly on the class (and its categories);
  • plus the selectors declared on every base class (and their categories);
  • plus the selectors of every adopted protocol, transitively through protocol inheritance.

The set of adopted protocols is taken from both the headers and the managed binding: Apple frequently implements a protocol (e.g. NSCoding, NSCopying) without declaring the conformance on the class, and the managed binding is the authority on which protocols a class inlines — crediting them avoids a large number of false positives (this alone reduced the reported entries from ~450 to 144).

Additional false-positive guards:

  • Only publicly visible managed types are checked (internal dispatcher/proxy helper types use fabricated selectors), mirroring the !unknown-type! check.
  • Managed types whose native name has no declaration in the headers are skipped (that's the !unknown-type! case).
  • Frameworks not parsed natively (e.g. excluded from the sharpie run) are skipped.

The pre-existing bindings surfaced by the new check (private/SPI selectors, protocol/category members Apple inlines without declaring the conformance on the class, managed callback infrastructure, and API Apple dropped) are added to the per-platform .ignore files as the reviewed baseline; any new occurrence will now fail the build — the deterministic signal requested in the issue.

Fixes #26053.

🤖 Pull request created by Copilot

…ion.

xtro only validated selectors native -> managed (!missing-selector!). It never
flagged the reverse: a managed [Export] selector with no matching native
declaration in the current SDK headers. When Apple removes or privatizes a
selector, the managed binding becomes stale but xtro stayed silent, and
introspection can't detect a privatized-but-still-implemented selector (a
respondsToSelector: call still returns true).

Add a reverse check to SelectorCheck that reports '!unknown-selector!' for a
managed 'Type::selector' when 'selector' is not part of the effective set of
selectors for the native class 'Type', which is:

* the selectors declared directly on the class (and its categories);
* plus the selectors declared on every base class (and their categories);
* plus the selectors of every adopted protocol, transitively through protocol
  inheritance.

The set of adopted protocols is taken from both the headers and the managed
binding: Apple frequently implements a protocol (e.g. NSCoding, NSCopying)
without declaring the conformance on the class, and the managed binding is the
authority on which protocols a class inlines - crediting them avoids a large
number of false positives.

Additional false-positive guards:

* Only publicly visible managed types are checked (internal dispatcher/proxy
  helper types use fabricated selectors), mirroring the '!unknown-type!' check.
* Managed types whose native name has no declaration in the headers are skipped
  (that's the '!unknown-type!' case).
* Frameworks not parsed natively (e.g. excluded from the sharpie run) are
  skipped.

The pre-existing bindings surfaced by the new check (private/SPI selectors,
protocol/category members Apple inlines without declaring the conformance on
the class, managed callback infrastructure, and API Apple dropped) are added to
the per-platform .ignore files as the reviewed baseline; any new occurrence
will now fail the build - the deterministic signal requested in the issue.

Fixes #26053

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ffddc3c0-7309-450c-a89e-3898e80a0647
@vs-mobiletools-engineering-service2

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a reverse selector validation to xtro (managed → native) so bindings with managed [Export] selectors that are no longer declared in the current SDK headers are reported as !unknown-selector! (fixing the gap described in #26053). This provides a deterministic signal to remove/adjust stale bindings when Apple removes or privatizes API.

Changes:

  • Extend SelectorCheck to compute an “effective selector set” per native class (including base classes, categories, and adopted protocols) and report managed selectors not present in that set as !unknown-selector!.
  • Add baseline !unknown-selector! entries to per-platform api-annotations-dotnet/*.ignore files so existing known deltas don’t fail the build, while new ones will.
  • Add per-file explanatory headers for the new baseline ignore sections.

Reviewed changes

Copilot reviewed 51 out of 51 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/xtro-sharpie/xtro-sharpie/SelectorCheck.cs Implements managed→native selector validation and emits !unknown-selector! for stale managed exports
tests/xtro-sharpie/api-annotations-dotnet/tvOS-VideoSubscriberAccount.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/tvOS-UIKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/tvOS-ModelIO.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/tvOS-MetalPerformanceShaders.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/tvOS-Metal.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/tvOS-GLKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/tvOS-Foundation.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/tvOS-CloudKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-WebKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-VideoToolbox.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-VideoSubscriberAccount.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-ModelIO.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-MetalPerformanceShaders.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-Metal.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-ImageCaptureCore.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-FSKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-Foundation.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-FileProvider.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-CoreSpotlight.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-CloudKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-AuthenticationServices.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/macOS-AppKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-WebKit.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-UIKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-StoreKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-SensorKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-PencilKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-ModelIO.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-MetalPerformanceShaders.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-Metal.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-Messages.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-Foundation.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-CoreSpotlight.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-CloudKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-WebKit.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-VideoSubscriberAccount.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-UIKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-PencilKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-ModelIO.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-MetalPerformanceShaders.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-Metal.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-Messages.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-GLKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-Foundation.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-DeviceDiscoveryUI.ignore New ignore file baselining !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-CoreSpotlight.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-CloudKit.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-CarPlay.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-AVFoundation.ignore Baseline ignores for newly-reported !unknown-selector! findings
tests/xtro-sharpie/api-annotations-dotnet/iOS-AccessorySetupKit.ignore New ignore file baselining !unknown-selector! findings

Comment thread tests/xtro-sharpie/xtro-sharpie/SelectorCheck.cs
Comment thread tests/xtro-sharpie/xtro-sharpie/SelectorCheck.cs Outdated
@vs-mobiletools-engineering-service2

This comment has been minimized.

* Guard against a null result from `TypeReference.Resolve ()` before calling
  `GetProtocolName`, which dereferences its argument (would throw if a
  referenced interface type can't be resolved, e.g. a missing assembly).
* Use `GetSelector ()` instead of `.Name` when collecting native property
  accessor selectors, for consistency with the method-declaration path (which
  uses `GetSelector ()`, preferring `Selector.ToString ()`).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ffddc3c0-7309-450c-a89e-3898e80a0647
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@rolfbjarne
rolfbjarne marked this pull request as ready for review July 20, 2026 06:04
@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: 905187fe6e4be7e9da4e9f2ed76cc05330c93cf0 [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🚀 [CI Build #905187f] Test results 🚀

Test results

✅ All tests passed on VSTS: test results.

🎉 All 203 tests passed 🎉

Tests counts

✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download
✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ linker (iOS): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (MacCatalyst): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (macOS): All 21 tests passed. Html Report (VSDrops) Download
✅ linker (tvOS): All 15 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 18 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 19 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

macOS tests

✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Ventura (13): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sonoma (14): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sequoia (15): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Tahoe (26): All 5 tests passed. Html Report (VSDrops) Download

Linux Build Verification

Linux build succeeded

Pipeline on Agent
Hash: 905187fe6e4be7e9da4e9f2ed76cc05330c93cf0 [PR build]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[xtro] Report extra/unknown selectors (managed bindings with no native declaration)

3 participants