/// <summary> /// Implement explicit overload selection using subscript syntax ([]). /// </summary> public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) { var self = (OverloadMapper)GetManagedObject(tp); // Note: if the type provides a non-generic method with N args // and a generic method that takes N params, then we always // prefer the non-generic version in doing overload selection. Type[] types = Runtime.PythonArgsToTypeArray(idx); if (types == null) { return(Exceptions.RaiseTypeError("type(s) expected")); } MethodInfo mi = MethodBinder.MatchSignature(self.m.info, types); if (mi == null) { var e = "No match found for signature"; return(Exceptions.RaiseTypeError(e)); } var mb = new MethodBinding(self.m, self.target) { info = mi }; return(mb.pyHandle); }
int IComparer.Compare(object m1, object m2) { var me1 = (MethodBase)m1; var me2 = (MethodBase)m2; if (me1.DeclaringType != me2.DeclaringType) { // m2's type derives from m1's type, favor m2 if (me1.DeclaringType.IsAssignableFrom(me2.DeclaringType)) { return(1); } // m1's type derives from m2's type, favor m1 if (me2.DeclaringType.IsAssignableFrom(me1.DeclaringType)) { return(-1); } } int p1 = MethodBinder.GetPrecedence((MethodBase)m1); int p2 = MethodBinder.GetPrecedence((MethodBase)m2); if (p1 < p2) { return(-1); } if (p1 > p2) { return(1); } return(0); }
private void _MethodObject(Type type, string name, MethodInfo[] info) { this.type = type; this.name = name; this.info = info; binder = new MethodBinder(); foreach (MethodInfo item in info) { binder.AddMethod(item); if (item.IsStatic) { this.is_static = true; } } }
/// <summary> /// This is a hack. Generally, no managed class is considered callable /// from Python - with the exception of System.Delegate. It is useful /// to be able to call a System.Delegate instance directly, especially /// when working with multicast delegates. /// </summary> public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { //ManagedType self = GetManagedObject(ob); IntPtr tp = Runtime.PyObject_TYPE(ob); var cb = (ClassBase)GetManagedObject(tp); if (cb.type != typeof(Delegate)) { Exceptions.SetError(Exceptions.TypeError, "object is not callable"); return(IntPtr.Zero); } var co = (CLRObject)GetManagedObject(ob); var d = co.inst as Delegate; BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; MethodInfo method = d.GetType().GetMethod("Invoke", flags); var binder = new MethodBinder(method); return(binder.Invoke(ob, args, kw)); }
/// <summary> /// Implement binding of generic methods using the subscript syntax []. /// </summary> public static IntPtr mp_subscript(IntPtr tp, IntPtr idx) { var self = (MethodBinding)GetManagedObject(tp); Type[] types = Runtime.PythonArgsToTypeArray(idx); if (types == null) { return(Exceptions.RaiseTypeError("type(s) expected")); } MethodInfo mi = MethodBinder.MatchParameters(self.m.info, types); if (mi == null) { return(Exceptions.RaiseTypeError("No match found for given type params")); } var mb = new MethodBinding(self.m, self.target) { info = mi }; return(mb.pyHandle); }
internal DelegateObject(Type tp) : base(tp) { binder = new MethodBinder(tp.GetMethod("Invoke")); }
/// <summary> /// MethodBinding __call__ implementation. /// </summary> public static IntPtr tp_call(IntPtr ob, IntPtr args, IntPtr kw) { var self = (MethodBinding)GetManagedObject(ob); // This works around a situation where the wrong generic method is picked, // for example this method in the tests: string Overloaded<T>(int arg1, int arg2, string arg3) if (self.info != null) { if (self.info.IsGenericMethod) { var len = Runtime.PyTuple_Size(args); //FIXME: Never used Type[] sigTp = Runtime.PythonArgsToTypeArray(args, true); if (sigTp != null) { Type[] genericTp = self.info.GetGenericArguments(); MethodInfo betterMatch = MethodBinder.MatchSignatureAndParameters(self.m.info, genericTp, sigTp); if (betterMatch != null) { self.info = betterMatch; } } } } // This supports calling a method 'unbound', passing the instance // as the first argument. Note that this is not supported if any // of the overloads are static since we can't know if the intent // was to call the static method or the unbound instance method. var disposeList = new List <IntPtr>(); try { IntPtr target = self.target; if (target == IntPtr.Zero && !self.m.IsStatic()) { var len = Runtime.PyTuple_Size(args); if (len < 1) { Exceptions.SetError(Exceptions.TypeError, "not enough arguments"); return(IntPtr.Zero); } target = Runtime.PyTuple_GetItem(args, 0); Runtime.XIncref(target); disposeList.Add(target); args = Runtime.PyTuple_GetSlice(args, 1, len); disposeList.Add(args); } // if the class is a IPythonDerivedClass and target is not the same as self.targetType // (eg if calling the base class method) then call the original base class method instead // of the target method. IntPtr superType = IntPtr.Zero; if (Runtime.PyObject_TYPE(target) != self.targetType) { var inst = GetManagedObject(target) as CLRObject; if (inst?.inst is IPythonDerivedType) { var baseType = GetManagedObject(self.targetType) as ClassBase; if (baseType != null) { string baseMethodName = "_" + baseType.type.Name + "__" + self.m.name; IntPtr baseMethod = Runtime.PyObject_GetAttrString(target, baseMethodName); if (baseMethod != IntPtr.Zero) { var baseSelf = GetManagedObject(baseMethod) as MethodBinding; if (baseSelf != null) { self = baseSelf; } Runtime.XDecref(baseMethod); } else { Runtime.PyErr_Clear(); } } } } return(self.m.Invoke(target, args, kw, self.info)); } finally { foreach (IntPtr ptr in disposeList) { Runtime.XDecref(ptr); } } }
public Indexer() { GetterBinder = new MethodBinder(); SetterBinder = new MethodBinder(); }