예제 #1
0
        public void GetTypeInheritanceTreeOfStringArray()
        {
            List <string> results = new List <IReturnType>(
                MemberLookupHelper.GetTypeInheritanceTree(new ArrayReturnType(msc, msc.SystemTypes.String, 1))
                ).ConvertAll <string>(delegate(IReturnType rt) { return(rt.DotNetName); });

            results.Sort();             // order is not guaranteed, so sort for the unit test

            Assert.AreEqual("System.Collections.Generic.ICollection{System.String};" +
                            "System.Collections.Generic.IEnumerable{System.String};" +
                            "System.Collections.Generic.IList{System.String};" +
                            "System.Collections.ICollection;" +
                            "System.Collections.IEnumerable;" +
                            "System.Collections.IList;" +
                            "System.Object;" +
                            "System.String[]",
                            string.Join(";", results.ToArray()));
        }
        void CreateInterfaceImplementations(IMember currentMember, ParametrizedNode memberDecl, List <InterfaceImplementation> interfaceImplementations)
        {
            if (currentMember != null &&
                (memberDecl.Modifier & Modifiers.Visibility) == Modifiers.None &&
                interfaceImplementations.Count == 1)
            {
                // member is explicitly implementing an interface member
                // to convert explicit interface implementations to VB, make the member private
                // and ensure its name does not collide with another member
                memberDecl.Modifier |= Modifiers.Private;
                memberDecl.Name      = interfaceImplementations[0].InterfaceType.Type.Replace('.', '_') + "_" + memberDecl.Name;
            }

            if (currentMember != null && currentMember.IsPublic &&
                currentMember.DeclaringType.ClassType != ClassType.Interface)
            {
                // member could be implicitly implementing an interface member,
                // search for interfaces containing the member
                foreach (IReturnType directBaseType in currentMember.DeclaringType.GetCompoundClass().BaseTypes)
                {
                    IClass directBaseClass = directBaseType.GetUnderlyingClass();
                    if (directBaseClass != null && directBaseClass.ClassType == ClassType.Interface)
                    {
                        // include members inherited from other interfaces in the search:
                        foreach (IReturnType baseType in MemberLookupHelper.GetTypeInheritanceTree(directBaseType))
                        {
                            IClass baseClass = baseType.GetUnderlyingClass();
                            if (baseClass != null && baseClass.ClassType == ClassType.Interface)
                            {
                                IMember similarMember = MemberLookupHelper.FindSimilarMember(baseClass, currentMember);
                                // add an interface implementation for similarMember
                                // only when similarMember is not explicitly implemented by another member in this class
                                if (similarMember != null && !HasExplicitImplementationFor(similarMember, baseType, memberDecl.Parent))
                                {
                                    interfaceImplementations.Add(new InterfaceImplementation(
                                                                     Refactoring.CodeGenerator.ConvertType(baseType, CreateContext()),
                                                                     currentMember.Name));
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        public void GetTypeInheritanceTreeOfClassDerivingFromListOfString()
        {
            List <string> results = new List <IReturnType>(
                MemberLookupHelper.GetTypeInheritanceTree(CreateClassDerivingFromListOfString().DefaultReturnType)
                ).ConvertAll <string>(delegate(IReturnType rt) { return(rt.DotNetName); });

            results.Sort();             // order is not guaranteed, so sort for the unit test

            Assert.AreEqual("DerivesFromList;" +
                            "System.Collections.Generic.ICollection{System.String};" +
                            "System.Collections.Generic.IEnumerable{System.String};" +
                            "System.Collections.Generic.IList{System.String};" +
                            "System.Collections.Generic.List{System.String};" +
                            "System.Collections.ICollection;" +
                            "System.Collections.IEnumerable;" +
                            "System.Collections.IList;" +
                            "System.Object",
                            string.Join(";", results.ToArray()));
        }
예제 #4
0
        /// <summary>
        /// Make lower bound inference from U for V.
        /// </summary>
        void MakeLowerBoundInference(IReturnType U, IReturnType V)
        {
            Log(" MakeLowerBoundInference from " + U + " for " + V);
            if (U == null || V == null)
            {
                return;
            }

            // If V is one of the unfixed Xi then U is added to the set of bounds for Xi.
            TP tp = GetTPForType(V);

            if (tp != null && tp.Fixed == false)
            {
                Log("  Add bound '" + U.DotNetName + "' to " + tp);
                tp.Bounds.Add(U);
                return;
            }
            // Otherwise if U is an array type Ue[…] and V is either an array type Ve[…]of the
            // same rank, or if U is a one­dimensional array type Ue[]and V is one of
            // IEnumerable<Ve>, ICollection<Ve> or IList<Ve> then
            ArrayReturnType       arrU = U.CastToArrayReturnType();
            ArrayReturnType       arrV = V.CastToArrayReturnType();
            ConstructedReturnType CV   = V.CastToConstructedReturnType();

            if (arrU != null &&
                (arrV != null && arrU.ArrayDimensions == arrV.ArrayDimensions ||
                 (arrU.ArrayDimensions == 1 && IsIEnumerableCollectionOrList(CV))))
            {
                IReturnType Ue = arrU.ArrayElementType;
                IReturnType Ve = arrV != null ? arrV.ArrayElementType : CV.TypeArguments[0];
                // If Ue is known to be a reference type then a lower­bound inference from Ue to Ve is made
                if (IsReferenceType(Ue) ?? false)
                {
                    MakeLowerBoundInference(Ue, Ve);
                }
                else
                {
                    // Otherwise an exact inference from Ue to Ve is made
                    MakeExactInference(Ue, Ve);
                }
                return;
            }
            // Otherwise if V is a constructed type C<V1…Vk> and there is a unique set of
            // types U1…Uk such that a standard implicit conversion exists from U to C<U1…Uk>
            // then an exact inference is made from each Ui for the corresponding Vi.
            if (CV != null)
            {
                foreach (IReturnType U2 in MemberLookupHelper.GetTypeInheritanceTree(U))
                {
                    ConstructedReturnType CU2 = U2.CastToConstructedReturnType();
                    if (CU2 != null &&
                        object.Equals(CU2.UnboundType, CV.UnboundType) &&
                        CU2.TypeArgumentCount == CV.TypeArgumentCount &&
                        CU2.TypeArguments.Count == CU2.TypeArgumentCount &&                     // unfortunately these might not be the same...
                        CV.TypeArguments.Count == CV.TypeArgumentCount)
                    {
                        for (int i = 0; i < CU2.TypeArgumentCount; i++)
                        {
                            MakeExactInference(CU2.TypeArguments[i], CV.TypeArguments[i]);
                        }
                        return;
                    }
                }
            }
        }