public static MethodTracker[] GetTrackerArray(MethodBase[] infos) { MethodTracker[] res = new MethodTracker[infos.Length]; for (int i = 0; i < res.Length; i++) { res[i] = new MethodTracker(infos[i]); } return(res); }
private static int GetPythonExposedArgCount(MethodTracker method) { int baseArgs = method.StaticArgs; ParameterInfo[] pis = method.GetParameters(); for (int i = 0; i < pis.Length; i++) { if (pis[i].IsOut && !pis[i].IsIn) { baseArgs--; } } return(baseArgs); }
public void AddMethod(MethodTracker method) { #if DEBUG if (fFinished) { throw new InvalidOperationException("Cannot add methods to finished param trees"); } #endif ParamTreeNode curNode = this; ParameterInfo[] pis = method.GetParameters(); bool fIsParams = false; if (pis.Length > 0 && ReflectionUtil.IsParamArray(pis[pis.Length - 1])) { fIsParams = true; } if (!method.IsStatic) { Type instType = method.DeclaringType; if ((funcType & FunctionType.FunctionMethodMask) == FunctionType.FunctionMethodMask) { instType = typeof(InstanceArgument); } curNode = curNode.AppendChild(method, instType, NodeFlags.None, argumentCount == 1); AppendParameters(method, curNode, pis, fIsParams, 1, 0); } else { int depthStart = 0; if ((funcType & FunctionType.OpsFunction) != 0 && (funcType & FunctionType.FunctionMethodMask) == FunctionType.FunctionMethodMask) { // this is an ops function that is combined w/ an ops method. We need to support // disambiguating between bound & unbound method calls, so we transform arg 1 // to an instance just like we do for non-static functions, and then skip the 1st // parameter in AppendParameters. In either case we want both depths to // start at 1 (we're appending @ depth 1, and reading from param 1 because we've // used param 0) so we just use depthStart here for both. depthStart = 1; curNode = curNode.AppendChild(method, typeof(InstanceArgument), NodeFlags.None, argumentCount == 1); } AppendParameters(method, curNode, pis, fIsParams, depthStart, depthStart); } Methods.Add(method); }
public ParamTreeNode AppendChild(MethodTracker method, Type curType, ParamTree.NodeFlags flags, bool fLastArg) { bool fFound = false; ParamTreeNode res = this; for (int i = 0; i < Children.Count; i++) { if (Children[i].ParamType == curType && Children[i].Flags == flags) { res = Children[i]; res.Methods.Add(method); fFound = true; break; } } if (!fFound) { res = InsertNewNode(curType, flags); res.Methods.Add(method); } else if (fLastArg) { // last node, we shouldn't be adding // extra methods here. We have two ways // we get here: // 1. We have a static and non-static overload, prefer the instance method // 2. We have default values for one of the methods, prefer the one w/o defaults. // // Both of these are identical checks: We prefer the method w/ less parameters. Debug.Assert(res.Methods.Count == 2); if (method.GetParameters().Length < res.Methods[0].GetParameters().Length) { // remove the old one. res.Methods.RemoveAt(0); } else { // remove the new one. res.Methods.RemoveAt(1); } } return(res); }
private MethodBinder(string name, MethodTracker[] methods, bool isBinaryOperator) { this.name = name; this.isBinaryOperator = isBinaryOperator; foreach (MethodTracker method in methods) { if (IsUnsupported(method)) continue; if (methods.Length > 1 && IsKwDictMethod(method)) continue; AddBasicMethodTargets(method); } foreach (ParamsMethodMaker maker in paramsMakers) { foreach (int count in targetSets.Keys) { MethodTarget target = maker.MakeTarget(count); if (target != null) AddTarget(target); } } }
private void AppendParameters(MethodTracker method, ParamTreeNode curNode, ParameterInfo[] pis, bool fIsParams, int depthStart, int pisStart) { int argCnt = argumentCount; for (int i = depthStart; i < argCnt; i++) { NodeFlags flags; Type curType = GetCurrentType(pis, i - depthStart + pisStart, fIsParams, out flags); if ((flags & NodeFlags.Out) != 0 && (i - depthStart + pisStart) < pis.Length) { // got an out param, need one more argument still... argCnt++; } bool fLastArg = (i == argumentCount - 1); curNode = curNode.AppendChild(method, curType, flags, fLastArg); } }
private static bool MatchesArgCount(MethodTracker method, int sigLen, int paramLen) { return(paramLen == sigLen || (paramLen > sigLen && (paramLen - method.DefaultCount) <= sigLen)); }
public MethodTarget(MethodTracker method, List<Parameter> parameters, ArgBuilder instanceBuilder, List<ArgBuilder> argBuilders, ReturnBuilder returnBuilder) { this.method = method; this.parameters = parameters; this.instanceBuilder = instanceBuilder; this.argBuilders = argBuilders; this.returnBuilder = returnBuilder; parameters.TrimExcess(); argBuilders.TrimExcess(); }
private void AddBasicMethodTargets(MethodTracker method) { List<Parameter> parameters = new List<Parameter>(); int argIndex = 0; ArgBuilder instanceBuilder; if (!method.IsStatic) { parameters.Add(new Parameter(method.DeclaringType)); instanceBuilder = new SimpleArgBuilder(argIndex++, parameters[0]); } else { instanceBuilder = new NullArgBuilder(); } List<ArgBuilder> argBuilders = new List<ArgBuilder>(); List<ArgBuilder> defaultBuilders = new List<ArgBuilder>(); bool hasByRef = false; foreach (ParameterInfo pi in method.GetParameters()) { if (pi.ParameterType == typeof(ICallerContext)) { argBuilders.Add(new ContextArgBuilder()); continue; } if (pi.DefaultValue != DBNull.Value) { defaultBuilders.Add(new DefaultArgBuilder(pi.ParameterType, pi.DefaultValue)); } else if (defaultBuilders.Count > 0) { // If we get a bad method with non-contiguous default values, then just use the contiguous list defaultBuilders.Clear(); } if (pi.ParameterType.IsByRef) { hasByRef = true; Parameter param = new ByRefParameter(pi.ParameterType.GetElementType(), pi.IsOut && !pi.IsIn); parameters.Add(param); argBuilders.Add(new ReferenceArgBuilder(argIndex++, param)); } else { Parameter param = new Parameter(pi.ParameterType); parameters.Add(param); argBuilders.Add(new SimpleArgBuilder(argIndex++, param)); } } ReturnBuilder returnBuilder = new ReturnBuilder(CompilerHelpers.GetReturnType(method.Method)); for (int i = 1; i < defaultBuilders.Count + 1; i++) { List<ArgBuilder> defaultArgBuilders = argBuilders.GetRange(0, argBuilders.Count - i); defaultArgBuilders.AddRange(defaultBuilders.GetRange(defaultBuilders.Count - i, i)); AddTarget(new MethodTarget(method, parameters.GetRange(0, parameters.Count - i), instanceBuilder, defaultArgBuilders, returnBuilder)); } if (hasByRef) AddSimpleTarget(MakeByRefReducedMethodTarget(method, parameters, instanceBuilder, argBuilders)); AddSimpleTarget(new MethodTarget(method, parameters, instanceBuilder, argBuilders, returnBuilder)); }
private static MethodTarget MakeByRefReducedMethodTarget(MethodTracker method, List<Parameter> parameters, ArgBuilder instanceBuilder, List<ArgBuilder> argBuilders) { List<Parameter> newParameters = new List<Parameter>(); foreach (Parameter param in parameters) { ByRefParameter p = param as ByRefParameter; if (p != null) { if (!p.IsOutOnly) { newParameters.Add(p.MakeInParameter()); } } else { newParameters.Add(param); } } List<int> returnArgs = new List<int>(); if (CompilerHelpers.GetReturnType(method.Method) != typeof(void)) { returnArgs.Add(-1); } int index = 0; int outParams = 0; List<ArgBuilder> newArgBuilders = new List<ArgBuilder>(); foreach (ArgBuilder ab in argBuilders) { ReferenceArgBuilder rab = ab as ReferenceArgBuilder; if (rab != null) { returnArgs.Add(index); if (((ByRefParameter)rab.parameter).IsOutOnly) { newArgBuilders.Add(new NullArgBuilder()); outParams++; } else { newArgBuilders.Add(new SimpleArgBuilder(rab.index - outParams, ((ByRefParameter)rab.parameter).MakeInParameter())); } } else { SimpleArgBuilder asb = ab as SimpleArgBuilder; if (asb != null) { newArgBuilders.Add(new SimpleArgBuilder(asb.index - outParams, asb.parameter)); } else { newArgBuilders.Add(ab); } } index++; } return new MethodTarget(method, newParameters, instanceBuilder, newArgBuilders, new ByRefReturnBuilder(CompilerHelpers.GetReturnType(method.Method), returnArgs)); }
private static bool IsUnsupported(MethodTracker method) { return (method.Method.CallingConvention & CallingConventions.VarArgs) != 0 || method.Method.ContainsGenericParameters; }
private static bool IsKwDictMethod(MethodTracker method) { ParameterInfo[] pis = method.GetParameters(); for (int i = pis.Length - 1; i >= 0; i--) { if (pis[i].IsDefined(typeof(ParamDictAttribute), false)) return true; } return false; }
public static MethodTracker[] GetTrackerArray(MethodBase[] infos) { MethodTracker[] res = new MethodTracker[infos.Length]; for (int i = 0; i < res.Length; i++) res[i] = new MethodTracker(infos[i]); return res; }