Skip to content

Commit 8cda8bb

Browse files
mandel-macaquerolfbjarneGitHub Actions Autoformatter
authored
[RGen] Create factory method for the NSNumber FromHandle methods. (#22312)
This new factory method will return the member access to the correct NSNumber factory method. This is later used in the code generation when dealing with NSNumber backed BindAs/BindFrom attributes. --------- Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com> Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
1 parent f14b020 commit 8cda8bb

3 files changed

Lines changed: 389 additions & 16 deletions

File tree

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

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.CodeAnalysis.CSharp;
77
using Microsoft.CodeAnalysis.CSharp.Syntax;
88
using Microsoft.Macios.Generator.Extensions;
9+
using TypeInfo = Microsoft.Macios.Generator.DataModel.TypeInfo;
910
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1011

1112
namespace Microsoft.Macios.Generator.Emitters;
@@ -53,9 +54,9 @@ public static InvocationExpressionSyntax GetHandle (string selector)
5354
{
5455
// (selector)
5556
var args = ArgumentList (SingletonSeparatedList (
56-
Argument (LiteralExpression (
57-
SyntaxKind.StringLiteralExpression,
58-
Literal (selector))))).NormalizeWhitespace ();
57+
Argument (LiteralExpression (
58+
SyntaxKind.StringLiteralExpression,
59+
Literal (selector))))).NormalizeWhitespace ();
5960

6061
// Selector.GetHandle (selector)
6162
return InvocationExpression (
@@ -120,16 +121,16 @@ public static InvocationExpressionSyntax MessagingInvocation (string objcMsgSend
120121
var argumentList = ArgumentList (SeparatedList<ArgumentSyntax> (args));
121122
// generates: ObjCRuntime.Messaging.objc_msgSend (this.Handle, Selector.GetHandle (selector), args)
122123
var invocation = InvocationExpression (
123-
MemberAccessExpression (
124-
SyntaxKind.SimpleMemberAccessExpression,
125124
MemberAccessExpression (
126125
SyntaxKind.SimpleMemberAccessExpression,
127-
AliasQualifiedName (
128-
IdentifierName (
129-
Token (SyntaxKind.GlobalKeyword)),
130-
IdentifierName ("ObjCRuntime")),
131-
IdentifierName ("Messaging")),
132-
IdentifierName (objcMsgSendMethod).WithTrailingTrivia (Space)))
126+
MemberAccessExpression (
127+
SyntaxKind.SimpleMemberAccessExpression,
128+
AliasQualifiedName (
129+
IdentifierName (
130+
Token (SyntaxKind.GlobalKeyword)),
131+
IdentifierName ("ObjCRuntime")),
132+
IdentifierName ("Messaging")),
133+
IdentifierName (objcMsgSendMethod).WithTrailingTrivia (Space)))
133134
.WithArgumentList (argumentList);
134135
return invocation;
135136
}
@@ -147,10 +148,10 @@ internal static InvocationExpressionSyntax StringArrayFromHandle (ImmutableArray
147148

148149
// generate: CFArray.StringArrayFromHandle (arg1, arg2, arg3)
149150
return InvocationExpression (
150-
MemberAccessExpression (
151-
SyntaxKind.SimpleMemberAccessExpression,
152-
IdentifierName ("CFArray"),
153-
IdentifierName ("StringArrayFromHandle").WithTrailingTrivia (Space)))
151+
MemberAccessExpression (
152+
SyntaxKind.SimpleMemberAccessExpression,
153+
IdentifierName ("CFArray"),
154+
IdentifierName ("StringArrayFromHandle").WithTrailingTrivia (Space)))
154155
.WithArgumentList (argumentList);
155156
}
156157

@@ -174,6 +175,44 @@ internal static InvocationExpressionSyntax StringFromHandle (ImmutableArray<Argu
174175
.WithArgumentList (argumentList);
175176
}
176177

