Ejemplo n.º 1
0
        public void RegisterMethod(String name, Type type, MethodInfo methodInfo)
        {
            lock (this)
            {
                // Only if not already registered

                // TODO Might need function overloading

                string key = type + "." + name;
                if (!m_MethodBindingByKey.ContainsKey(key))
                {
                    m_NextMethodId++;
                    var binding = new MethodBinding(m_NextMethodId, name, type, methodInfo);
                    m_MethodBindingById.Add(m_NextMethodId, binding);
                    m_MethodBindingByKey.Add(key, binding);
                }
            }
        }
Ejemplo n.º 2
0
 public AITreeNode(MethodBinding methodBinding, long guid, params AITreeNode[] children)
 {
     this.methodBinding = methodBinding;
     this.children      = children;
     this.guid          = guid;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Performs late-bound invocation - used by ReflectedMethod's and
        /// for keyword argument calls.
        /// </summary>
        protected static object Invoke(MethodBinding binding)
        {
            object result;

            try {
                if (binding.method is ConstructorInfo)
                {
                    result = ((ConstructorInfo)binding.method).Invoke(binding.arguments);
                }
                else
                {
                    result = binding.method.Invoke(binding.instance, binding.arguments);
                }
            } catch (TargetInvocationException tie) {
                throw ExceptionConverter.UpdateForRethrow(tie.InnerException);
            }

            MethodBase info = binding.method;

            ParameterInfo[] parameters = info.GetParameters();
            int             results    = 0;

            for (int parm = 0; parm < parameters.Length; parm++)
            {
                if (parameters[parm].ParameterType.IsByRef)
                {
                    results++;
                }
            }
            if (results == 0)
            {
                return(Ops.ToPython(CompilerHelpers.GetReturnType(info), result));
            }

            object[] retValues;
            int      retValueIndex = 0;

            if (info is MethodInfo && ((MethodInfo)info).ReturnType != typeof(void))
            {
                retValues = new object[results + 1];
                retValues[retValueIndex++] = Ops.ToPython(CompilerHelpers.GetReturnType(info), result);
            }
            else
            {
                retValues = new object[results];
            }

            for (int parm = 0; parm < parameters.Length; parm++)
            {
                Type parmType = parameters[parm].ParameterType;
                if (parmType.IsByRef)
                {
                    retValues[retValueIndex++] = Ops.ToPython(parmType, binding.arguments[parm]);
                }
            }
            if (retValues.Length == 1)
            {
                return(retValues[0]);
            }
            else
            {
                return(Tuple.MakeTuple(retValues));
            }
        }
Ejemplo n.º 4
0
        public virtual object Call(object[] args, string[] names)
        {
            // we allow kw-arg binding to ctor's of arbitrary CLS types, but
            // NOT Python built-in types.  After the ctor succeeds we'll set the kw args as
            // arbitrary properties on the CLS type.  If this ends up being a built-in type we'll
            // do the check when we're going to set the kw-args.  This accomplishes 2 things:
            //      1. Our error messages match CPython more closely
            //      2. The attribute lookup is done lazily only if kw-args are supplied to a ctor

            KwArgBinder            kwArgBinder     = new KwArgBinder(args, names, targets[0].IsConstructor);
            MethodBinding          bestBinding     = new MethodBinding();
            List <UnboundArgument> bestUnboundArgs = null;

            for (int i = 0; i < targets.Length; i++)
            {
                object[] realArgs = kwArgBinder.DoBind(targets[i], Name);

                if (realArgs != null)
                {
                    MethodBinding mb = new MethodBinding();
                    mb.method = targets[i];

                    if (!(targets[i].IsStatic || targets[i].IsConstructor))
                    {
                        if (!HasInstance)
                        {
                            if (realArgs.Length == 0)
                            {
                                throw Ops.TypeError("bad number of arguments for function {0}", targets[0].Name);
                            }
                            mb.instance  = realArgs[0];
                            mb.arguments = new object[realArgs.Length - 1];
                            Array.Copy(realArgs, mb.arguments, realArgs.Length - 1);
                        }
                        else
                        {
                            mb.instance  = Instance;
                            mb.arguments = realArgs;
                        }
                    }
                    else
                    {
                        mb.arguments = realArgs;
                    }

                    if (!kwArgBinder.AllowUnboundArgs)
                    {
                        // we can have no better bindings!
                        bestBinding = mb;
                        break;
                    }

                    if (bestBinding.method == null ||
                        (kwArgBinder.UnboundArgs == null ||
                         (bestUnboundArgs != null && bestUnboundArgs.Count > kwArgBinder.UnboundArgs.Count)))
                    {
                        bestBinding     = mb;
                        bestUnboundArgs = kwArgBinder.UnboundArgs;
                    }
                }
            }

            if (bestBinding.method != null)
            {
                // we've bound the arguments to a real method,
                // finally we're going to dispatch back to the
                // optimized version of the calls.
                object ret = Call(bestBinding.arguments);

                // any unbound arguments left over we assume the user
                // wants to do a property set with.  We'll go ahead and try
                // that - if they fail we'll throw.
                if (bestUnboundArgs != null)
                {
                    ///!!! if we had a constructor w/ a ref param then we'll try
                    // updating the Tuple here instead of the user's object.

                    if (targets[0].DeclaringType.IsDefined(typeof(PythonTypeAttribute), false))
                    {
                        throw Ops.TypeError("'{0}' is an invalid keyword argument for this function",
                                            bestUnboundArgs[0].Name,
                                            Name);
                    }

                    for (int j = 0; j < bestUnboundArgs.Count; j++)
                    {
                        Ops.SetAttr(DefaultContext.Default, ret,
                                    SymbolTable.StringToId(bestUnboundArgs[j].Name),
                                    bestUnboundArgs[j].Value);
                    }
                }

                return(ret);
            }

            if (kwArgBinder.GetError() != null)
            {
                throw kwArgBinder.GetError();
            }

            throw Ops.TypeError("bad number of arguments for function {0}", FriendlyName);
        }
Ejemplo n.º 5
0
        private void AddInvocable(InvocableBinding invocableBinding)
        {
            InvokeParameter[] parameters = invocableBinding.GetParameters();

            // Note: Don't use <= otherwise we will never see an IntelliPromt for methods/functions
            //       with no parameters.

            if (parameters.Length < _parameterIndex)
            {
                return;
            }

            StringBuilder sb = new StringBuilder();

            using (StringWriter sw = new StringWriter(sb, CultureInfo.CurrentCulture))
            {
                XmlWriter writer = new XmlTextWriter(sw);

                if (invocableBinding.ReturnType != null)
                {
                    writer.WriteString(invocableBinding.ReturnType.Name);
                    writer.WriteWhitespace(" ");
                }

                MethodBinding methodBinding = invocableBinding as MethodBinding;
                if (methodBinding != null)
                {
                    writer.WriteString(methodBinding.DeclaringType.Name);
                    writer.WriteString(".");
                }

                writer.WriteString(invocableBinding.Name);

                bool highlighParentheses = (_parameterIndex == 0 && parameters.Length == 0);

                if (highlighParentheses)
                {
                    writer.WriteStartElement("b");
                }
                writer.WriteString(" (");
                if (highlighParentheses)
                {
                    writer.WriteEndElement();
                }

                for (int i = 0; i < parameters.Length; i++)
                {
                    if (i > 0)
                    {
                        writer.WriteString(", ");
                    }

                    bool isSelectedParameter = (i == _parameterIndex);

                    if (isSelectedParameter)
                    {
                        writer.WriteStartElement("b");
                    }

                    writer.WriteString(parameters[i].Name);
                    writer.WriteString(": ");
                    writer.WriteString(parameters[i].DataType.Name);

                    if (isSelectedParameter)
                    {
                        writer.WriteEndElement();
                    }
                }

                if (highlighParentheses)
                {
                    writer.WriteStartElement("b");
                }
                writer.WriteString(")");
                if (highlighParentheses)
                {
                    writer.WriteEndElement();
                }
            }

            _infoTip.Info.Add(sb.ToString());
        }
Ejemplo n.º 6
0
 public void AcceptMethod(MethodBinding method)
 {
     AddInvocable(method);
 }
Ejemplo n.º 7
0
 /// <summary>An annotation that specifies a method, property or constructor to patch</summary>
 /// <param name="methodBinding">The <see cref="MethodBinding"/></param>
 /// <param name="argumentTypes">An array of argument types to target overloads</param>
 /// <param name="argumentVariations">An array of <see cref="ArgumentType"/></param>
 ///
 public HarmonyDelegate(MethodBinding methodBinding, Type[] argumentTypes, ArgumentType[] argumentVariations)
     : base(MethodType.Normal, argumentTypes, argumentVariations)
 {
     info.virtualDelegate = methodBinding == MethodBinding.CallVirtually;
 }
Ejemplo n.º 8
0
 /// <summary>An annotation that specifies a method, property or constructor to patch</summary>
 /// <param name="methodBinding">The <see cref="MethodBinding"/></param>
 /// <param name="argumentTypes">An array of argument types to target overloads</param>
 ///
 public HarmonyDelegate(MethodBinding methodBinding, params Type[] argumentTypes)
     : base(MethodType.Normal, argumentTypes)
 {
     info.virtualDelegate = methodBinding == MethodBinding.CallVirtually;
 }
Ejemplo n.º 9
0
 /// <summary>An annotation that specifies call dispatching mechanics for the delegate</summary>
 /// <param name="methodBinding">The <see cref="MethodBinding"/></param>
 ///
 public HarmonyDelegate(MethodBinding methodBinding)
 {
     info.virtualDelegate = methodBinding == MethodBinding.CallVirtually;
 }
Ejemplo n.º 10
0
 /// <summary>An annotation that specifies a method, property or constructor to patch</summary>
 /// <param name="methodName">The name of the method, property or constructor to patch</param>
 /// <param name="methodBinding">The <see cref="MethodBinding"/></param>
 ///
 public HarmonyDelegate(string methodName, MethodBinding methodBinding)
     : base(methodName, MethodType.Normal)
 {
     info.virtualDelegate = methodBinding == MethodBinding.CallVirtually;
 }
Ejemplo n.º 11
0
 /// <summary>An annotation that specifies a method, property or constructor to patch</summary>
 /// <param name="declaringType">The declaring class/type</param>
 /// <param name="methodBinding">The <see cref="MethodBinding"/></param>
 ///
 public HarmonyDelegate(Type declaringType, MethodBinding methodBinding)
     : base(declaringType, MethodType.Normal)
 {
     info.virtualDelegate = methodBinding == MethodBinding.CallVirtually;
 }
Ejemplo n.º 12
0
 public object Next(HandleMethod method, MethodBinding binding,
                    IHandler composer, NextDelegate <object> next)
 {
     Console.WriteLine($"Handle method {method.Method.Name}");
     return(next());
 }
Ejemplo n.º 13
0
        internal object CallHelper(ICallerContext context, object[] args, string[] names, object instance)
        {
            // we allow kw-arg binding to ctor's of arbitrary CLS types, but
            // NOT Python built-in types.  After the ctor succeeds we'll set the kw args as
            // arbitrary properties on the CLS type.  If this ends up being a built-in type we'll
            // do the check when we're going to set the kw-args.  This accomplishes 2 things:
            //      1. Our error messages match CPython more closely
            //      2. The attribute lookup is done lazily only if kw-args are supplied to a ctor

            CoerceArgs(context, ref args, ref instance);

            KwArgBinder kwArgBinder = new KwArgBinder(context, args, names, targets[0].IsConstructor);
            MethodBinding bestBinding = new MethodBinding();
            List<UnboundArgument> bestUnboundArgs = null;

            for (int i = 0; i < targets.Length; i++) {
                object[] realArgs = kwArgBinder.DoBind(targets[i], Name);

                if (realArgs != null) {
                    MethodBinding mb = new MethodBinding();
                    mb.method = targets[i];

                    if (!CompilerHelpers.IsStatic(targets[i])) {
                        if (instance == null) {
                            if (realArgs.Length == 0) {
                                throw Ops.TypeError("bad number of arguments for function {0}", targets[0].Name);
                            }
                            mb.instance = realArgs[0];
                            mb.arguments = new object[realArgs.Length - 1];
                            Array.Copy(realArgs, mb.arguments, realArgs.Length - 1);
                        } else {
                            mb.instance = instance;
                            mb.arguments = realArgs;
                        }
                    } else {
                        mb.arguments = realArgs;
                    }

                    if (!kwArgBinder.AllowUnboundArgs) {
                        // we can have no better bindings!
                        bestBinding = mb;
                        break;
                    }

                    if (bestBinding.method == null ||
                        (kwArgBinder.UnboundArgs == null ||
                        (bestUnboundArgs != null && bestUnboundArgs.Count > kwArgBinder.UnboundArgs.Count))) {
                        bestBinding = mb;
                        bestUnboundArgs = kwArgBinder.UnboundArgs;
                    }

                }
            }

            if (bestBinding.method != null) {
                // we've bound the arguments to a real method,
                // finally we're going to dispatch back to the
                // optimized version of the calls.
                object[] callArgs = bestBinding.arguments;

                ParameterInfo[] pis = bestBinding.method.GetParameters();
                object[] dynamicArgs = new object[pis.Length];
                for (int i = 0; i < pis.Length; i++) {
                    dynamicArgs[i] = Ops.GetDynamicTypeFromType(pis[i].ParameterType);
                }
                FastCallable fc = (FastCallable)Overloads.GetKeywordArgumentOverload(new Tuple(true, dynamicArgs));
                object ret;
                if (instance == null) ret = fc.Call(context, callArgs);
                else ret = fc.CallInstance(context, instance, callArgs);

                // any unbound arguments left over we assume the user
                // wants to do a property set with.  We'll go ahead and try
                // that - if they fail we'll throw.
                if (bestUnboundArgs != null) {
                    // if we had a constructor w/ a ref param then we'll try
                    // updating the Tuple here instead of the user's object.

                    if (targets[0].DeclaringType.IsDefined(typeof(PythonTypeAttribute), false)) {
                        // calling ctor w/ kw-args w/ zero args, let it go, don't do any sets.
                        if (args.Length == names.Length) return ret;

                        throw Ops.TypeError("'{0}' is an invalid keyword argument for this function",
                            bestUnboundArgs[0].Name,
                            Name);
                    }

                    for (int j = 0; j < bestUnboundArgs.Count; j++) {
                        Ops.SetAttr(DefaultContext.Default, ret,
                            SymbolTable.StringToId(bestUnboundArgs[j].Name),
                            bestUnboundArgs[j].Value);
                    }
                }

                return ret;
            }

            if (kwArgBinder.GetError() != null) {
                throw kwArgBinder.GetError();
            }

            throw Ops.TypeError("bad number of arguments for function {0}", FriendlyName);
        }
Ejemplo n.º 14
0
 public object Next(
     object callback, MethodBinding method, IHandler composer, NextDelegate <object> next)
 {
     return(null);
 }
Ejemplo n.º 15
0
 public T Next(object callback, MethodBinding method, IHandler composer, NextDelegate <T> next)
 {
     return(default(T));
 }
Ejemplo n.º 16
0
 public void AcceptMethod(MethodBinding method)
 {
 }