diff --git a/msbuild/Directory.Build.props b/msbuild/Directory.Build.props index 63c5da1fbd75..1e02d1a83c81 100644 --- a/msbuild/Directory.Build.props +++ b/msbuild/Directory.Build.props @@ -16,7 +16,7 @@ --> [3.0.13] - [17.14.51-gd03e25086a] + [17.14.83-g77e8f56103] diff --git a/msbuild/Makefile b/msbuild/Makefile index 8ce64128f360..1dbee190e1b0 100644 --- a/msbuild/Makefile +++ b/msbuild/Makefile @@ -53,7 +53,7 @@ IOS_WINDOWS_TARGETS = \ TASK_ASSEMBLIES = Xamarin.MacDev.Tasks $(LOCALIZATION_ASSEMBLIES) IOS_WINDOWS_TASK_ASSEMBLIES = Xamarin.iOS.Tasks.Windows -IOS_WINDOWS_DEPENDENCIES = Xamarin.iOS.Windows.Client iSign.Core ws2_32 System.Diagnostics.Tracer System.Formats.Asn1 System.Buffers System.Memory System.Numerics.Vectors System.Runtime.CompilerServices.Unsafe System.Security.Cryptography.ProtectedData System.Security.Cryptography.Pkcs Microsoft.Win32.Registry System.Security.AccessControl System.Security.Principal.Windows +IOS_WINDOWS_DEPENDENCIES = Xamarin.iOS.Windows.Client iSign.Core ws2_32 System.Diagnostics.Tracer System.Formats.Asn1 System.Buffers System.Memory System.Numerics.Vectors System.Runtime.CompilerServices.Unsafe System.Security.Cryptography.ProtectedData System.Security.Cryptography.Pkcs Microsoft.Win32.Registry IOS_WINDOWS_MOBILEDEVICE_TOOLS = iMobileDevice-net bz2 getopt ideviceactivation idevicebackup idevicebackup2 idevicecrashreport idevicedate idevicedebug idevicedebugserverproxy idevicediagnostics ideviceenterrecovery ideviceimagemounter ideviceinfo ideviceinstaller idevicename idevicenotificationproxy idevicepair ideviceprovision idevicerestore idevicescreenshot idevicesyslog idevice_id imobiledevice-net-lighthouse imobiledevice ios_webkit_debug_proxy iproxy irecovery irecovery libcharset libcurl LIBEAY32 libiconv libusb-1.0 libusb0 libxml2 lzma pcre pcreposix plist plistutil plist_cmp plist_test pthreadVC3 readline SSLEAY32 usbmuxd usbmuxd vcruntime140 zip zlib1 PROPS_AND_TARGETS = \ diff --git a/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Tasks.Windows.csproj b/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Tasks.Windows.csproj index 1173aaeb0905..7cbc1215d9bb 100644 --- a/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Tasks.Windows.csproj +++ b/msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.Tasks.Windows.csproj @@ -22,6 +22,7 @@ + @@ -38,7 +39,7 @@ PreserveNewest - + diff --git a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs index 9ec45041ef0d..b4b0b82903c6 100644 --- a/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs +++ b/src/rgen/Microsoft.Macios.Generator/DataModel/TypeInfo.cs @@ -235,7 +235,7 @@ public override int GetHashCode () const string IntPtr = "IntPtr"; const string UIntPtr = "UIntPtr"; - public string? ToMarshallType (ReferenceKind referenceKind) + public string? ToMarshallType () { #pragma warning disable format var type = this switch { diff --git a/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.ObjCRuntime.cs b/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.ObjCRuntime.cs index 98b7b6c402c5..ec0622d4dbc0 100644 --- a/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.ObjCRuntime.cs +++ b/src/rgen/Microsoft.Macios.Generator/Emitters/BindingSyntaxFactory.ObjCRuntime.cs @@ -5,10 +5,14 @@ using System.Collections.Immutable; using System.Linq; using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.Macios.Generator.Attributes; using Microsoft.Macios.Generator.DataModel; using Microsoft.Macios.Generator.Extensions; using TypeInfo = Microsoft.Macios.Generator.DataModel.TypeInfo; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Microsoft.Macios.Generator.Emitters; @@ -16,6 +20,62 @@ static partial class BindingSyntaxFactory { readonly static string objc_msgSend = "objc_msgSend"; readonly static string objc_msgSendSuper = "objc_msgSendSuper"; + /// + /// Returns the expression needed to cast a parameter to its native type. + /// + /// The parameter whose castin we need to generate. The type info has to be + /// and enum and be marked as native. If it is not the method returns null + /// + internal static CastExpressionSyntax? CastToNative (in Parameter parameter) + { + // not an enum and not a native value. we cannot calculate the casting expression. + if (!parameter.Type.IsEnum || !parameter.Type.IsNativeEnum) + return null; + + // build a casting expression based on the marshall type of the typeinfo + var marshalType = parameter.Type.ToMarshallType (); + if (marshalType is null) + // cannot calculate the marshal, return null + return null; + + var enumBackingValue = parameter.Type.EnumUnderlyingType.Value.GetKeyword (); + var castExpression = CastExpression (IdentifierName (marshalType), // (IntPtr/UIntPtr) cast + CastExpression ( + IdentifierName (enumBackingValue), + IdentifierName (parameter.Name) + .WithLeadingTrivia (Space)) + .WithLeadingTrivia (Space)); // (backingfield) (variable) cast + return castExpression; + } + + /// + /// Returns the expression needed to cast a bool to a byte to be used in a native call. + /// + /// The parameter to cast. + /// A conditional expression that casts a bool to a byte. + internal static ConditionalExpressionSyntax? CastToByte (in Parameter parameter) + { + if (parameter.Type.SpecialType != SpecialType.System_Boolean) + return null; + // (byte) 1 + var castOne = CastExpression ( + PredefinedType (Token (SyntaxKind.ByteKeyword)), + LiteralExpression (SyntaxKind.NumericLiteralExpression, Literal (1)).WithLeadingTrivia (Space).WithTrailingTrivia (Space) + ); + // (byte) 0 + var castZero = CastExpression ( + PredefinedType (Token (SyntaxKind.ByteKeyword)), + LiteralExpression (SyntaxKind.NumericLiteralExpression, Literal (0)).WithLeadingTrivia (Space) + ).WithLeadingTrivia (Space); + + // with this exact space count + // foo ? (byte) 1 : (byte) 0 + return ConditionalExpression ( + condition: IdentifierName (parameter.Name).WithTrailingTrivia (Space), + whenTrue: castOne.WithLeadingTrivia (Space), + whenFalse: castZero); + } + static string? GetObjCMessageSendMethodName (ExportData exportData, TypeInfo returnType, ImmutableArray parameters, bool isSuper = false, bool isStret = false) where T : Enum { @@ -42,7 +102,7 @@ static partial class BindingSyntaxFactory { } // return types do not have a reference kind - sb.Append (returnType.ToMarshallType (ReferenceKind.None)); + sb.Append (returnType.ToMarshallType ()); sb.Append ('_'); // append the msg method based if it is for super or not, do not append '_' intimidatingly, since if we do // not have parameters, we are done @@ -53,7 +113,7 @@ static partial class BindingSyntaxFactory { // loop over params and get their native handler name if (parameters.Length > 0) { sb.Append ('_'); - sb.AppendJoin ('_', parameters.Select (p => p.Type.ToMarshallType (p.ReferenceKind))); + sb.AppendJoin ('_', parameters.Select (p => p.Type.ToMarshallType ())); } // check if we do have a custom marshall exception set for the export diff --git a/src/rgen/Microsoft.Macios.Generator/Extensions/SpecialTypeExtensions.cs b/src/rgen/Microsoft.Macios.Generator/Extensions/SpecialTypeExtensions.cs index 6e14d5ca519a..21049b621965 100644 --- a/src/rgen/Microsoft.Macios.Generator/Extensions/SpecialTypeExtensions.cs +++ b/src/rgen/Microsoft.Macios.Generator/Extensions/SpecialTypeExtensions.cs @@ -17,7 +17,7 @@ static class SpecialTypeExtensions { /// /// The special type to convert. /// The string representation of the keyword. - public static string? GetKeyword (this SpecialType self) + public static string GetKeyword (this SpecialType self) { var kind = self switch { SpecialType.System_Void => SyntaxKind.VoidKeyword, diff --git a/src/rgen/Microsoft.Macios.Transformer.Generator/Microsoft.Macios.Transformer.Generator/XamarinBindingAPIGenerator.cs b/src/rgen/Microsoft.Macios.Transformer.Generator/Microsoft.Macios.Transformer.Generator/XamarinBindingAPIGenerator.cs index 72cff4800382..7d6bfee038f4 100644 --- a/src/rgen/Microsoft.Macios.Transformer.Generator/Microsoft.Macios.Transformer.Generator/XamarinBindingAPIGenerator.cs +++ b/src/rgen/Microsoft.Macios.Transformer.Generator/Microsoft.Macios.Transformer.Generator/XamarinBindingAPIGenerator.cs @@ -242,6 +242,7 @@ void GenerateCode (SourceProductionContext context, Compilation compilation, var models = new (string Model, AttributeTargets[] Targets) [] { ("EnumMember", [AttributeTargets.Field]), ("Parameter", [AttributeTargets.Parameter]), + ("Accessor", [AttributeTargets.Property]), ("Property", [AttributeTargets.Property]), ("Method", [AttributeTargets.Method]), ("Binding", [AttributeTargets.Interface, AttributeTargets.Class, AttributeTargets.Enum, AttributeTargets.Struct]), diff --git a/src/rgen/Microsoft.Macios.Transformer/DataModel/Accessor.Transformer.cs b/src/rgen/Microsoft.Macios.Transformer/DataModel/Accessor.Transformer.cs index 3220114a142d..372467045775 100644 --- a/src/rgen/Microsoft.Macios.Transformer/DataModel/Accessor.Transformer.cs +++ b/src/rgen/Microsoft.Macios.Transformer/DataModel/Accessor.Transformer.cs @@ -8,4 +8,6 @@ namespace Microsoft.Macios.Generator.DataModel; readonly partial struct Accessor { public ExportData? ExportPropertyData { get; init; } + + public Accessor () { } } diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoToMarshallTypeTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoToMarshallTypeTests.cs index 4ac0910c8408..6f50de75e446 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoToMarshallTypeTests.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/TypeInfoToMarshallTypeTests.cs @@ -205,7 +205,7 @@ void ToMarshallType (ApplePlatform platform, string inputText, string expectedTy Assert.NotNull (declaration); Assert.True (Property.TryCreate (declaration, semanticModel, out var changes)); Assert.NotNull (changes); - var marshall = changes.Value.ReturnType.ToMarshallType (ReferenceKind.None); + var marshall = changes.Value.ReturnType.ToMarshallType (); Assert.NotNull (marshall); Assert.Equal (expectedTypeName, marshall); } diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/Emitters/BindingSyntaxFactoryObjCRuntimeTests.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/Emitters/BindingSyntaxFactoryObjCRuntimeTests.cs new file mode 100644 index 000000000000..4a34d717499e --- /dev/null +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/Emitters/BindingSyntaxFactoryObjCRuntimeTests.cs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Collections; +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.Macios.Generator.DataModel; +using Xunit; +using static Microsoft.Macios.Generator.Emitters.BindingSyntaxFactory; +using static Microsoft.Macios.Generator.Tests.TestDataFactory; + +namespace Microsoft.Macios.Generator.Tests.Emitters; + +public class BindingSyntaxFactoryObjCRuntimeTests { + + class TestDataCastToNativeTests : IEnumerable { + public IEnumerator GetEnumerator () + { + + // not enum parameter + var boolParam = new Parameter ( + position: 0, + type: ReturnTypeForBool (), + name: "myParam"); + yield return [boolParam, null!]; + + // not smart enum parameter + var enumParam = new Parameter ( + position: 0, + type: ReturnTypeForEnum ("MyEnum", isNativeEnum: false), + name: "myParam"); + + yield return [enumParam, null!]; + + // int64 + var byteEnum = new Parameter ( + position: 0, + type: ReturnTypeForEnum ("MyEnum", isNativeEnum: true, underlyingType: SpecialType.System_Int64), + name: "myParam"); + yield return [byteEnum, "(IntPtr) (long) myParam"]; + + // uint64 + var int64Enum = new Parameter ( + position: 0, + type: ReturnTypeForEnum ("MyEnum", isNativeEnum: true, underlyingType: SpecialType.System_UInt64), + name: "myParam"); + yield return [int64Enum, "(UIntPtr) (ulong) myParam"]; + } + + IEnumerator IEnumerable.GetEnumerator () => GetEnumerator (); + } + + [Theory] + [ClassData (typeof (TestDataCastToNativeTests))] + void CastToNativeTests (Parameter parameter, string? expectedCast) + { + var expression = CastToNative (parameter); + if (expectedCast is null) { + Assert.Null (expression); + } else { + Assert.NotNull (expression); + Assert.Equal (expectedCast, expression?.ToString ()); + } + } + + [Fact] + void CastToByteTests () + { + var boolParameter = new Parameter (0, ReturnTypeForBool (), "myParameter"); + var conditionalExpr = CastToByte (boolParameter); + Assert.NotNull (conditionalExpr); + Assert.Equal ("myParameter ? (byte) 1 : (byte) 0", conditionalExpr.ToString ()); + + var intParameter = new Parameter (1, ReturnTypeForInt (), "myParameter"); + conditionalExpr = CastToByte (intParameter); + Assert.Null (conditionalExpr); + } +} diff --git a/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs b/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs index 5c28ac2e00d2..6caa973ca695 100644 --- a/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs +++ b/tests/rgen/Microsoft.Macios.Generator.Tests/TestDataFactory.cs @@ -181,7 +181,8 @@ public static TypeInfo ReturnTypeForStruct (string structName) isStruct: true ) { Parents = ["System.ValueType", "object"] }; - public static TypeInfo ReturnTypeForEnum (string enumName, bool isSmartEnum = false, bool isNativeEnum = false) + public static TypeInfo ReturnTypeForEnum (string enumName, bool isSmartEnum = false, bool isNativeEnum = false, + SpecialType underlyingType = SpecialType.System_Int32) => new ( name: enumName, isBlittable: true, @@ -199,7 +200,7 @@ public static TypeInfo ReturnTypeForEnum (string enumName, bool isSmartEnum = fa "System.ISpanFormattable" ], IsNativeEnum = isNativeEnum, - EnumUnderlyingType = SpecialType.System_Int32, + EnumUnderlyingType = underlyingType, }; public static TypeInfo ReturnTypeForArray (string type, bool isNullable = false, bool isBlittable = false) diff --git a/tools/devops/automation/build-pipeline.yml b/tools/devops/automation/build-pipeline.yml index de5ac8964149..ee5ba61c090e 100644 --- a/tools/devops/automation/build-pipeline.yml +++ b/tools/devops/automation/build-pipeline.yml @@ -14,7 +14,7 @@ parameters: - name: macOSName # comes from the build agent demand named macOS.Name displayName: Name of the version of macOS to use type: string - default: 'Sonoma' + default: 'Sequoia' - name: runGovernanceTests displayName: Run Governance Checks diff --git a/tools/devops/automation/build-pull-request.yml b/tools/devops/automation/build-pull-request.yml index 0733fbabcb11..c1ec04a9f8ac 100644 --- a/tools/devops/automation/build-pull-request.yml +++ b/tools/devops/automation/build-pull-request.yml @@ -15,7 +15,7 @@ parameters: - name: macOSName # comes from the build agent demand named macOS.Name displayName: Name of the version of macOS to use type: string - default: 'Sonoma' + default: 'Sequoia' - name: runGovernanceTests displayName: Run Governance Checks diff --git a/tools/devops/automation/templates/pipelines/api-diff-pipeline.yml b/tools/devops/automation/templates/pipelines/api-diff-pipeline.yml index 991def1ca58b..3a22e978aa6e 100644 --- a/tools/devops/automation/templates/pipelines/api-diff-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/api-diff-pipeline.yml @@ -11,7 +11,7 @@ parameters: - name: macOSName # comes from the build agent demand named macOS.Name displayName: Name of the version of macOS to use type: string - default: 'Sonoma' + default: 'Sequoia' - name: pool type: string diff --git a/tools/devops/automation/templates/pipelines/build-pipeline.yml b/tools/devops/automation/templates/pipelines/build-pipeline.yml index 7271c276caff..3133a1b5ae2a 100644 --- a/tools/devops/automation/templates/pipelines/build-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/build-pipeline.yml @@ -11,7 +11,7 @@ parameters: - name: macOSName # comes from the build agent demand named macOS.Name displayName: Name of the version of macOS to use type: string - default: 'Sonoma' + default: 'Sequoia' - name: pool type: string diff --git a/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml b/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml index b87e0def11af..210d8a997969 100644 --- a/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml +++ b/tools/devops/automation/templates/pipelines/run-tests-pipeline.yml @@ -14,7 +14,7 @@ parameters: - name: macOSName # comes from the build agent demand named macOS.Name displayName: Name of the version of macOS to use type: string - default: 'Sonoma' + default: 'Sequoia' - name: runTests displayName: Run Simulator Tests