Skip to content

Conversation

@mandel-macaque
Copy link
Contributor

From the review we noticed that sealed property and methods do not need the IsDirecBinding check. We update the struct to let use know if the method is sealed and generate the call accordingly. We just need to update some if conditions.

Tests have been updated to handle this case.

From the [review](#23656 (review)) we noticed
that sealed property and methods do not need the IsDirecBinding check.
We update the struct to let use know if the method is sealed and
generate the call accordingly. We just need to update some if
conditions.

Tests have been updated to handle this case.
Copy link
Contributor

Copilot AI left a comment

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 optimizes code generation for sealed properties and methods in the RGen (binding generator) by eliminating unnecessary IsDirectBinding checks. When properties or methods are marked as sealed, they cannot be overridden, so the generator can call Objective-C messaging directly without checking for subclass overrides.

Key changes:

  • Added IsSealed property to both Method and Property data models to track sealed modifiers
  • Updated code generation logic to bypass IsDirectBinding checks for sealed members
  • Added test cases and expected output files for sealed property and method scenarios

Reviewed Changes

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

Show a summary per file
File Description
src/rgen/Microsoft.Macios.Generator/DataModel/Method.cs Added IsSealed property to track sealed modifier on methods
src/rgen/Microsoft.Macios.Generator/DataModel/Property.cs Added IsSealed property to track sealed modifier on properties
src/rgen/Microsoft.Macios.Generator/Emitters/ClassEmitterExtensions.cs Updated code generation logic to use direct messaging for sealed members
tests/rgen/Microsoft.Macios.Generator.Tests/Classes/Data/MethodTests.cs Added test case for sealed method
tests/rgen/Microsoft.Macios.Generator.Tests/Classes/Data/PropertyTests.cs Added test case for sealed property
Multiple expected output files Updated with generated code for sealed members without IsDirectBinding checks
Comments suppressed due to low confidence (2)

[SupportedOSPlatform ("macos")]
[SupportedOSPlatform ("maccatalyst13.1")]
[Export<Property> ("sealedProperty")]
public sealed partial string SelaedProperty { get; set; }
Copy link

Copilot AI Aug 21, 2025

Choose a reason for hiding this comment

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

The property name 'SelaedProperty' contains a spelling error. It should be 'SealedProperty'.

Suggested change
public sealed partial string SelaedProperty { get; set; }
public sealed partial string SealedProperty { get; set; }

Copilot uses AI. Check for mistakes.
[SupportedOSPlatform ("tvos")]
[SupportedOSPlatform ("maccatalyst13.1")]
[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
public sealed partial string SelaedProperty
Copy link

Copilot AI Aug 21, 2025

Choose a reason for hiding this comment

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

The property name 'SelaedProperty' contains a spelling error. It should be 'SealedProperty'.

Suggested change
public sealed partial string SelaedProperty
public sealed partial string SealedProperty

Copilot uses AI. Check for mistakes.
@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.

@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.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #5d3c39c] Tests on macOS X64 - Mac Sonoma (14) passed 💻

All tests on macOS X64 - Mac Sonoma (14) passed.

Pipeline on Agent
Hash: 5d3c39c1f281cd18b9f1cddb45aa1888c44a1574 [PR build]

@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.

@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.

[SupportedOSPlatform ("macos")]
[SupportedOSPlatform ("maccatalyst13.1")]
[Export<Property> ("sealedProperty")]
public sealed partial string SelaedProperty { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

The [Sealed] attribute in bgen has more than one meaning, and the one that's important here is "don't export this method to Objective-C". This means the method must not have an [Export] attribute, and as an optimization, we can skip the IsDirectBinding check (because it won't call itself because it's not exported to Objective-C).

As such, I think it would be better to use something other than the sealed keyword to mark such APIs, because there's no reason it shouldn't be possible to export a sealed method to Objective-C (also it's a rather unintituive/obscure behavior).

Ideas:

  • Use a different attribute, say [Import ("selector")] or [Expose ("selector")] instead of [Export<T> ("selector")].
  • Use a property/flag on the [Export<T>] attribute, say [Export<T> ("selector", OnlyImport = true)]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I prefer to property flag, makes the api consistent

@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.

@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.

@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.

var (tempVar, tempDeclaration) = GetReturnValueAuxVariable (property.ReturnType);
// if the binding is a protocol, we need to call send directly
if (context.Changes.BindingType == BindingType.Protocol) {
if (context.Changes.BindingType == BindingType.Protocol || property.IsSealed) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (context.Changes.BindingType == BindingType.Protocol || property.IsSealed) {
if (context.Changes.BindingType == BindingType.Protocol || property.SkipRegistration) {

// perform the invocation
// if the binding is a protocol, we need to call send directly
if (context.Changes.BindingType == BindingType.Protocol) {
if (context.Changes.BindingType == BindingType.Protocol || property.IsSealed) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (context.Changes.BindingType == BindingType.Protocol || property.IsSealed) {
if (context.Changes.BindingType == BindingType.Protocol || property.SkipRegistration) {

Comment on lines 75 to 81
readonly bool isSealed;

/// <summary>
/// True if the method was marked as sealed.
/// </summary>
public bool IsSealed => isSealed;

Copy link
Member

Choose a reason for hiding this comment

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

No longer needed:

Suggested change
readonly bool isSealed;
/// <summary>
/// True if the method was marked as sealed.
/// </summary>
public bool IsSealed => isSealed;

init {
modifiers = value;
isStatic = modifiers.Any (x => x.IsKind (SyntaxKind.StaticKeyword));
isSealed = modifiers.Any (x => x.IsKind (SyntaxKind.SealedKeyword));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
isSealed = modifiers.Any (x => x.IsKind (SyntaxKind.SealedKeyword));

Comment on lines 76 to 82
readonly bool isSealed;

/// <summary>
/// True if the method was marked as sealed.
/// </summary>
public bool IsSealed => isSealed;

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
readonly bool isSealed;
/// <summary>
/// True if the method was marked as sealed.
/// </summary>
public bool IsSealed => isSealed;

init {
modifiers = value;
isStatic = modifiers.Any (x => x.IsKind (SyntaxKind.StaticKeyword));
isSealed = modifiers.Any (x => x.IsKind (SyntaxKind.SealedKeyword));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
isSealed = modifiers.Any (x => x.IsKind (SyntaxKind.SealedKeyword));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ugh I forgot I added in more than one place. Cleaning.

[SupportedOSPlatform ("macos")]
[SupportedOSPlatform ("maccatalyst13.1")]
[Export<Property> ("sealedProperty")]
public sealed partial string SelaedProperty { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public sealed partial string SelaedProperty { get; set; }
public sealed partial string SealedProperty { get; set; }

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [CI Build #cb0fbb4] Build passed (Build packages) ✅

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [PR Build #cb0fbb4] Build passed (Detect API changes) ✅

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ API diff for current PR / commit

.NET ( No breaking changes )

✅ API diff vs stable

.NET ( No breaking changes )

ℹ️ Generator diff

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

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [CI Build #cb0fbb4] Build passed (Build macOS tests) ✅

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #cb0fbb4] Tests on macOS M1 - Mac Monterey (12) passed 💻

All tests on macOS M1 - Mac Monterey (12) passed.

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #cb0fbb4] Tests on macOS M1 - Mac Ventura (13) passed 💻

All tests on macOS M1 - Mac Ventura (13) passed.

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [CI Build #4befbdc] Build passed (Build macOS tests) ✅

Pipeline on Agent
Hash: 4befbdc6bb3d99398ac5ed86c87c59582bff6c5c [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #cb0fbb4] Tests on macOS arm64 - Mac Sequoia (15) passed 💻

All tests on macOS arm64 - Mac Sequoia (15) passed.

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #4befbdc] Tests on macOS arm64 - Mac Sequoia (15) passed 💻

All tests on macOS arm64 - Mac Sequoia (15) passed.

Pipeline on Agent
Hash: 4befbdc6bb3d99398ac5ed86c87c59582bff6c5c [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #4befbdc] Tests on macOS M1 - Mac Ventura (13) passed 💻

All tests on macOS M1 - Mac Ventura (13) passed.

Pipeline on Agent
Hash: 4befbdc6bb3d99398ac5ed86c87c59582bff6c5c [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [CI Build #4befbdc] Tests on macOS M1 - Mac Monterey (12) passed 💻

All tests on macOS M1 - Mac Monterey (12) passed.

Pipeline on Agent
Hash: 4befbdc6bb3d99398ac5ed86c87c59582bff6c5c [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

🔥 [CI Build #cb0fbb4] Test results 🔥

Test results

❌ Tests failed on VSTS: test results

1 tests crashed, 0 tests failed, 112 tests passed.

Failures

❌ monotouch tests (macOS) [attempt 3]

🔥 Failed catastrophically on VSTS: test results - monotouch_macos (no summary found).

Html Report (VSDrops) Download

Successes

✅ 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: All 44 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 8 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 15 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ monotouch (tvOS): All 10 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. [attempt 2] Html Report (VSDrops) Download

Pipeline on Agent
Hash: cb0fbb49b5f25ea150741fca81ff6db7d4efb267 [PR build]

@mandel-macaque
Copy link
Contributor Author

mono Mac tests are not touch by the code changes.

@mandel-macaque mandel-macaque merged commit 99eaf5f into main Sep 4, 2025
37 of 40 checks passed
@mandel-macaque mandel-macaque deleted the dev/mandel/rgen-sealed-methods branch September 4, 2025 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants