Skip to content

[bgen] Support BindAs parameters in protocols - #26195

Merged
dalexsoto merged 8 commits into
mainfrom
dev/alex/bindas-protocol-parameters
Jul 24, 2026
Merged

dalexsoto merged 8 commits into
mainfrom
dev/alex/bindas-protocol-parameters

Conversation

@dalexsoto

Copy link
Copy Markdown
Member

Summary

  • allow parameter-level [BindAs] in [Protocol] and [Model] definitions while continuing to reject properties and return values
  • preserve native OriginalType metadata and messaging signatures, and resolve parameter attributes through mapped protocol methods in both registrars
  • use managed parameter types for trimming dependencies and generated XML documentation IDs
  • add generator, native callback, diagnostics, documentation, and XML-doc golden coverage

Context

This support was extracted from #26158 at @rolfbjarne’s request so that the generalized bgen/registrar feature lands in main independently of the Xcode 27 CoreSpotlight bindings. The deferred CoreSpotlight callback will be added after this change flows to xcode27.0.

Validation

  • make world with NO_XCODE=1 for the platform-independent main feature
  • full bgen suite: 399 passed, 1 skipped
  • XML documentation tests: 4 passed across iOS, tvOS, Mac Catalyst, and macOS

Allow parameter-level BindAs in Protocol and Model definitions while continuing to reject property and return-value usage.

Preserve the native OriginalType through generated metadata and messaging signatures, resolve BindAs metadata through protocol interface maps in the static and managed registrars, and emit managed parameter types in DynamicDependency and XML documentation IDs.

Add generator, registrar callback, diagnostic, documentation, and XML documentation coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b96fb7cb-f82d-4cd4-9b60-a7f899f3b42d
Copilot AI review requested due to automatic review settings July 20, 2026 15:04
@dalexsoto
dalexsoto requested a review from rolfbjarne as a code owner July 20, 2026 15:04
@dalexsoto dalexsoto added this to the xcode27 milestone Jul 20, 2026
dalexsoto added a commit that referenced this pull request Jul 20, 2026
Move generalized parameter-level BindAs support for Protocol and Model definitions to #26195, which targets main as requested during review.

Temporarily defer the protection-class searchable-items delegate callback and restore its targeted xtro todo entries until the feature flows from main to xcode27.0.

Keep the CoreSpotlight compatibility fixes that hide incorrectly shipped APIs with Obsolete and EditorBrowsable attributes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b96fb7cb-f82d-4cd4-9b60-a7f899f3b42d

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

This PR extends the binding generator (bgen) and both registrars to support parameter-level [BindAs] inside [Protocol] / [Model] definitions (while continuing to reject [BindAs] on protocol/model properties and return values). It also updates diagnostics, documentation, and adds/updates test coverage (including XML doc “golden” expectations) to validate the new behavior.

Changes:

  • Allow [BindAs] on protocol/model parameters and propagate the metadata correctly through generator + registrars (including mapped protocol/interface methods).
  • Adjust marshalling/doc-id generation to use the correct managed vs native parameter types where appropriate (trimming dependencies + XML doc IDs).
  • Add bindings-test + bgen test coverage and update user-facing docs/error messages to reflect the new constraints.

Reviewed changes

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

