[registrar] Fix verification of generic parameters to accept unrelated generic types. Fixes #6687. (#6850)
* [registrar] Fix verification of generic parameters to accept unrelated generic types. Fixes #6687. When we export generic classes to Objective-C, we verify that any generic parameters are constrained so that we know how to handle them. Example: class MyObj<T> : NSObject where T: NSObject { [Export ("foo:")] public void Foo (T obj); } in this case we verify that the parameter T is constrained to NSObject, so that we can treat the argument like an NSObject. The problem was when the function contained a generic type which was not related to T: class MyObj<T> : NSObject where T: NSObject { [Export ("foo:")] public void Foo (Action<int> obj); } in which case the same logic would kick in and reject the Action<int> type since it's not related to NSObject (no generic arguments could be found, and the default response was 'not valid'). So I've changed the default response for generic types that are unrelated to the generic parameter we're verifying to accept such types. Fixes https://github.com/xamarin/xamarin-macios/issues/6687. * No need to use a UIViewController as the super class, NSObject works just fine for this test. Fixes the test build on macOS.
This commit is contained in:
Родитель
fac23dc599
Коммит
73ce0f8882
|
@ -503,20 +503,7 @@ namespace Registrar {
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (type.IsGenericType) {
|
||||
var rv = true;
|
||||
var args = type.GetGenericArguments ();
|
||||
var constrs = new Type [args.Length];
|
||||
for (int i = 0; i < args.Length; i++) {
|
||||
Type constr;
|
||||
rv &= VerifyIsConstrainedToNSObject (args [i], out constr);
|
||||
constrs [i] = constr;
|
||||
}
|
||||
constrained_type = type.GetGenericTypeDefinition ().MakeGenericType (constrs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override Exception CreateException (int code, Exception innerException, MethodBase method, string message, params object[] args)
|
||||
|
|
|
@ -254,6 +254,9 @@ namespace MonoTouch.ObjCRuntime
|
|||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_int_int_int (IntPtr receiver, IntPtr selector, int p1, ref int p2, out int p3);
|
||||
|
||||
[DllImport (LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
|
||||
public extern static void void_objc_msgSend_IntPtr_IntPtr_BlockLiteral (IntPtr receiver, IntPtr selector, IntPtr p1, IntPtr p2, ref BlockLiteral p3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ using CoreLocation;
|
|||
#if !__TVOS__
|
||||
using Contacts;
|
||||
#endif
|
||||
using WebKit;
|
||||
#else
|
||||
using MonoTouch;
|
||||
using MonoTouch.AddressBook;
|
||||
|
@ -5246,6 +5247,44 @@ namespace MonoTouchFixtures.ObjCRuntime {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
#if !__WATCHOS__ && !__TVOS__ // No WebKit on watchOS/tvOS
|
||||
[Test]
|
||||
public void GenericClassWithUnrelatedGenericDelegate ()
|
||||
{
|
||||
using (var obj = new GenericWebNavigationThingie<NSObject> ()) {
|
||||
var handler_called = false;
|
||||
Action<WKNavigationActionPolicy> handler = new Action<WKNavigationActionPolicy> ((v) => {
|
||||
handler_called = true;
|
||||
});
|
||||
var block = new BlockLiteral ();
|
||||
var tramp = new DActionArity1V3 (SDActionArity1V3.Invoke);
|
||||
if (Runtime.DynamicRegistrationSupported) {
|
||||
block.SetupBlock (tramp, handler);
|
||||
Messaging.void_objc_msgSend_IntPtr_IntPtr_BlockLiteral (obj.Handle, Selector.GetHandle ("webView:decidePolicyForNavigationAction:decisionHandler:"), IntPtr.Zero, IntPtr.Zero, ref block);
|
||||
block.CleanupBlock ();
|
||||
Assert.IsTrue (handler_called, "Handler called");
|
||||
} else {
|
||||
Assert.Throws<RuntimeException> (() => block.SetupBlock (tramp, handler));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointerAttribute (CallingConvention.Cdecl)]
|
||||
internal delegate void DActionArity1V3 (IntPtr block, nint value);
|
||||
static internal class SDActionArity1V3 {
|
||||
static internal readonly DActionArity1V3 Handler = Invoke;
|
||||
|
||||
[MonoPInvokeCallback (typeof (DActionArity1V3))]
|
||||
public static unsafe void Invoke (IntPtr block, nint value)
|
||||
{
|
||||
var del = BlockLiteral.GetTarget<Action<WKNavigationActionPolicy>> (block);
|
||||
if (del != null)
|
||||
del ((WKNavigationActionPolicy) (long) value);
|
||||
}
|
||||
}
|
||||
#endif // !__WATCHOS__ && !__TVOS__
|
||||
|
||||
}
|
||||
|
||||
#if !__WATCHOS__
|
||||
|
@ -5382,6 +5421,18 @@ namespace MonoTouchFixtures.ObjCRuntime {
|
|||
public class SomeConsumer : NSObject, ISomeDelegate
|
||||
{
|
||||
}
|
||||
|
||||
#if !__WATCHOS__ && !__TVOS__ // No WebKit on watchOS/tvOS
|
||||
[Preserve]
|
||||
public class GenericWebNavigationThingie<WebViewModel> : NSObject, IWKNavigationDelegate {
|
||||
[Export ("webView:decidePolicyForNavigationAction:decisionHandler:")]
|
||||
public void DecidePolicy (WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)
|
||||
{
|
||||
decisionHandler (WKNavigationActionPolicy.Allow);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !__WATCHOS__ // no MetalKit on watchOS
|
||||
// These classes implement Metal* protocols, so that the generated registrar code includes the corresponding Metal* headers.
|
||||
// https://github.com/xamarin/xamarin-macios/issues/4422
|
||||
|
|
Загрузка…
Ссылка в новой задаче