Skip to content

Commit

Permalink
[Rgen] Allows to mark a property or accessor to marshal native except…
Browse files Browse the repository at this point in the history
…ions (#21997)

Properties can also do it. Allow to set the flag and provide a method
that will allow use to know if an accessor should marshal the native
exceptions or not.

---------

Co-authored-by: GitHub Actions Autoformatter <[email protected]>
  • Loading branch information
mandel-macaque and GitHub Actions Autoformatter authored Jan 18, 2025
1 parent f3a1a59 commit 9a50089
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/ObjCBindings/ExportTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ public enum Property : Int64 {
/// Generate a notification for the property.
/// </summary>
Notification = 1 << 3,

/// <summary>
/// Make a method support native (Objective-C) exceptions. Instead of calling objc_msgSend directly, the invocation
/// will go through a custom trampoline which catches ObjectiveC exceptions and marshals them into managed exceptions.
/// </summary>
MarshalNativeExceptions = 1 << 4,

}
}

11 changes: 11 additions & 0 deletions src/rgen/Microsoft.Macios.Generator/DataModel/Accessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ namespace Microsoft.Macios.Generator.DataModel;
/// </summary>
public ExportData<ObjCBindings.Property>? ExportPropertyData { get; init; }

public bool MarshalNativeExceptions
=> ExportPropertyData is not null && ExportPropertyData.Value.Flags.HasFlag (ObjCBindings.Property.MarshalNativeExceptions);

/// <summary>
/// List of attribute code changes of the accessor.
/// </summary>
Expand Down Expand Up @@ -82,6 +85,14 @@ public Accessor (AccessorKind accessorKind,
return ExportPropertyData.Value.Selector;
}

/// <summary>
/// Returns if the accessor should marshal native exceptions with the associated property.
/// </summary>
/// <param name="property">The property associated with the accessor.</param>
/// <returns>True if either the accessor or the property were marked with the MarshalNativeExceptions flag.</returns>
public bool ShouldMarshalNativeExceptions (in Property property)
=> MarshalNativeExceptions || property.MarshalNativeExceptions;

/// <inheritdoc />
public bool Equals (Accessor other)
{
Expand Down
5 changes: 5 additions & 0 deletions src/rgen/Microsoft.Macios.Generator/DataModel/Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ namespace Microsoft.Macios.Generator.DataModel;
/// </summary>
public ExportData<ObjCBindings.Method> ExportMethodData { get; }

/// <summary>
/// True if the method was exported with the MarshalNativeExceptions flag allowing it to support native exceptions.
/// </summary>
public bool MarshalNativeExceptions => ExportMethodData.Flags.HasFlag (ObjCBindings.Method.MarshalNativeExceptions);

/// <summary>
/// Get the attributes added to the constructor.
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions src/rgen/Microsoft.Macios.Generator/DataModel/Property.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ public bool IsNotification
/// </summary>
public ImmutableArray<AttributeCodeChange> Attributes { get; } = [];

/// <summary>
/// True if the method was exported with the MarshalNativeExceptions flag allowing it to support native exceptions.
/// </summary>
public bool MarshalNativeExceptions
=> IsProperty && ExportPropertyData.Value.Flags.HasFlag (ObjCBindings.Property.MarshalNativeExceptions);

/// <summary>
/// Get the modifiers of the property.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma warning disable APL0003
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.Macios.Generator.Attributes;
using Microsoft.Macios.Generator.Availability;
using Microsoft.Macios.Generator.DataModel;
using ObjCRuntime;
using Xunit;
using static Microsoft.Macios.Generator.Tests.TestDataFactory;

Expand Down Expand Up @@ -469,4 +471,45 @@ public void GetSetterSelectorExportData ()
Assert.NotNull (selector);
Assert.Equal (customSelector, selector);
}

[Theory]
[InlineData (false, false, false)]
[InlineData (false, true, true)]
[InlineData (true, false, true)]
[InlineData (true, true, true)]
public void ShouldMarshalNativeExceptionsBothFalse (bool propertyHasFlag, bool accessorHasFalg, bool expectedResult)
{
var property = new Property (
name: "MyProperty",
returnType: ReturnTypeForString (),
symbolAvailability: new (),
attributes: [],
modifiers: [],
accessors: []
) {
ExportPropertyData = new (
selector: "selector",
argumentSemantic: ArgumentSemantic.None,
flags: propertyHasFlag ? ObjCBindings.Property.MarshalNativeExceptions : ObjCBindings.Property.Default),
};

var accessor = new Accessor (
accessorKind: AccessorKind.Getter,
symbolAvailability: new (),
exportPropertyData: new (
selector: "selector",
argumentSemantic: ArgumentSemantic.None,
flags: accessorHasFalg ? ObjCBindings.Property.MarshalNativeExceptions : ObjCBindings.Property.Default),
attributes: [
new ("First"),
new ("Second"),
],
modifiers: [
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
SyntaxFactory.Token (SyntaxKind.PrivateKeyword)
]);
Assert.Equal (expectedResult, accessor.ShouldMarshalNativeExceptions (property));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.Macios.Generator.Attributes;
using Microsoft.Macios.Generator.Availability;
using Microsoft.Macios.Generator.DataModel;
using ObjCRuntime;
using Xamarin.Tests;
using Xamarin.Utils;
using Xunit;
Expand Down Expand Up @@ -444,6 +445,44 @@ public class TestClass {
}
];

const string marshallNativeException = @"
using System;
using ObjCBindings;
namespace Test;
public class TestClass {
[Export<Property>(""name"", Property.MarshalNativeExceptions)]
public string Name { get; }
}
";
yield return [
marshallNativeException,
new Property (
name: "Name",
returnType: ReturnTypeForString (),
symbolAvailability: new (),
attributes: [
new ("ObjCBindings.ExportAttribute<ObjCBindings.Property>", ["name", "ObjCBindings.Property.MarshalNativeExceptions"])
],
modifiers: [
SyntaxFactory.Token (kind: SyntaxKind.PublicKeyword),
],
accessors: [
new (
accessorKind: AccessorKind.Getter,
symbolAvailability: new (),
exportPropertyData: null,
attributes: [],
modifiers: []
)
]
) {
ExportPropertyData = new (selector: "name", ArgumentSemantic.None, ObjCBindings.Property.MarshalNativeExceptions),
}
];

const string valueTypeProperty = @"
using System;
using ObjCBindings;
Expand Down

0 comments on commit 9a50089

Please sign in to comment.