Show a summary per file
File Description
tools/dotnet-linker/Steps/ManagedRegistrarStep.cs Resolves parameter [BindAs] via mapped protocol interface methods for the managed registrar step.
src/ObjCRuntime/Registrar.cs Resolves parameter [BindAs] via mapped protocol interface methods in the runtime registrar.
src/bgen/Generator.cs Permits protocol/model parameter [BindAs], preserves OriginalType, and uses managed types for doc IDs/trimming metadata.
src/bgen/Models/MarshalInfo.cs Uses BindAsAttribute.OriginalType when determining marshaling type info (native signature preservation).
src/bgen/DocumentationManager.cs Adds an optional parameter-type provider to compute doc IDs using managed parameter types.
src/ObjCRuntime/BindAsAttribute.cs Updates inline docs to describe parameter support in protocol/model definitions.
src/Resources.resx Updates BI1050 message to match the new restriction (properties/return values only).
src/Resources.Designer.cs Regenerates BI1050 designer comment to match updated resource string.
tests/bindings-test/ApiDefinition.cs Adds a protocol/model method using parameter-level [BindAs] for runtime validation.
tests/bindings-test/ProtocolTest.cs Adds a test that invokes the exported selector and asserts correct BindAs conversion in protocol implementation.
tests/bindings-test/Messaging.cs Adds an objc_msgSend P/Invoke variant returning void used by the new protocol BindAs test.
tests/bgen/tests/bindastests.cs Adds bgen test coverage for parameter [BindAs] inside [Protocol]/[Model].
tests/bgen/tests/xmldocs.cs Adds protocol method with parameter [BindAs] to exercise XML doc ID/type generation.
tests/bgen/tests/ExpectedXmlDocs.iOS.xml Updates XML-doc golden output for BindAs-parameter doc IDs (iOS).
tests/bgen/tests/ExpectedXmlDocs.tvOS.xml Updates XML-doc golden output for BindAs-parameter doc IDs (tvOS).
tests/bgen/tests/ExpectedXmlDocs.macOS.xml Updates XML-doc golden output for BindAs-parameter doc IDs (macOS).
tests/bgen/tests/ExpectedXmlDocs.MacCatalyst.xml Updates XML-doc golden output for BindAs-parameter doc IDs (Mac Catalyst).
tests/bgen/ErrorTests.cs Updates BI1050 expected error text to match new restriction wording.
docs/website/generator-errors.md Updates BI1050 documentation to match new restriction wording.
docs/website/binding_types_reference_guide.md Updates BindAs docs to describe protocol/model parameter support and continued restrictions.
docs/website/binding_objc_libs.md Updates BindAs docs to describe protocol/model parameter support and continued restrictions.
docs/api/ObjCRuntime/BindAsAttribute.xml Adds API doc note clarifying protocol/model parameter-only support.
Files not reviewed (1)
  • src/Resources.Designer.cs: Generated file

Comment thread src/ObjCRuntime/Registrar.cs Resolved
Reuse the per-type protocol method map during normal registrar validation instead of rebuilding it for every parameter. Late signature evaluation prepares at most one local map per method, including null results.

Thread one local map through each managed-registrar type without adding persistent runtime caches, and skip lookups for properties, constructors, and categories.

Add native callback coverage for a protocol method with multiple BindAs parameters.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b96fb7cb-f82d-4cd4-9b60-a7f899f3b42d
@dalexsoto

Copy link
Copy Markdown
Member Author

Addressed the interface-map performance feedback in 6f41033 without adding persistent runtime caches. Normal registration reuses its existing per-type map, late evaluation builds at most one local map per method, and the managed registrar threads one local map through each type. Added a two-parameter native callback test; both callback tests pass under dynamic, static, and managed-static registrars on Xcode 27.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

Update the tvOS and Mac Catalyst MonoVM interpreter preserved API baselines generated by CI for the protocol method-map reuse changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b96fb7cb-f82d-4cd4-9b60-a7f899f3b42d
@dalexsoto

Copy link
Copy Markdown
Member Author

Updated the CI-generated tvOS and Mac Catalyst MonoVM interpreter preserved-API baselines in 86a3eeb. Both failed legs were app-size expectation drift from the registrar method-map changes; published NUnit results contained no functional test failures.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

Update the iOS MonoVM interpreter preserved API baseline generated by CI for the protocol method-map reuse changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b96fb7cb-f82d-4cd4-9b60-a7f899f3b42d
@dalexsoto

Copy link
Copy Markdown
Member Author

Added the CI-generated iOS MonoVM interpreter preserved-API baseline in 6d7b84e. This completes the app-size updates for all three affected platforms: iOS, tvOS, and Mac Catalyst.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@dalexsoto

Copy link
Copy Markdown
Member Author

/azp run xamarin-macios-sim-pr-tests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@dalexsoto

Copy link
Copy Markdown
Member Author

/azp run xamarin-macios-sim-pr-tests

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@vs-mobiletools-engineering-service2

This comment has been minimized.

@dalexsoto

Copy link
Copy Markdown
Member Author

/azp run xamarin-macios-sim-pr-tests

@github-actions

Copy link
Copy Markdown
Contributor

✅ Applied expected app size files from gist.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

⚠️ AppSizeTest expected files changed ⚠️

The AppSizeTest detected changes in the expected app size files.

To update the expected files, add a comment with the following command:

/apply-gist https://gist.github.com/vs-mobiletools-engineering-service2/3cf8ff719be49662de1febf84a2da537
Updated files
  • iOS-MonoVM-interpreter-preservedapis.txt
  • MacCatalyst-MonoVM-interpreter-preservedapis.txt
  • TVOS-MonoVM-interpreter-preservedapis.txt

Pipeline on Agent
Hash: e862a966741b114f303a0305ad01d38a78e3f395 [PR build]

@dalexsoto

Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Resolve conflicts in TVOS and iOS MonoVM interpreter preservedapis expected files
by accepting the updated content from main.

