Beispiel #1
0
        /// <summary>
        /// A version of Implements that works over instantiated types and methods.
        ///
        /// t-devinc: Not entirely convinced this is correct.
        /// </summary>
        /// <param name="derived"></param>
        /// <param name="upto"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        internal static IMethodDefinition ImplementsInstantiated(ITypeDefinition derived, IMethodDefinition m)
        {
            Contract.Requires(derived != null);
            Contract.Requires(!(derived is Dummy));
            Contract.Requires(m != null);
            Contract.Requires(!(m is Dummy));

            Contract.Requires(TypeHelper.Type1DerivesFromOrIsTheSameAsType2(derived, m.ContainingTypeDefinition));

            Contract.Requires(!derived.IsInterface);

            Contract.Ensures(Contract.Result <IMethodDefinition>() != null);
            Contract.Ensures(!(Contract.Result <IMethodDefinition>() is Dummy));

            var classHierarchyChain = new ITypeDefinition[] { derived }.Concat(GarbageCollectHelper.AllSuperClasses(derived));

            foreach (var classInHierarchy in classHierarchyChain)
            {
                IMethodDefinition specializedImplementation = ImplementationForMethodInClass(m, classInHierarchy);

                if (specializedImplementation != null)
                {
                    return(specializedImplementation);
                }
            }

            // We shouldn't get here
            return(null);
        }
Beispiel #2
0
        /// <summary>
        /// Find possible implementations of m for derived, upto (and including) 'upto').
        ///
        /// If m is an unspecialized generic interface, they may be multiple possible implementations; at this
        /// point we can't tell which one would be called since we've removed all specialization from m.
        ///
        /// We require 'derived' to be unspecialized, but note that its super types may be specialized.
        /// We require 'm' to be unspecialized.
        ///
        /// </summary>
        internal static ICollection <IMethodDefinition> Implements(ITypeDefinition derived, ITypeDefinition upto, IMethodDefinition m)
        {
            Contract.Requires(derived != null);
            Contract.Requires(!(derived is Dummy));
            Contract.Requires(upto != null);
            Contract.Requires(!(upto is Dummy));
            Contract.Requires(m != null);
            Contract.Requires(!(m is Dummy));
            Contract.Requires(GarbageCollectHelper.TypeDefinitionIsUnspecialized(derived));

            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(m));

            Contract.Requires(!derived.IsInterface);

            Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM => GarbageCollectHelper.MethodDefinitionIsUnspecialized(resultM)));
            Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM =>
                                             resultM != null && !(resultM is Dummy))
                             );

            ISet <IMethodDefinition> foundImplementations = new HashSet <IMethodDefinition>();

            // If derived implements an interface multiple times, there may be multiple specialized versions for derived
            IEnumerable <IMethodDefinition> versionsOfMSpecializedForDerived = SearchSpecializedHierarchyForVersionOfMethod(derived, m);

            var classHierarchyChain = new ITypeDefinition[] { derived }.Concat(GarbageCollectHelper.AllSuperClasses(derived));


            foreach (IMethodDefinition mSpecializedForDerived in versionsOfMSpecializedForDerived)
            {
                // Check explicit implementation overrides before implicit methods
                IMethodDefinition foundImplementation = null;

                foreach (var classInHierarchy in classHierarchyChain)
                {
                    IMethodDefinition specializedImplementation = ImplementationForMethodInClass(mSpecializedForDerived, classInHierarchy);

                    if (specializedImplementation != null)
                    {
                        foundImplementation = specializedImplementation;
                        break;
                    }

                    if (TypeHelper.TypesAreEquivalent(GarbageCollectHelper.UnspecializeAndResolveTypeReference(classInHierarchy), upto))
                    {
                        break;
                    }
                }

                // Do we really expect to find an implementation for EACH mSpecializedForDerived; or do we expect to find at least one overall all?
                Contract.Assert(foundImplementation != null);

                foundImplementations.Add(GarbageCollectHelper.UnspecializeAndResolveMethodReference(foundImplementation));
            }

            return(foundImplementations);
        }
Beispiel #3
0
        /// <summary>
        /// Find possible implementations of m for derived, upto (and including) 'upto').
        ///
        /// If m is an unspecialized generic interface, they may be multiple possible implementations; at this
        /// point we can't tell which one would be called since we've removed all specialization from m.
        ///
        /// We require 'derived' to be unspecialized, but note that its super types may be specialized.
        /// We require 'm' to be unspecialized.
        ///
        /// </summary>
        internal static ICollection <IMethodDefinition> Implements(ITypeDefinition derived, ITypeDefinition upto, IMethodDefinition m)
        {
            Contract.Requires(derived != null);
            Contract.Requires(!(derived is Dummy));
            Contract.Requires(upto != null);
            Contract.Requires(!(upto is Dummy));
            Contract.Requires(m != null);
            Contract.Requires(!(m is Dummy));
            Contract.Requires(GarbageCollectHelper.TypeDefinitionIsUnspecialized(derived));

            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(m));

            Contract.Requires(!derived.IsInterface);

            Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM => GarbageCollectHelper.MethodDefinitionIsUnspecialized(resultM)));
            Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM =>
                                             resultM != null && !(resultM is Dummy))
                             );

            ISet <IMethodDefinition> foundImplementations = new HashSet <IMethodDefinition>();

            // If derived implements an interface multiple times, there may be multiple specialized versions for derived
            IEnumerable <IMethodDefinition> versionsOfMSpecializedForDerived = SearchSpecializedHierarchyForVersionOfMethod(derived, m);

            var classHierarchyChain = new ITypeDefinition[] { derived }.Concat(GarbageCollectHelper.AllSuperClasses(derived));

            foreach (IMethodDefinition mSpecializedForDerived in versionsOfMSpecializedForDerived)
            {
                IMethodDefinition foundImplementation = null;

                // If this is a method defined on an inteface, we must first search the hierarchy for explicit implementations,
                // since an explicit implementation on a base type supercedes an implicit implementation on a derived type

                if (m.ContainingTypeDefinition.IsInterface)
                {
                    foreach (var classInHierarchy in classHierarchyChain)
                    {
                        foreach (IMethodImplementation methodImplementation in classInHierarchy.ExplicitImplementationOverrides)
                        {
                            if (methodImplementation.ImplementedMethod.InternedKey == mSpecializedForDerived.InternedKey)
                            {
                                foundImplementation = methodImplementation.ImplementingMethod.ResolvedMethod;
                                break;
                            }
                        }
                        if (foundImplementation != null)
                        {
                            break;
                        }
                        if (TypeHelper.TypesAreEquivalent(GarbageCollectHelper.UnspecializeAndResolveTypeReference(classInHierarchy), upto))
                        {
                            break;
                        }
                    }
                }

                // If we found an explicit implementation, don't seach for an implicit one

                if (foundImplementation == null)
                {
                    foreach (var classInHierarchy in classHierarchyChain)
                    {
                        foundImplementation = ImplementationForMethodInClass(mSpecializedForDerived, classInHierarchy);
                        if (foundImplementation != null)
                        {
                            break;
                        }
                        if (TypeHelper.TypesAreEquivalent(GarbageCollectHelper.UnspecializeAndResolveTypeReference(classInHierarchy), upto))
                        {
                            break;
                        }
                    }
                }

                // Do we really expect to find an implementation for EACH mSpecializedForDerived; or do we expect to find at least one overall all?
                Contract.Assert(foundImplementation != null);

                foundImplementations.Add(GarbageCollectHelper.UnspecializeAndResolveMethodReference(foundImplementation));
            }

            return(foundImplementations);
        }