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); } } }
public AITreeNode(MethodBinding methodBinding, long guid, params AITreeNode[] children) { this.methodBinding = methodBinding; this.children = children; this.guid = guid; }
/// <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)); } }
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); }
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()); }
public void AcceptMethod(MethodBinding method) { AddInvocable(method); }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
public object Next(HandleMethod method, MethodBinding binding, IHandler composer, NextDelegate <object> next) { Console.WriteLine($"Handle method {method.Method.Name}"); return(next()); }
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); }
public object Next( object callback, MethodBinding method, IHandler composer, NextDelegate <object> next) { return(null); }
public T Next(object callback, MethodBinding method, IHandler composer, NextDelegate <T> next) { return(default(T)); }
public void AcceptMethod(MethodBinding method) { }