diff --git a/ReactWindows/ReactNative.Shared/Bridge/GenericDelegate.cs b/ReactWindows/ReactNative.Shared/Bridge/GenericDelegate.cs new file mode 100644 index 00000000000..23762f6f69e --- /dev/null +++ b/ReactWindows/ReactNative.Shared/Bridge/GenericDelegate.cs @@ -0,0 +1,70 @@ +using System; +using System.Reflection; + +namespace ReactNative.Bridge +{ + static class GenericDelegate + { + public static IGenericDelegate Create(MethodInfo method) + { + return (IGenericDelegate)Activator.CreateInstance(CreateDelegateType(method, false), method); + } + + public static IGenericDelegate Create(object instance, MethodInfo method) + { + return (IGenericDelegate)Activator.CreateInstance(CreateDelegateType(method, true), instance, method); + } + + private static Type CreateDelegateType(MethodInfo method, bool withInstance) + { + var methodParameters = method.GetParameters(); + var hasReturnValue = method.ReturnType != typeof(void); + var maximumParameterCount = hasReturnValue ? GenericDelegateTypes.FuncTypes.Length : GenericDelegateTypes.ActionTypes.Length; + + // If the number of arguments exceeds the number supported by generic delegates, + // return null. This will fall back to using reflection. + var thisArgumentCount = withInstance ? 0 : 1; + var argumentCount = methodParameters.Length + thisArgumentCount; + if (argumentCount > maximumParameterCount) + { + return null; + } + + // Increment the generic arity for methods with return values. + var genericArity = hasReturnValue ? argumentCount + 1 : argumentCount; + var typeList = new Type[genericArity]; + + // Set the first generic parameter to the declaring type, if necessary + if (!withInstance) + { + typeList[0] = method.DeclaringType; + } + + // Fill the generic type parameter list with method parameter types. + for (int t = thisArgumentCount; t < argumentCount; t++) + { + typeList[t] = methodParameters[t - thisArgumentCount].ParameterType; + } + + // If the function has a return value, append it to the generic type parameters. + if (hasReturnValue) + { + typeList[argumentCount] = method.ReturnType; + } + + // Get the appropriate generic delegate type. + var genericDelegateType = hasReturnValue + ? GenericDelegateTypes.FuncTypes[argumentCount] + : GenericDelegateTypes.ActionTypes[argumentCount]; + + // Close the generic type over the argument and return types, if necessary. + var delegateType = genericDelegateType; + if (genericArity > 0) + { + delegateType = genericDelegateType.MakeGenericType(typeList); + } + + return delegateType; + } + } +} diff --git a/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.cs b/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.cs index b0361030813..ecfce3fa508 100644 --- a/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.cs +++ b/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.cs @@ -1,7 +1,6 @@ // // This file is generated by GenericDelegateTypes.tt // - using System; using System.Reflection; @@ -28,7 +27,6 @@ static class GenericDelegateTypes typeof(SignatureAction14<,,,,,,,,,,,,,>), typeof(SignatureAction15<,,,,,,,,,,,,,,>), typeof(SignatureAction16<,,,,,,,,,,,,,,,>), - }; public static Type[] FuncTypes = @@ -50,23 +48,25 @@ static class GenericDelegateTypes typeof(SignatureFunc14<,,,,,,,,,,,,,,>), typeof(SignatureFunc15<,,,,,,,,,,,,,,,>), typeof(SignatureFunc16<,,,,,,,,,,,,,,,,>), - }; class SignatureAction0 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction0(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction0(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); } - public object DelegateTarget => _instancedDelegate.Target; - public object Invoke(object[] args) { - _instancedDelegate(); + _instancedDelegate(); return null; } } @@ -75,31 +75,36 @@ class SignatureFunc0 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc0(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc0(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); } - public object DelegateTarget => _instancedDelegate.Target; - public object Invoke(object[] args) => _instancedDelegate(); } - class SignatureAction1 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction1(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction1(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); } - public object DelegateTarget => _instancedDelegate.Target; - public object Invoke(object[] args) { - _instancedDelegate((T0)args[0]); + _instancedDelegate((T0)args[0]); return null; } } @@ -108,6 +113,11 @@ class SignatureFunc1 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc1(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc1(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -116,11 +126,15 @@ public SignatureFunc1(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0]); } - class SignatureAction2 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction2(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction2(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -128,7 +142,7 @@ public SignatureAction2(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1]); + _instancedDelegate((T0)args[0], (T1)args[1]); return null; } } @@ -137,6 +151,11 @@ class SignatureFunc2 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc2(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc2(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -145,11 +164,15 @@ public SignatureFunc2(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1]); } - class SignatureAction3 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction3(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction3(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -157,7 +180,7 @@ public SignatureAction3(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2]); return null; } } @@ -166,6 +189,11 @@ class SignatureFunc3 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc3(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc3(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -174,11 +202,15 @@ public SignatureFunc3(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2]); } - class SignatureAction4 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction4(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction4(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -186,7 +218,7 @@ public SignatureAction4(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3]); return null; } } @@ -195,6 +227,11 @@ class SignatureFunc4 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc4(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc4(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -203,11 +240,15 @@ public SignatureFunc4(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3]); } - class SignatureAction5 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction5(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction5(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -215,7 +256,7 @@ public SignatureAction5(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4]); return null; } } @@ -224,6 +265,11 @@ class SignatureFunc5 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc5(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc5(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -232,11 +278,15 @@ public SignatureFunc5(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4]); } - class SignatureAction6 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction6(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction6(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -244,7 +294,7 @@ public SignatureAction6(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5]); return null; } } @@ -253,6 +303,11 @@ class SignatureFunc6 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc6(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc6(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -261,11 +316,15 @@ public SignatureFunc6(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5]); } - class SignatureAction7 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction7(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction7(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -273,7 +332,7 @@ public SignatureAction7(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6]); return null; } } @@ -282,6 +341,11 @@ class SignatureFunc7 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc7(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc7(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -290,11 +354,15 @@ public SignatureFunc7(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6]); } - class SignatureAction8 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction8(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction8(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -302,7 +370,7 @@ public SignatureAction8(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7]); return null; } } @@ -311,6 +379,11 @@ class SignatureFunc8 : IGenericDelegate { Func _instancedDelegate; + public SignatureFunc8(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc8(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -319,11 +392,15 @@ public SignatureFunc8(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7]); } - class SignatureAction9 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction9(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction9(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -331,7 +408,7 @@ public SignatureAction9(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8]); return null; } } @@ -340,6 +417,11 @@ class SignatureFunc9 : IGenericDele { Func _instancedDelegate; + public SignatureFunc9(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc9(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -348,11 +430,15 @@ public SignatureFunc9(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8]); } - class SignatureAction10 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction10(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction10(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -360,7 +446,7 @@ public SignatureAction10(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9]); return null; } } @@ -369,6 +455,11 @@ class SignatureFunc10 : IGeneri { Func _instancedDelegate; + public SignatureFunc10(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc10(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -377,11 +468,15 @@ public SignatureFunc10(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9]); } - class SignatureAction11 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction11(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction11(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -389,7 +484,7 @@ public SignatureAction11(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10]); return null; } } @@ -398,6 +493,11 @@ class SignatureFunc11 : IG { Func _instancedDelegate; + public SignatureFunc11(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc11(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -406,11 +506,15 @@ public SignatureFunc11(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10]); } - class SignatureAction12 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction12(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction12(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -418,7 +522,7 @@ public SignatureAction12(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11]); return null; } } @@ -427,6 +531,11 @@ class SignatureFunc12 { Func _instancedDelegate; + public SignatureFunc12(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc12(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -435,11 +544,15 @@ public SignatureFunc12(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11]); } - class SignatureAction13 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction13(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction13(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -447,7 +560,7 @@ public SignatureAction13(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12]); return null; } } @@ -456,6 +569,11 @@ class SignatureFunc13 _instancedDelegate; + public SignatureFunc13(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc13(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -464,11 +582,15 @@ public SignatureFunc13(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12]); } - class SignatureAction14 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction14(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction14(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -476,7 +598,7 @@ public SignatureAction14(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13]); return null; } } @@ -485,6 +607,11 @@ class SignatureFunc14 _instancedDelegate; + public SignatureFunc14(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc14(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -493,11 +620,15 @@ public SignatureFunc14(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13]); } - class SignatureAction15 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction15(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction15(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -505,7 +636,7 @@ public SignatureAction15(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13], (T14)args[14]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13], (T14)args[14]); return null; } } @@ -514,6 +645,11 @@ class SignatureFunc15 _instancedDelegate; + public SignatureFunc15(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc15(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -522,11 +658,15 @@ public SignatureFunc15(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13], (T14)args[14]); } - class SignatureAction16 : IGenericDelegate { Action _instancedDelegate; + public SignatureAction16(MethodInfo method) + { + _instancedDelegate = (Action)method.CreateDelegate(typeof(Action)); + } + public SignatureAction16(object instance, MethodInfo method) { _instancedDelegate = (Action)method.CreateDelegate(typeof(Action), instance); @@ -534,7 +674,7 @@ public SignatureAction16(object instance, MethodInfo method) public object Invoke(object[] args) { - _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13], (T14)args[14], (T15)args[15]); + _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13], (T14)args[14], (T15)args[15]); return null; } } @@ -543,6 +683,11 @@ class SignatureFunc16 _instancedDelegate; + public SignatureFunc16(MethodInfo method) + { + _instancedDelegate = (Func)method.CreateDelegate(typeof(Func)); + } + public SignatureFunc16(object instance, MethodInfo method) { _instancedDelegate = (Func)method.CreateDelegate(typeof(Func), instance); @@ -551,6 +696,5 @@ public SignatureFunc16(object instance, MethodInfo method) public object Invoke(object[] args) => _instancedDelegate((T0)args[0], (T1)args[1], (T2)args[2], (T3)args[3], (T4)args[4], (T5)args[5], (T6)args[6], (T7)args[7], (T8)args[8], (T9)args[9], (T10)args[10], (T11)args[11], (T12)args[12], (T13)args[13], (T14)args[14], (T15)args[15]); } - } } diff --git a/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.tt b/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.tt index 145793416bd..b04aa49fc66 100644 --- a/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.tt +++ b/ReactWindows/ReactNative.Shared/Bridge/GenericDelegateTypes.tt @@ -13,7 +13,7 @@ using System.Reflection; namespace ReactNative.Bridge { - static class GenericDelegateType + static class GenericDelegateTypes { public static Type[] ActionTypes = { @@ -54,10 +54,16 @@ for (var i = 0; i <= maxArity; ++i) funcTypeParamsString = funcTypeParamsString + ", "; } #> + class SignatureAction<#=i#><#=actionTypeParamsString#> : IGenericDelegate { Action<#=actionTypeParamsString#> _instancedDelegate; + public SignatureAction<#=i#>(MethodInfo method) + { + _instancedDelegate = (Action<#=actionTypeParamsString#>)method.CreateDelegate(typeof(Action<#=actionTypeParamsString#>)); + } + public SignatureAction<#=i#>(object instance, MethodInfo method) { _instancedDelegate = (Action<#=actionTypeParamsString#>)method.CreateDelegate(typeof(Action<#=actionTypeParamsString#>), instance); @@ -74,6 +80,11 @@ for (var i = 0; i <= maxArity; ++i) { Func<<#=funcTypeParamsString#>TResult> _instancedDelegate; + public SignatureFunc<#=i#>(MethodInfo method) + { + _instancedDelegate = (Func<<#=funcTypeParamsString#>TResult>)method.CreateDelegate(typeof(Func<<#=funcTypeParamsString#>TResult>)); + } + public SignatureFunc<#=i#>(object instance, MethodInfo method) { _instancedDelegate = (Func<<#=funcTypeParamsString#>TResult>)method.CreateDelegate(typeof(Func<<#=funcTypeParamsString#>TResult>), instance); diff --git a/ReactWindows/ReactNative.Shared/Bridge/ReflectionReactDelegateFactory.cs b/ReactWindows/ReactNative.Shared/Bridge/ReflectionReactDelegateFactory.cs index 0b0dafa8740..f3d40eb254b 100644 --- a/ReactWindows/ReactNative.Shared/Bridge/ReflectionReactDelegateFactory.cs +++ b/ReactWindows/ReactNative.Shared/Bridge/ReflectionReactDelegateFactory.cs @@ -31,7 +31,7 @@ public override Action Create(INativeModule module, Meth var extractors = CreateExtractors(module, method); var expectedArguments = extractors.Sum(e => e.ExpectedArguments); var extractFunctions = extractors.Select(e => e.ExtractFunction).ToList(); - var genericDelegate = CreateGenericDelegate(module, method); + var genericDelegate = GenericDelegate.Create(module, method); return (reactInstance, arguments) => Invoke( @@ -179,52 +179,6 @@ private static void Invoke( } } - static IGenericDelegate CreateGenericDelegate(object instance, MethodInfo method) - { - var methodParameters = method.GetParameters(); - var hasReturnValue = method.ReturnType != typeof(void); - var maximumParameterCount = hasReturnValue ? GenericDelegateTypes.FuncTypes.Length : GenericDelegateTypes.ActionTypes.Length; - - // If the number of arguments exceeds the number supported by generic delegates, - // return null. This will fall back to using reflection. - var argumentCount = methodParameters.Length; - if (argumentCount > maximumParameterCount) - { - return null; - } - - // Increment the generic arity for methods with return values. - var genericArity = hasReturnValue ? argumentCount + 1 : argumentCount; - var typeList = new Type[genericArity]; - - // Fill the generic type parameter list with method parameter types. - for (int t = 0; t < argumentCount; t++) - { - typeList[t] = methodParameters[t].ParameterType; - } - - // If the function has a return value, append it to the generic type parameters. - if (hasReturnValue) - { - typeList[argumentCount] = method.ReturnType; - } - - // Get the appropriate generic delegate type. - var genericDelegateType = hasReturnValue - ? GenericDelegateTypes.FuncTypes[argumentCount] - : GenericDelegateTypes.ActionTypes[argumentCount]; - - // Close the generic type over the argument and return types, if necessary. - var delegateType = genericDelegateType; - if (genericArity > 0) - { - delegateType = genericDelegateType.MakeGenericType(typeList); - } - - // Create the generic delegate instance. - return (IGenericDelegate)Activator.CreateInstance(delegateType, instance, method); - } - private struct Result { public Result(int nextIndex, object value) diff --git a/ReactWindows/ReactNative.Shared/ReactNative.Shared.projitems b/ReactWindows/ReactNative.Shared/ReactNative.Shared.projitems index 289d96a3424..66942f10d4e 100644 --- a/ReactWindows/ReactNative.Shared/ReactNative.Shared.projitems +++ b/ReactWindows/ReactNative.Shared/ReactNative.Shared.projitems @@ -28,6 +28,7 @@ + diff --git a/ReactWindows/ReactNative.Shared/UIManager/PropertySetter.cs b/ReactWindows/ReactNative.Shared/UIManager/PropertySetter.cs index fb239918d0d..b247382fc5a 100644 --- a/ReactWindows/ReactNative.Shared/UIManager/PropertySetter.cs +++ b/ReactWindows/ReactNative.Shared/UIManager/PropertySetter.cs @@ -1,7 +1,7 @@ +using ReactNative.Bridge; using ReactNative.UIManager.Annotations; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Reflection; using System.Threading; #if WINDOWS_UWP @@ -47,6 +47,7 @@ abstract class PropertySetter : IPropertySetter { typeof(bool), a => a.DefaultBoolean }, }; + private readonly IGenericDelegate _genericDelegate; private readonly ReactPropBaseAttribute _attribute; private readonly string _propertyType; @@ -56,6 +57,8 @@ protected PropertySetter(MethodInfo method, string name, ReactPropBaseAttribute Name = name; PropertyType = GetPropertyType(method); + _genericDelegate = GenericDelegate.Create(method); + _propertyType = attribute.CustomType == ReactPropBaseAttribute.UseDefaultType ? GetPropertyType(PropertyType) : attribute.CustomType; @@ -84,7 +87,7 @@ public void UpdateShadowNodeProperty(ReactShadowNode shadowNode, ReactStylesDiff if (props == null) throw new ArgumentNullException(nameof(props)); - Invoke(shadowNode, GetShadowNodeArgs(props)); + Invoke(GetShadowNodeArgs(shadowNode, props)); } public void UpdateViewManagerProperty(IViewManager viewManager, DependencyObject view, ReactStylesDiffMap props) @@ -94,15 +97,15 @@ public void UpdateViewManagerProperty(IViewManager viewManager, DependencyObject if (props == null) throw new ArgumentNullException(nameof(props)); - Invoke(viewManager, GetViewManagerArgs(view, props)); + Invoke(GetViewManagerArgs(viewManager, view, props)); } - protected virtual object[] GetShadowNodeArgs(ReactStylesDiffMap props) + protected virtual object[] GetShadowNodeArgs(ReactShadowNode shadowNode, ReactStylesDiffMap props) { throw new NotSupportedException(Invariant($"'{nameof(ReactShadowNode)}' properties cannot be changed with this setter.")); } - protected virtual object[] GetViewManagerArgs(DependencyObject view, ReactStylesDiffMap props) + protected virtual object[] GetViewManagerArgs(IViewManager viewManager, DependencyObject view, ReactStylesDiffMap props) { throw new NotSupportedException($"'{nameof(IViewManager)}' properties cannot be changed with this setter."); } @@ -120,19 +123,22 @@ protected object ExtractProperty(ReactStylesDiffMap props) return defaultFunc(_attribute); } - return props.GetProperty(Name)? + var prop = props.GetProperty(Name)? .ToObject(PropertyType); + + if (prop == null && PropertyType.GetTypeInfo().IsValueType) + { + return Activator.CreateInstance(PropertyType); + } + + return prop; } - private void Invoke(object instance, object[] args) + private void Invoke(object[] args) { try { - Method.Invoke(instance, args); - } - catch (TargetInvocationException ex) - { - throw ex.InnerException; + _genericDelegate.Invoke(args); } finally { @@ -215,7 +221,7 @@ public static IEnumerable CreateViewManagerSetters(MethodInfo m class ViewManagerPropertySetter : PropertySetter { - private static ThreadLocal s_args = new ThreadLocal(() => new object[2]); + private static ThreadLocal s_args = new ThreadLocal(() => new object[3]); public ViewManagerPropertySetter(MethodInfo method, string name, ReactPropBaseAttribute attribute) : base(method, name, attribute) @@ -240,22 +246,24 @@ protected override Type GetPropertyType(MethodInfo method) return parameters[1].ParameterType; } - protected override object[] GetViewManagerArgs(DependencyObject view, ReactStylesDiffMap props) + protected override object[] GetViewManagerArgs(IViewManager viewManager, DependencyObject view, ReactStylesDiffMap props) { - s_args.Value[0] = view; - s_args.Value[1] = ExtractProperty(props); - return s_args.Value; + var args = s_args.Value; + args[0] = viewManager; + args[1] = view; + args[2] = ExtractProperty(props); + return args; } protected override void OnInvoked() { - Array.Clear(s_args.Value, 0, 2); + Array.Clear(s_args.Value, 0, 3); } } class ViewManagerGroupPropertySetter : PropertySetter { - private static ThreadLocal s_args = new ThreadLocal(() => new object[3]); + private static ThreadLocal s_args = new ThreadLocal(() => new object[4]); private readonly int _index; @@ -290,23 +298,25 @@ protected override Type GetPropertyType(MethodInfo method) return parameters[2].ParameterType; } - protected override object[] GetViewManagerArgs(DependencyObject view, ReactStylesDiffMap props) + protected override object[] GetViewManagerArgs(IViewManager viewManager, DependencyObject view, ReactStylesDiffMap props) { - s_args.Value[0] = view; - s_args.Value[1] = _index; - s_args.Value[2] = ExtractProperty(props); - return s_args.Value; + var args = s_args.Value; + args[0] = viewManager; + args[1] = view; + args[2] = _index; + args[3] = ExtractProperty(props); + return args; } protected override void OnInvoked() { - Array.Clear(s_args.Value, 0, 3); + Array.Clear(s_args.Value, 0, 4); } } class ShadowNodePropertySetter : PropertySetter { - private static ThreadLocal s_args = new ThreadLocal(() => new object[1]); + private static ThreadLocal s_args = new ThreadLocal(() => new object[2]); public ShadowNodePropertySetter(MethodInfo method, string name, ReactPropBaseAttribute attribute) : base(method, name, attribute) @@ -325,21 +335,23 @@ protected override Type GetPropertyType(MethodInfo method) return parameters[0].ParameterType; } - protected override object[] GetShadowNodeArgs(ReactStylesDiffMap props) + protected override object[] GetShadowNodeArgs(ReactShadowNode shadowNode, ReactStylesDiffMap props) { - s_args.Value[0] = ExtractProperty(props); - return s_args.Value; + var args = s_args.Value; + args[0] = shadowNode; + args[1] = ExtractProperty(props); + return args; } protected override void OnInvoked() { - Array.Clear(s_args.Value, 0, 1); + Array.Clear(s_args.Value, 0, 2); } } class ShadowNodeGroupPropertySetter : PropertySetter { - private static ThreadLocal s_args = new ThreadLocal(() => new object[2]); + private static ThreadLocal s_args = new ThreadLocal(() => new object[3]); private readonly int _index; @@ -367,16 +379,18 @@ protected override Type GetPropertyType(MethodInfo method) return parameters[1].ParameterType; } - protected override object[] GetShadowNodeArgs(ReactStylesDiffMap props) + protected override object[] GetShadowNodeArgs(ReactShadowNode shadowNode, ReactStylesDiffMap props) { - s_args.Value[0] = _index; - s_args.Value[1] = ExtractProperty(props); - return s_args.Value; + var args = s_args.Value; + args[0] = shadowNode; + args[1] = _index; + args[2] = ExtractProperty(props); + return args; } protected override void OnInvoked() { - Array.Clear(s_args.Value, 0, 2); + Array.Clear(s_args.Value, 0, 3); } } }