Co-authored-by: dalexsoto <204671+dalexsoto@users.noreply.github.com>

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved the merge conflicts in b283d7d. The conflicts were in TVOS-MonoVM-interpreter-preservedapis.txt and iOS-MonoVM-interpreter-preservedapis.txt — those files had been incorrectly emptied by the previously applied CI gist (commit e862a96). The merge takes the valid content from origin/main for both files.

@dalexsoto
dalexsoto enabled auto-merge (squash) July 24, 2026 02:30
@dalexsoto
dalexsoto requested a review from rolfbjarne July 24, 2026 02:30
@vs-mobiletools-engineering-service2

This comment has been minimized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e9e228af-33c5-4ac3-ac5e-f8839d48f8bc
@vs-mobiletools-engineering-service2

This comment has been minimized.

@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: 9c5f42720a0bf770a266a906dbe1be14a637ca13 [PR build]

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🚀 [CI Build #9c5f427] 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. [attempt 2] 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: 9c5f42720a0bf770a266a906dbe1be14a637ca13 [PR build]

@dalexsoto
dalexsoto merged commit 758a48d into main Jul 24, 2026
56 checks passed
@dalexsoto
dalexsoto deleted the dev/alex/bindas-protocol-parameters branch July 24, 2026 14:14
dalexsoto added a commit that referenced this pull request Jul 27, 2026
## Summary

- Bind
`CSSearchableIndexDelegate.searchableItemsForIdentifiers:protectionClass:searchableItemsHandler:`
on iOS 27.0, macOS 27.0, and Mac Catalyst 27.0.
- Reuse the existing searchable-items completion handler and preserve
the native non-null contract.
- Remove the resolved iOS, macOS, and Mac Catalyst CoreSpotlight xtro
todo files.

## Temporary API shape

The native `NSFileProtectionType` parameter is temporarily exposed as
`NSString` because bgen still rejects parameter-level `[BindAs]` inside
protocol/model definitions. Issue #26273 tracks changing it to `[BindAs
(typeof (NSFileProtectionType))] NSString` before Xcode 27 GA, after
#26195 lands.

## Validation

- `make world`
- Clean xtro generation/classification: sanity passed for all platforms
- Clean cecil suite: passed
- iOS 27 introspection: 44 passed, 0 failed
- tvOS 27 introspection: 43 passed, 0 failed
- macOS introspection: 32 passed, 0 failed, 2 host-version-gated
- Mac Catalyst introspection: 39 passed, 0 failed, 4 expected ignores
- Clean filtered `AppSizeTest`: 0 failed; 16 skipped because app-size
baselines are disabled for beta Xcode

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2883e233-aebe-4ada-932d-21a971c895e5
dalexsoto added a commit that referenced this pull request Sep 17, 2026
…26649)

## Summary

Strongly type the Xcode 27 `CSSearchableIndexDelegate` protection-class
parameter as `NSFileProtectionType`, completing the temporary binding
tracked by #26273.

The binding remains `[BindAs (typeof (NSFileProtectionType))] NSString
protectionClass`: callers see the managed smart enum, while Objective-C
still receives an `NSString`. The generator/registrar prerequisite from
#26195 is already in `main`; no additional generator change is
necessary.

## Regression coverage

- Check the generated `ICSSearchableIndexDelegate`, model, extension,
and `CSIndexExtensionRequestHandler` signatures in both reference and
implementation assemblies.
- Assert the native `BindAs.OriginalType` and optional `ProtocolMember`
metadata remain `NSString`, and that the completion-block proxy stays at
parameter index 2.
- Verify the older two-argument overload's visibility, return type,
parameter types, and block-proxy position; preserve existing platform
availability and tvOS exclusion.
- Exercise native round trips containing an identifiers array, a
non-default smart enum, and an array-returning completion block. Cover
both an unannotated interface implementation and a model override.

The callback test uses the generated internal protocol messaging helper,
rather than managed interface dispatch, so it also works when legacy
extension generation is disabled. No API-diff suppressions or
known-failure baseline changes were added.

Native protocol metadata assertions are unconditional, matching bgen's
emission independently of legacy extension generation.

## API compatibility

The replacement of the temporary `NSString` signature is intentional.
[API-diff build
15351050](https://dev.azure.com/devdiv/DevDiv/_build/results?buildId=15351050)
flags 12 `CP0002` removals against the PR base: the old signature on the
four generated surfaces for iOS, macOS, and Mac Catalyst. The same build
reports no breaking changes against stable 26.5 on any platform. This
compatibility change remains visible for review; no suppression file was
generated.

## Validation

Built and installed all four SDKs with `make world` and Xcode 27.

| Check | Result |
| --- | --- |
| Full bgen suite | 409 passed, 1 skipped |
| Full Cecil suite | 124 passed, 4 skipped; all 8 new API cases passed |
| xtro `gen-all` and `dotnet-classify` | All four platforms passed
sanity |
| iOS 27 introspection | 44 passed |
| tvOS 27 introspection | 43 passed |
| macOS introspection | 32 passed, 2 ignored |
| Mac Catalyst introspection | 39 passed, 4 ignored |
| macOS/CoreCLR protocol fixture | 9 passed for each of dynamic, static,
managed-static, and trimmable-static registrars |
| iOS 27/MonoVM protocol fixture | 9 passed with the managed-static
registrar |

The static registrar variations and iOS MonoVM variation used
`TrimMode=full`; the dynamic variation disabled trimming.

After the coverage refinements, all 8 targeted Cecil cases were rerun
successfully on each SDK.

Desktop tests ran on macOS 26.6.2, so new OS 27-only desktop symbols are
availability-gated there. Cecil checks their generated API and native
metadata independently, and the OS-independent callback tests execute
the marshaling paths rather than relying on introspection as an ABI
check.

Local launcher issues were handled without modifying or skipping tests:
desktop apps used the TCC-disclaiming spawner from a neutral directory;
the Catalyst app was staged on internal storage with executable hash
equality and code-signature verification; simulator NUnit output was
captured through the existing FILE reporter after installation.

The independently built and validated .NET 10 companion is #26651,
targeting `release/10.0.1xx`.

Fixes #26273.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 95b272cb-1a3e-4e2b-a3b4-e40fa69edae0
dalexsoto added a commit that referenced this pull request Sep 17, 2026
…NET 10) (#26651)

## Summary

Companion to #26649 for `release/10.0.1xx`, addressing #26273 with the
same binding and regression-test patch.

Replace the temporary `NSString`-only protection-class parameter on the
Xcode 27 `CSSearchableIndexDelegate` callback with `[BindAs (typeof
(NSFileProtectionType))] NSString protectionClass`. The public managed
surfaces expose the smart enum while preserving the Objective-C
`NSString` ABI. The prerequisite support from #26195 is already present
on this branch.

## Regression coverage

- Verify the generated interface, model, extension, and
`CSIndexExtensionRequestHandler` signatures in reference and
implementation assemblies.
- Preserve `NSString` in native `ProtocolMember` metadata and
`BindAs.OriginalType`, and keep the completion-block proxy at index 2.
- Verify the older overload's full signature and handler block-proxy
position; retain existing platform availability and tvOS exclusion.
- Run native array/smart-enum/block round trips through an unannotated
interface implementation and a model override. The generated internal
messaging helper prevents managed dispatch from bypassing the native
boundary and does not depend on legacy extension generation.

The branch-specific test-harness behavior was preserved. No API-diff
suppressions or known-failure baseline updates were added.

Native protocol metadata assertions run independently of legacy
extension generation, matching bgen's unconditional metadata emission.

## Independent .NET 10 validation

Built and installed all four SDKs with `make world` and Xcode 27. The
initial local ILRepack resolver failure was resolved by restoring the
repository-pinned tools and rerunning the complete build successfully;
no tool version or product workaround was committed.

| Check | Result |
| --- | --- |
| Full bgen suite | 408 passed, 1 skipped |
| Full Cecil suite | 124 passed, 4 skipped; all 8 new API cases passed |
| xtro `gen-all` and `dotnet-classify` | All four platforms passed
sanity |
| iOS 27 introspection | 43 passed, 1 ignored |
| tvOS 27 introspection | 42 passed, 1 ignored |
| macOS introspection | 32 passed, 2 ignored |
| Mac Catalyst introspection | 39 passed, 4 ignored |
| macOS/CoreCLR protocol fixture | 9 passed for each of dynamic, static,
managed-static, and trimmable-static registrars |
| iOS 27/MonoVM protocol fixture | 9 passed with the managed-static
registrar |

The static registrar variations and iOS MonoVM variation used
`TrimMode=full`; the dynamic variation disabled trimming.

After the coverage refinements, all 8 targeted Cecil cases were rerun
successfully on each SDK.

Desktop tests ran on macOS 26.6.2, so new OS 27-only desktop symbols are
availability-gated there. The compiled API/native metadata checks and
OS-independent callback tests provide separate coverage of the changed
contract and marshaling.

Local launcher adaptations did not change or skip tests: the generic
TCC-disclaiming spawner was used from a neutral directory, the identical
signed Catalyst app was staged on internal storage to avoid
external-volume startup probes, and simulator NUnit reports were
captured through the existing FILE reporter after installation.

Fixes #26273.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 95b272cb-1a3e-4e2b-a3b4-e40fa69edae0
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.

5 participants