コード例 #1
0
 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);
 }
コード例 #2
0
ファイル: ParamTree.cs プロジェクト: weimingtom/IronPythonMod
        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);
        }
コード例 #3
0
ファイル: ParamTree.cs プロジェクト: weimingtom/IronPythonMod
        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);
        }
コード例 #4
0
ファイル: ParamTree.cs プロジェクト: weimingtom/IronPythonMod
        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);
        }
コード例 #5
0
        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);
                }
            }
        }
コード例 #6
0
ファイル: ParamTree.cs プロジェクト: weimingtom/IronPythonMod
        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);
            }
        }
コード例 #7
0
ファイル: ParamTree.cs プロジェクト: weimingtom/IronPythonMod
 private static bool MatchesArgCount(MethodTracker method, int sigLen, int paramLen)
 {
     return(paramLen == sigLen || (paramLen > sigLen && (paramLen - method.DefaultCount) <= sigLen));
 }
コード例 #8
0
            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();
            }
コード例 #9
0
        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));
        }
コード例 #10
0
        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));
        }
コード例 #11
0
 private static bool IsUnsupported(MethodTracker method)
 {
     return (method.Method.CallingConvention & CallingConventions.VarArgs) != 0
         || method.Method.ContainsGenericParameters;
 }
コード例 #12
0
 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;
 }
コード例 #13
0
 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;
 }