178+
/// <summary>
179+
/// Returns the method group needed to get a NSNumber from a handle.
180+
/// </summary>
181+
/// <param name="returnType">The type info of the return type.</param>
182+
/// <returns>The member access to the correct NSNumber method.</returns>
183+
internal static MemberAccessExpressionSyntax? NSNumberFromHandle (TypeInfo returnType)
184+
{
185+
#pragma warning disable format
186+
var memberName = returnType switch {
187+
// name must be before SpecialType or you'll get them wrong values because
188+
// the type we want by name also have a valid special type, the tests should catch
189+
// mistakes here
190+
{ Name: "NFloat" or "nfloat" } => "ToNFloat",
191+
{ Name: "nint" } => "ToNInt",
192+
{ Name: "nuint" } => "ToNUInt",
193+
{ SpecialType: SpecialType.System_Boolean } => "ToBool",
194+
{ SpecialType: SpecialType.System_Byte } => "ToByte",
195+
{ SpecialType: SpecialType.System_Double } => "ToDouble",
196+
{ SpecialType: SpecialType.System_Single } => "ToFloat",
197+
{ SpecialType: SpecialType.System_Int16 } => "ToInt16",
198+
{ SpecialType: SpecialType.System_Int32 } => "ToInt32",
199+
{ SpecialType: SpecialType.System_Int64 } => "ToInt64",
200+
{ SpecialType: SpecialType.System_SByte } => "ToSByte",
201+
{ SpecialType: SpecialType.System_UInt16 } => "ToUInt16",
202+
{ SpecialType: SpecialType.System_UInt32 } => "ToUInt32",
203+
{ SpecialType: SpecialType.System_UInt64 } => "ToUInt64",
204+
_ => null,
205+
};
206+
#pragma warning restore format
207+
if (memberName is null)
208+
return null;
209+
return MemberAccessExpression (
210+
SyntaxKind.SimpleMemberAccessExpression,
211+
IdentifierName ("NSNumber"),
212+
IdentifierName (memberName));
213+
}
214+
215+
177216
/// <summary>
178217
/// Generates a call to the NSArray.ArrayFromHandleFunc with the given arguments.
179218
/// </summary>

tests/rgen/Microsoft.Macios.Generator.Tests/Emitters/BindingSyntaxFactoryRuntimeTests.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
using System.Collections.Immutable;
77
using Microsoft.CodeAnalysis.CSharp;
88
using Microsoft.CodeAnalysis.CSharp.Syntax;
9+
using Microsoft.Macios.Generator.DataModel;
910
using Xunit;
1011
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1112
using static Microsoft.Macios.Generator.Emitters.BindingSyntaxFactory;
13+
using static Microsoft.Macios.Generator.Tests.TestDataFactory;
1214

1315
namespace Microsoft.Macios.Generator.Tests.Emitters;
1416

@@ -146,6 +148,77 @@ void StringFromHandleTests (ImmutableArray<ArgumentSyntax> arguments, string exp
146148
Assert.Equal (expectedDeclaration, declaration.ToFullString ());
147149
}
148150

151+
class TestDataNSNumberFromHandleTests : IEnumerable<object []> {
152+
public IEnumerator<object []> GetEnumerator ()
153+
{
154+
155+
yield return [
156+
ReturnTypeForBool (),
157+
"NSNumber.ToBool"
158+
];
159+
160+
yield return [
161+
ReturnTypeForInt (),
162+
"NSNumber.ToInt32"
163+
];
164+
165+
yield return [
166+
ReturnTypeForInt (isUnsigned: true),
167+
"NSNumber.ToUInt32"
168+
];
169+
170+
yield return [
171+
ReturnTypeForShort (),
172+
"NSNumber.ToInt16"
173+
];
174+
175+
yield return [
176+
ReturnTypeForShort (isUnsigned: true),
177+
"NSNumber.ToUInt16"
178+
];
179+
180+
yield return [
181+
ReturnTypeForLong (),
182+
"NSNumber.ToInt64"
183+
];
184+
185+
yield return [
186+
ReturnTypeForLong (isUnsigned: true),
187+
"NSNumber.ToUInt64"
188+
];
189+
190+
yield return [
191+
ReturnTypeForNInt (),
192+
"NSNumber.ToNInt"
193+
];
194+
195+
yield return [
196+
ReturnTypeForNInt (isUnsigned: true),
197+
"NSNumber.ToNUInt"
198+
];
199+
200+
yield return [
201+
ReturnTypeForDouble (),
202+
"NSNumber.ToDouble"
203+
];
204+
205+
yield return [
206+
ReturnTypeForFloat (),
207+
"NSNumber.ToFloat"
208+
];
209+
}
210+
211+
IEnumerator IEnumerable.GetEnumerator () => GetEnumerator ();
212+
}
213+
214+
[Theory]
215+
[ClassData (typeof (TestDataNSNumberFromHandleTests))]
216+
void NSNumberFromHandleTests (TypeInfo returnType, string expectedDeclaration)
217+
{
218+
var declaration = NSNumberFromHandle (returnType);
219+
Assert.Equal (expectedDeclaration, declaration?.ToFullString ());
220+
}
221+
149222
class TestDataNSArrayFromHandleFunc : IEnumerable<object []> {
150223
public IEnumerator<object []> GetEnumerator ()
151224
{

0 commit comments

Comments
 (0)