From 911eab97b75b48eb4e490a9c7fcdd4e54a9c0038 Mon Sep 17 00:00:00 2001 From: Alex Soto Date: Wed, 14 Jun 2017 14:42:07 -0500 Subject: [PATCH 1/5] [registrar] BindAs uses Nullable types so allow them to be registered as NSObjects BindAsAttribute allows to bind NSValue and NSNumber into more accurate C# types lyke bool?, int? etc. so we must teach registrar about this. --- src/ObjCRuntime/Registrar.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ObjCRuntime/Registrar.cs b/src/ObjCRuntime/Registrar.cs index 274b121ca7a1..8c5cd62a2f15 100644 --- a/src/ObjCRuntime/Registrar.cs +++ b/src/ObjCRuntime/Registrar.cs @@ -2130,7 +2130,9 @@ protected string ToSignature (TType type, ObjCMember member, ref bool success, b { bool isNativeEnum; - switch (GetTypeFullName (type)) { + var typeFullName = GetTypeFullName (type); + + switch (typeFullName) { case "System.IntPtr": return "^v"; case "System.SByte": return "c"; case "System.Byte": return "C"; @@ -2163,6 +2165,10 @@ protected string ToSignature (TType type, ObjCMember member, ref bool success, b throw CreateException (4102, member, "The registrar found an invalid type `{0}` in signature for method `{2}`. Use `{1}` instead.", "System.DateTime", IsDualBuild ? "Foundation.NSDate" : CompatNamespace + ".Foundation.NSDate", member.FullName); } + // We use BindAsAttribute to wrap NSNumber/NSValue into more accurate Nullable types + if (typeFullName != null && typeFullName.Contains ("Nullable")) + return "@"; + if (Is (type, ObjCRuntime, "Selector")) return ":"; From d256179416f6dccfc553873a865277e20d7dd174 Mon Sep 17 00:00:00 2001 From: Alex Soto Date: Wed, 14 Jun 2017 14:44:24 -0500 Subject: [PATCH 2/5] [tests][introspection] Teach intro about BindAs and Nullable types Introspection will currently fail if BindAs is used, introspection will report that the incorrect type is registered so we need to skip this check if Nullable type is found in the signature --- tests/introspection/ApiSignatureTest.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/introspection/ApiSignatureTest.cs b/tests/introspection/ApiSignatureTest.cs index dab0ee507cc6..369c4a798df0 100644 --- a/tests/introspection/ApiSignatureTest.cs +++ b/tests/introspection/ApiSignatureTest.cs @@ -181,7 +181,18 @@ protected virtual bool Skip (Type type) protected virtual bool Skip (Type type, MethodBase method, string selector) { + if (method is MethodInfo mf) { + if (IsNullableType (mf.ReturnType)) + return true; + + foreach (var param in mf.GetParameters ()) { + if (IsNullableType (param.ParameterType)) + return true; + } + } return SkipDueToAttribute (method); + + bool IsNullableType (Type t) => Nullable.GetUnderlyingType (t) != null; } public int CurrentParameter { get; private set; } From 9310bc4fc9d0483e2e24eccde833bcf4ec50c3bc Mon Sep 17 00:00:00 2001 From: Alex Soto Date: Wed, 14 Jun 2017 22:57:19 -0500 Subject: [PATCH 3/5] [introspection] Add better type checking instead of totally skipping the type when Nullable type is encountered Introspection will currently fail if BindAs is used. Introspection will report that the incorrect type is registered so we need verify if a Nullable type is found in the signature and check against of a withelist of BindAs supported types --- tests/introspection/ApiSignatureTest.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/introspection/ApiSignatureTest.cs b/tests/introspection/ApiSignatureTest.cs index 369c4a798df0..2e9a0d3e95d6 100644 --- a/tests/introspection/ApiSignatureTest.cs +++ b/tests/introspection/ApiSignatureTest.cs @@ -181,18 +181,7 @@ protected virtual bool Skip (Type type) protected virtual bool Skip (Type type, MethodBase method, string selector) { - if (method is MethodInfo mf) { - if (IsNullableType (mf.ReturnType)) - return true; - - foreach (var param in mf.GetParameters ()) { - if (IsNullableType (param.ParameterType)) - return true; - } - } return SkipDueToAttribute (method); - - bool IsNullableType (Type t) => Nullable.GetUnderlyingType (t) != null; } public int CurrentParameter { get; private set; } @@ -656,6 +645,12 @@ protected virtual bool Check (char encodedType, Type type) { switch (encodedType) { case '@': + // We use BindAsAttribute to wrap NSNumber/NSValue into more accurate Nullable types + // So we check if T of nullable is supported by bindAs + var nullableType = Nullable.GetUnderlyingType (type); + if (nullableType != null) + return BindAsSupportedTypes.Contains (nullableType.Name); + return (type.IsInterface || // protocol type.IsArray || // NSArray (type.Name == "NSArray") || // NSArray @@ -989,5 +984,13 @@ protected virtual bool IgnoreAsync (MethodInfo m) } return false; } + + protected HashSet BindAsSupportedTypes = new HashSet { + "CGAffineTransform", "Range", "CGVector", "SCNMatrix4", "CLLocationCoordinate2D", + "SCNVector3", "Vector", "CGPoint", "CGRect", "CGSize", "UIEdgeInsets", + "UIOffset", "MKCoordinateSpan", "CMTimeRange", "CMTime", "CMTimeMapping", + "CATransform3D", "Boolean", "Byte", "Double", "Float", "Int16", "Int32", + "Int64", "SByte", "UInt16", "UInt32", "UInt64", "nfloat", "nint", "nuint", + }; } } From 8a9c588611a8a166f156f565c50b4642c1d7494b Mon Sep 17 00:00:00 2001 From: Alex Soto Date: Fri, 23 Jun 2017 09:58:50 -0500 Subject: [PATCH 4/5] Revert "[registrar] BindAs uses Nullable types so allow them to be registered as NSObjects" This reverts commit 911eab97b75b48eb4e490a9c7fcdd4e54a9c0038. --- src/ObjCRuntime/Registrar.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/ObjCRuntime/Registrar.cs b/src/ObjCRuntime/Registrar.cs index 8c5cd62a2f15..274b121ca7a1 100644 --- a/src/ObjCRuntime/Registrar.cs +++ b/src/ObjCRuntime/Registrar.cs @@ -2130,9 +2130,7 @@ protected string ToSignature (TType type, ObjCMember member, ref bool success, b { bool isNativeEnum; - var typeFullName = GetTypeFullName (type); - - switch (typeFullName) { + switch (GetTypeFullName (type)) { case "System.IntPtr": return "^v"; case "System.SByte": return "c"; case "System.Byte": return "C"; @@ -2165,10 +2163,6 @@ protected string ToSignature (TType type, ObjCMember member, ref bool success, b throw CreateException (4102, member, "The registrar found an invalid type `{0}` in signature for method `{2}`. Use `{1}` instead.", "System.DateTime", IsDualBuild ? "Foundation.NSDate" : CompatNamespace + ".Foundation.NSDate", member.FullName); } - // We use BindAsAttribute to wrap NSNumber/NSValue into more accurate Nullable types - if (typeFullName != null && typeFullName.Contains ("Nullable")) - return "@"; - if (Is (type, ObjCRuntime, "Selector")) return ":"; From 3a19a0fbdc89ac356a8fee1b5da774ea5dbf4600 Mon Sep 17 00:00:00 2001 From: Alex Soto Date: Fri, 23 Jun 2017 10:05:26 -0500 Subject: [PATCH 5/5] [tests] Add comment about where to find BindAs types --- tests/introspection/ApiSignatureTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/introspection/ApiSignatureTest.cs b/tests/introspection/ApiSignatureTest.cs index 2e9a0d3e95d6..1fadf6807949 100644 --- a/tests/introspection/ApiSignatureTest.cs +++ b/tests/introspection/ApiSignatureTest.cs @@ -985,6 +985,7 @@ protected virtual bool IgnoreAsync (MethodInfo m) return false; } + // This must be kept in sync with generator.cs NSValueCreateMap and NSValueReturnMap protected HashSet BindAsSupportedTypes = new HashSet { "CGAffineTransform", "Range", "CGVector", "SCNMatrix4", "CLLocationCoordinate2D", "SCNVector3", "Vector", "CGPoint", "CGRect", "CGSize", "UIEdgeInsets",