Ejemplo n.º 1
0
        public PyMethod(PyObject self, IPyCallable callable)
        {
            this.callable = callable;
            var asSuper = self as PySuper;

            if (asSuper != null)
            {
                selfHandle = (PyObject)asSuper.__getattribute__("__self__");
            }
            else
            {
                selfHandle = self;
            }
            __setattr__("__call__", this);
        }
Ejemplo n.º 2
0
        public static Delegate Create(MethodInfo dotNetMethod, Type delegateType, IPyCallable callable, IInterpreter interpreter, FrameContext contextToUseForCall)
        {
            var proxy = new CallableDelegateProxy(callable, interpreter, contextToUseForCall);
            var dotNetMethodParamInfos = dotNetMethod.GetParameters();

            if (dotNetMethodParamInfos.Length > 2)
            {
                throw new NotImplementedException("We have only created templates for generic wrappers up to 4 arguments");
            }

            Delegate asDelegate;

            Type[]     delegateArgs;
            MethodInfo genericWrapper;

            // An ugly amount of copypasta. If we have a return type, then we need an array one element longer to put in RetVal at the end.
            // We also need to find the method matching the name of the right return type and accommodate the existing of a return value into
            // the number of generic parameters required for the right binding.
            if (dotNetMethod.ReturnType == typeof(void))
            {
                delegateArgs = new Type[dotNetMethodParamInfos.Length];
                for (int i = 0; i < dotNetMethodParamInfos.Length; ++i)
                {
                    delegateArgs[i] = dotNetMethodParamInfos[i].ParameterType;
                }
                genericWrapper = typeof(CallableDelegateProxy).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
                                 .Where(x => x.Name == "GenericWrapperVoid" && x.GetParameters().Length == delegateArgs.Length)
                                 .First();
            }
            else
            {
                throw new Exception("Attempted to bind a callable to an event that requires a return type. We don't support this type of binding.  " +
                                    "All our callables have to be async, and that meddles with signature of basic return values. Why are you using an event with " +
                                    "a return type anyways?");
            }

            var monomorphizedWrapper = genericWrapper.MakeGenericMethod(delegateArgs);

            asDelegate = Delegate.CreateDelegate(delegateType, proxy, monomorphizedWrapper);
            return(asDelegate);
        }
Ejemplo n.º 3
0
        // [TODO][SYS.SCHEDULE - RETURN TASK] sys.schedule should return the task record or a similar handle that the caller can manage
        public void schedule(PyModule module, FrameContext context, IPyCallable call, params object[] args)
        {
            var callCodeObject = call as CodeObject;

            // [TODO][SYS.SCHEDULE - RETURN TASK - CODEOBJECT]
            if (callCodeObject != null)
            {
                if (args == null)
                {
                    scheduler.Schedule(callCodeObject, context);
                }
                else
                {
                    scheduler.Schedule(callCodeObject, context, args);
                }
            }
            // [TODO][SYS.SCHEDULE - RETURN TASK - PYCALLABLE]
            else
            {
                call.Call(scheduler.Interpreter, context, args);
            }
        }
Ejemplo n.º 4
0
        public PyTypeObject(string name, IPyCallable __init__)
        {
            __dict__      = new Dictionary <string, object>();
            Name          = name;
            this.__init__ = __init__;
            __setattr__("__init__", this.__init__);
            __setattr__("__call__", this);

            // DefaultNew doesn't invoking any asynchronous code so we won't pass along its context to the wrapper.
            Expression <Action <PyTypeObject> > expr = instance => DefaultNew(null);
            var methodInfo = ((MethodCallExpression)expr.Body).Method;

            this.__new__ = new WrappedCodeObject("__new__", methodInfo, this);

            // The FlattenHierarchy flag in particular will search upstairs for ClassMember-decorated methods that were declared
            // in PyClass or PyTypeObject.
            var classMembers = GetType().GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
                               .Where(m => m.GetCustomAttributes(typeof(ClassMember), false).Length > 0).ToArray();

            foreach (var classMember in classMembers)
            {
                // We might have subclasses going on:
                // 1. Test if we already declared a WrappedCodeObject for this method
                // 2. If we did, check if it's declaring class is a child of the new candidate
                // 3. If so, disregard the candidate; we have the better one already.
                if (this.__dict__.ContainsKey(classMember.Name))
                {
                    var existing = this.__dict__[classMember.Name] as WrappedCodeObject;
                    if (existing.MethodBases[0].DeclaringType.IsSubclassOf(classMember.DeclaringType))
                    {
                        continue;
                    }
                }
                __setattr__(classMember.Name, new WrappedCodeObject(classMember.Name, classMember));
            }
        }
Ejemplo n.º 5
0
 public bool MatchesTarget(IPyCallable callable)
 {
     return(this.callable.Equals(callable));
 }
Ejemplo n.º 6
0
 private CallableDelegateProxy(IPyCallable callable, IInterpreter interpreter, FrameContext contextToUseForCall)
 {
     this.callable            = callable;
     this.interpreter         = interpreter;
     this.contextToUseForCall = contextToUseForCall;
 }