Skip to content

Commit 3b647ca

Browse files
[Rgen] Add method in the syntax factory to cast a bool to a byte. (#22061)
This is needed because the pinvokes do not use bools but bytes.
1 parent a70bd3e commit 3b647ca

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using System.Text;
88
using Microsoft.CodeAnalysis;
9+
using Microsoft.CodeAnalysis.CSharp;
910
using Microsoft.CodeAnalysis.CSharp.Syntax;
1011
using Microsoft.Macios.Generator.Attributes;
1112
using Microsoft.Macios.Generator.DataModel;
@@ -47,6 +48,34 @@ static partial class BindingSyntaxFactory {
4748
return castExpression;
4849
}
4950

51+
/// <summary>
52+
/// Returns the expression needed to cast a bool to a byte to be used in a native call.
53+
/// </summary>
54+
/// <param name="parameter">The parameter to cast.</param>
55+
/// <returns>A conditional expression that casts a bool to a byte.</returns>
56+
internal static ConditionalExpressionSyntax? CastToByte (in Parameter parameter)
57+
{
58+
if (parameter.Type.SpecialType != SpecialType.System_Boolean)
59+
return null;
60+
// (byte) 1
61+
var castOne = CastExpression (
62+
PredefinedType (Token (SyntaxKind.ByteKeyword)),
63+
LiteralExpression (SyntaxKind.NumericLiteralExpression, Literal (1)).WithLeadingTrivia (Space).WithTrailingTrivia (Space)
64+
);
65+
// (byte) 0
66+
var castZero = CastExpression (
67+
PredefinedType (Token (SyntaxKind.ByteKeyword)),
68+
LiteralExpression (SyntaxKind.NumericLiteralExpression, Literal (0)).WithLeadingTrivia (Space)
69+
).WithLeadingTrivia (Space);
70+
71+
// with this exact space count
72+
// foo ? (byte) 1 : (byte) 0
73+
return ConditionalExpression (
74+
condition: IdentifierName (parameter.Name).WithTrailingTrivia (Space),
75+
whenTrue: castOne.WithLeadingTrivia (Space),
76+
whenFalse: castZero);
77+
}
78+
5079
static string? GetObjCMessageSendMethodName<T> (ExportData<T> exportData,
5180
TypeInfo returnType, ImmutableArray<Parameter> parameters, bool isSuper = false, bool isStret = false) where T : Enum
5281
{

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Microsoft.Macios.Generator.Tests.Emitters;
1313

1414
public class BindingSyntaxFactoryObjCRuntimeTests {
1515

16-
class TestDataCodeChangesFromClassDeclaration : IEnumerable<object []> {
16+
class TestDataCastToNativeTests : IEnumerable<object []> {
1717
public IEnumerator<object []> GetEnumerator ()
1818
{
1919

@@ -51,7 +51,7 @@ public IEnumerator<object []> GetEnumerator ()
5151
}
5252

5353
[Theory]
54-
[ClassData (typeof (TestDataCodeChangesFromClassDeclaration))]
54+
[ClassData (typeof (TestDataCastToNativeTests))]
5555
void CastToNativeTests (Parameter parameter, string? expectedCast)
5656
{
5757
var expression = CastToNative (parameter);
@@ -62,4 +62,17 @@ void CastToNativeTests (Parameter parameter, string? expectedCast)
6262
Assert.Equal (expectedCast, expression?.ToString ());
6363
}
6464
}
65+
66+
[Fact]
67+
void CastToByteTests ()
68+
{
69+
var boolParameter = new Parameter (0, ReturnTypeForBool (), "myParameter");
70+
var conditionalExpr = CastToByte (boolParameter);
71+
Assert.NotNull (conditionalExpr);
72+
Assert.Equal ("myParameter ? (byte) 1 : (byte) 0", conditionalExpr.ToString ());
73+
74+
var intParameter = new Parameter (1, ReturnTypeForInt (), "myParameter");
75+
conditionalExpr = CastToByte (intParameter);
76+
Assert.Null (conditionalExpr);
77+
}
6578
}

0 commit comments

Comments
 (0)