int BetterConversion(Type s, Type t1, Type t2)
        {
            IType sType  = compilation.FindType(s);
            IType t1Type = compilation.FindType(t1);
            IType t2Type = compilation.FindType(t2);

            return(conversions.BetterConversion(sType, t1Type, t2Type));
        }
Example #2
0
        /// <summary>
        /// Returns 1 if c1 is better than c2; 2 if c2 is better than c1; or 0 if neither is better.
        /// </summary>
        int BetterFunctionMember(Candidate c1, Candidate c2)
        {
            // prefer applicable members (part of heuristic that produces a best candidate even if none is applicable)
            if (c1.ErrorCount == 0 && c2.ErrorCount > 0)
            {
                return(1);
            }
            if (c1.ErrorCount > 0 && c2.ErrorCount == 0)
            {
                return(2);
            }

            // C# 4.0 spec: ยง7.5.3.2 Better function member
            bool c1IsBetter = false;
            bool c2IsBetter = false;

            for (int i = 0; i < arguments.Length; i++)
            {
                int p1 = c1.ArgumentToParameterMap[i];
                int p2 = c2.ArgumentToParameterMap[i];
                if (p1 >= 0 && p2 < 0)
                {
                    c1IsBetter = true;
                }
                else if (p1 < 0 && p2 >= 0)
                {
                    c2IsBetter = true;
                }
                else if (p1 >= 0 && p2 >= 0)
                {
                    switch (conversions.BetterConversion(arguments[i], c1.ParameterTypes[p1], c2.ParameterTypes[p2]))
                    {
                    case 1:
                        c1IsBetter = true;
                        break;

                    case 2:
                        c2IsBetter = true;
                        break;
                    }
                }
            }
            if (c1IsBetter && !c2IsBetter)
            {
                return(1);
            }
            if (!c1IsBetter && c2IsBetter)
            {
                return(2);
            }

            // prefer members with less errors (part of heuristic that produces a best candidate even if none is applicable)
            if (c1.ErrorCount < c2.ErrorCount)
            {
                return(1);
            }
            if (c1.ErrorCount > c2.ErrorCount)
            {
                return(2);
            }

            if (!c1IsBetter && !c2IsBetter)
            {
                // we need the tie-breaking rules

                // non-generic methods are better
                if (!c1.IsGenericMethod && c2.IsGenericMethod)
                {
                    return(1);
                }
                else if (c1.IsGenericMethod && !c2.IsGenericMethod)
                {
                    return(2);
                }

                // non-expanded members are better
                if (!c1.IsExpandedForm && c2.IsExpandedForm)
                {
                    return(1);
                }
                else if (c1.IsExpandedForm && !c2.IsExpandedForm)
                {
                    return(2);
                }

                // prefer the member with less arguments mapped to the params-array
                int r = c1.ArgumentsPassedToParamsArray.CompareTo(c2.ArgumentsPassedToParamsArray);
                if (r < 0)
                {
                    return(1);
                }
                else if (r > 0)
                {
                    return(2);
                }

                // prefer the member where no default values need to be substituted
                if (!c1.HasUnmappedOptionalParameters && c2.HasUnmappedOptionalParameters)
                {
                    return(1);
                }
                else if (c1.HasUnmappedOptionalParameters && !c2.HasUnmappedOptionalParameters)
                {
                    return(2);
                }

                // compare the formal parameters
                r = MoreSpecificFormalParameters(c1, c2);
                if (r != 0)
                {
                    return(r);
                }

                // prefer non-lifted operators
                ILiftedOperator lift1 = c1.Member as ILiftedOperator;
                ILiftedOperator lift2 = c2.Member as ILiftedOperator;
                if (lift1 == null && lift2 != null)
                {
                    return(1);
                }
                if (lift1 != null && lift2 == null)
                {
                    return(2);
                }
            }
            return(0);
        }