Skip to content

Commit c33c803

Browse files
mandel-macaqueGitHub Actions Autoformatter
andauthored
[RGen] Add method that can calculate the low level parameter for a trampoline. (#22834)
Add a new method that will take a managed delegate parameter and will generate the needed parameter syntax for the Invoke and delegate in a trampoline. Example of conversions: Action -> IntrPtr NSObject -> NativeHandle Pointer -> Pointer Array -> NativeHandle The tests take care to verify that the correct conversions is done for all the known parameter types. We need this conversion to fix the reviews in #22813 --------- Co-authored-by: GitHub Actions Autoformatter <[email protected]>
1 parent 51b7b03 commit c33c803

File tree

3 files changed

+492
-0
lines changed

3 files changed

+492
-0
lines changed

src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.ObjCRuntime.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ static partial class BindingSyntaxFactory {
3737
@namespace: ["ObjCRuntime"],
3838
@class: "NativeHandle",
3939
isGlobal: true);
40+
public readonly static TypeSyntax IntPtr = GetIdentifierName (
41+
@namespace: ["System"],
42+
@class: "IntPtr",
43+
isGlobal: true);
4044

4145
/// <summary>
4246
/// Returns the expression needed to cast a parameter to its native type.

src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.Trampoline.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Microsoft.CodeAnalysis.CSharp.Syntax;
99
using Microsoft.Macios.Generator.DataModel;
1010
using Microsoft.Macios.Generator.Extensions;
11+
using Microsoft.Macios.Generator.Formatters;
1112
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1213
using TypeInfo = Microsoft.Macios.Generator.DataModel.TypeInfo;
1314

@@ -74,6 +75,92 @@ internal static ExpressionSyntax CreateTrampolineNativeInvocationClass (string t
7475
return StaticInvocationExpression (staticClassName, "Create", arguments, suppressNullableWarning: true);
7576
}
7677

78+
79+
/// <summary>
80+
/// Returns the needed data to build the parameter syntax for the native trampoline delegate.
81+
/// </summary>
82+
/// <param name="trampolineName">The trampoline name of the parameter we want to generate.</param>
83+
/// <param name="parameter">The parameter we want to generate for the lower invoke method.</param>
84+
/// <returns>The parameter syntax needed for the parameter.</returns>
85+
internal static ParameterSyntax GetTrampolineInvokeParameter (string trampolineName, in DelegateParameter parameter)
86+
{
87+
var parameterIdentifier = Identifier (parameter.Name);
88+
#pragma warning disable format
89+
(SyntaxToken ParameterName, TypeSyntax? ParameterType) parameterInfo = parameter switch {
90+
// pointer parameter
91+
{ Type.IsPointer: true }
92+
=> (parameterIdentifier,
93+
parameter.Type.GetIdentifierSyntax ()),
94+
95+
// parameters that are passed by reference, depend on the type that is referenced
96+
{ IsByRef: true, Type.IsReferenceType: false, Type.IsNullable: true}
97+
=> (parameterIdentifier,
98+
PointerType (IdentifierName (parameter.Type.FullyQualifiedName))),
99+
100+
{ IsByRef: true, Type.SpecialType: SpecialType.System_Boolean}
101+
=> (parameterIdentifier,
102+
PointerType (PredefinedType (Token(SyntaxKind.ByteKeyword)))),
103+
104+
{ IsByRef: true, Type.IsReferenceType: true, Type.IsNullable: false}
105+
=> (parameterIdentifier,
106+
PointerType (NativeHandle)),
107+
108+
// delegate parameter is a NativeHandle
109+
{ Type.IsDelegate: true } => (parameterIdentifier, IntPtr),
110+
111+
// native enum, return the conversion expression to the native type
112+
{ Type.IsNativeEnum: true}
113+
=> (parameterIdentifier, IdentifierName(parameter.Type.EnumUnderlyingType!.Value.GetKeyword ())),
114+
115+
// boolean, convert it to byte
116+
{ Type.SpecialType: SpecialType.System_Boolean }
117+
=> (parameterIdentifier,
118+
PredefinedType (Token(SyntaxKind.ByteKeyword))),
119+
120+
// same name, native handle
121+
{ Type.IsArray: true }
122+
=> (parameterIdentifier, NativeHandle),
123+
124+
// string
125+
// same name, native handle
126+
{ Type.SpecialType: SpecialType.System_String }
127+
=> (parameterIdentifier, NativeHandle),
128+
129+
// same name, NativeHandle
130+
{ Type.IsProtocol: true } => (parameterIdentifier, NativeHandle),
131+
132+
// same name, NativeHandle
133+
{ ForcedType: not null } => (parameterIdentifier, NativeHandle),
134+
135+
// special types
136+
137+
// CoreMedia.CMSampleBuffer
138+
// same name, native handle
139+
{ Type.FullyQualifiedName: "CoreMedia.CMSampleBuffer" } => (parameterIdentifier, NativeHandle),
140+
141+
// AudioToolbox.AudioBuffers
142+
// same name, native handle
143+
{ Type.FullyQualifiedName: "AudioToolbox.AudioBuffers" } => (parameterIdentifier, NativeHandle),
144+
145+
// general NSObject/INativeObject, has to be after the special types otherwise the special types will
146+
// fall into the NSObject/INativeObject case
147+
148+
// same name, native handle
149+
{ Type.IsNSObject: true } => (parameterIdentifier, NativeHandle),
150+
151+
// same name, native handle
152+
{ Type.IsINativeObject: true } => (parameterIdentifier, NativeHandle),
153+
154+
// by default, we will use the parameter name as is and the type of the parameter
155+
_ => (parameterIdentifier, parameter.Type.GetIdentifierSyntax ()),
156+
};
157+
#pragma warning restore format
158+
159+
return Parameter (parameterInfo.ParameterName)
160+
.WithType (parameterInfo.ParameterType)
161+
.NormalizeWhitespace ();
162+
}
163+
77164
/// <summary>
78165
/// Returns the argument syntax of a parameter to be used for the trampoliner to invoke a delegate.
79166
/// </summary>

0 commit comments

Comments
 (0)