示例#1
0
        /// <summary>
        /// Resolves best method to be overriden.
        /// </summary>
        /// <param name="method">The override.</param>
        /// <returns>Candidate to be overriden by given <paramref name="method"/>.</returns>
        public static MethodSymbol ResolveOverride(this SourceMethodSymbol method)
        {
            Contract.ThrowIfNull(method);

            if (method.IsStatic || method.DeclaredAccessibility == Accessibility.Private)
            {
                return(null);    // static or private methods can't be overrides
            }

            //
            var          bestCost      = ConversionCost.Error;
            MethodSymbol bestCandidate = null;

            // enumerate types in descending order and
            // find best candidate to be overriden

            // once a type defines method with same name, we have to ignore all its overriden methods (they are overriden already)

            var overriden = new HashSet <MethodSymbol>();    // set of methods we will ignore, they are already overriden

            foreach (var t in EnumerateOverridableTypes(method.ContainingType))
            {
                foreach (var m in t.GetMembers(method.Name).OfType <MethodSymbol>())
                {
                    if (overriden.Contains(m))
                    {
                        continue;
                    }

                    var cost = OverrideCost(method, m);
                    if (cost < bestCost && IsAllowedCost(cost))
                    {
                        bestCost      = cost;
                        bestCandidate = m;

                        if (cost == ConversionCost.Pass)
                        {
                            return(bestCandidate);
                        }
                    }

                    // remember m's base declaration cannot be overriden again
                    var mbase = m.OverriddenMethod;
                    if (mbase != null)
                    {
                        overriden.Add((MethodSymbol)mbase);
                    }
                }
            }

            //
            return(bestCandidate);
        }
示例#2
0
        /// <summary>
        /// Resolves best method to be overriden.
        /// </summary>
        /// <param name="method">The override.</param>
        /// <returns>Candidate to be overriden by given <paramref name="method"/>.</returns>
        public static MethodSymbol ResolveOverride(this SourceMethodSymbol method)
        {
            Contract.ThrowIfNull(method);

            if (method.IsStatic || method.DeclaredAccessibility == Accessibility.Private)
            {
                return(null);    // static or private methods can't be overrides
            }

            //
            var          bestCost      = ConversionCost.Error;
            MethodSymbol bestCandidate = null;

            // enumerate types in descending order and
            // find best candidate to be overriden

            foreach (var t in EnumerateOverridableTypes(method.ContainingType))
            {
                foreach (var m in t.GetMembers(method.Name).OfType <MethodSymbol>())
                {
                    var cost = OverrideCost(method, m);
                    if (cost < bestCost && IsAllowedCost(cost))
                    {
                        bestCost      = cost;
                        bestCandidate = m;

                        if (cost == ConversionCost.Pass)
                        {
                            return(bestCandidate);
                        }
                    }
                }
            }


            //
            return(bestCandidate);
        }
示例#3
0
 /// <summary>
 /// Determines whether <paramref name="method"/> can override <paramref name="basemethod"/>.
 /// </summary>
 /// <param name="method">Source method.</param>
 /// <param name="basemethod">Overriden method.</param>
 public static bool CanBeOverride(SourceMethodSymbol method, MethodSymbol basemethod)
 {
     return(IsAllowedCost(OverrideCost(method, basemethod)));
 }
示例#4
0
        /// <summary>
        /// Calculates override cost, i.e. whether the override is possible and its value.
        /// In case of more possible overrides, the one with better cost is selected.
        /// </summary>
        /// <param name="method">Source method.</param>
        /// <param name="basemethod">A hypothetical base method.</param>
        /// <returns></returns>
        public static ConversionCost OverrideCost(SourceMethodSymbol method, MethodSymbol basemethod)
        {
            Contract.ThrowIfNull(method);
            Contract.ThrowIfNull(basemethod);

            //
            if (method.IsStatic || basemethod.IsStatic || basemethod.IsSealed ||
                (!basemethod.IsVirtual && !basemethod.IsAbstract) ||    // not abstract or virtual
                method.Name.EqualsOrdinalIgnoreCase(basemethod.Name) == false ||
                method.DeclaredAccessibility == Accessibility.Private || basemethod.DeclaredAccessibility == Accessibility.Private)
            {
                return(ConversionCost.NoConversion);
            }

            if (method.ReturnType != basemethod.ReturnType)
            {
                return(ConversionCost.ImplicitCast);
            }

            //
            var ps     = method.Parameters;
            var psbase = basemethod.Parameters;

            //
            var result = ConversionCost.Pass;

            // NOTE: there shouldn't be any implicit parameters (Context and LateBoundType are known from this instance)

            for (int i = 0; i < ps.Length; i++)
            {
                if (i < psbase.Length)
                {
                    var p     = ps[i];
                    var pbase = psbase[i];

                    if (p.Type != pbase.Type)
                    {
                        if (p.Type.IsOfType(pbase.Type))
                        {
                            result |= ConversionCost.ImplicitCast;
                        }
                        else
                        {
                            result |= ConversionCost.NoConversion;
                        }
                    }
                }
                else
                {
                    result |= ConversionCost.TooManyArgs;
                }
            }

            //
            if (ps.Length < psbase.Length)
            {
                result |= ConversionCost.MissingArgs;
            }

            //
            return(result);
        }
示例#5
0
        /// <summary>
        /// Calculates override cost, i.e. whether the override is possible and its value.
        /// In case of more possible overrides, the one with better cost is selected.
        /// </summary>
        /// <param name="method">Source method.</param>
        /// <param name="basemethod">A hypothetical base method.</param>
        /// <returns></returns>
        public static ConversionCost OverrideCost(SourceMethodSymbol method, MethodSymbol basemethod)
        {
            Contract.ThrowIfNull(method);
            Contract.ThrowIfNull(basemethod);

            //
            if (method.IsStatic || basemethod.IsStatic || basemethod.IsSealed ||
                (!basemethod.IsVirtual && !basemethod.IsAbstract) ||    // not abstract or virtual
                method.Name.EqualsOrdinalIgnoreCase(basemethod.Name) == false ||
                method.DeclaredAccessibility == Accessibility.Private || basemethod.DeclaredAccessibility == Accessibility.Private)
            {
                return ConversionCost.NoConversion;
            }

            if (method.ReturnType != basemethod.ReturnType)
            {
                return ConversionCost.ImplicitCast;
            }

            //
            var ps = method.Parameters;
            var psbase = basemethod.Parameters;

            //
            var result = ConversionCost.Pass;

            // NOTE: there shouldn't be any implicit parameters (Context and LateBoundType are known from this instance)

            for (int i = 0; i < ps.Length; i++)
            {
                if (i < psbase.Length)
                {
                    var p = ps[i];
                    var pbase = psbase[i];

                    if (p.Type != pbase.Type)
                    {
                        if (p.Type.IsOfType(pbase.Type))
                        {
                            result |= ConversionCost.ImplicitCast;
                        }
                        else
                        {
                            result |= ConversionCost.NoConversion;
                        }
                    }
                }
                else
                {
                    result |= ConversionCost.TooManyArgs;
                }
            }

            //
            if (ps.Length < psbase.Length)
            {
                result |= ConversionCost.MissingArgs;
            }

            //
            return result;
        }
示例#6
0
 /// <summary>
 /// Determines whether <paramref name="method"/> can override <paramref name="basemethod"/>.
 /// </summary>
 /// <param name="method">Source method.</param>
 /// <param name="basemethod">Overriden method.</param>
 public static bool CanBeOverride(SourceMethodSymbol method, MethodSymbol basemethod)
 {
     return IsAllowedCost(OverrideCost(method, basemethod));
 }