예제 #1
0
파일: overload.cs 프로젝트: tatlin/pyRevit
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #3
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;
         }
     }
 }
예제 #4
0
        /// <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));
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
 internal DelegateObject(Type tp) : base(tp)
 {
     binder = new MethodBinder(tp.GetMethod("Invoke"));
 }
예제 #7
0
        /// <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);
                }
            }
        }
예제 #8
0
 public Indexer()
 {
     GetterBinder = new MethodBinder();
     SetterBinder = new MethodBinder();
 }