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); }
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); } }