예제 #1
0
        private static IEnumerable <AggregateType> AllPossibleInterfaces(TypeParameterType type)
        {
            foreach (AggregateType t in type.GetEffectiveBaseClass().TypeAndBaseClassInterfaces())
            {
                yield return(t);
            }

            foreach (AggregateType t in type.GetInterfaceBounds().AllConstraintInterfaces())
            {
                yield return(t);
            }
        }
예제 #2
0
파일: SymbolLoader.cs 프로젝트: jnm2/corefx
        private bool HasImplicitReferenceTypeParameterConversion(
            TypeParameterType pSource, CType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);

            if (!pSource.IsRefType())
            {
                // Not a reference conversion.
                return(false);
            }

            // The following implicit conversions exist for a given type parameter T:
            //
            // * From T to its effective base class C.
            AggregateType pEBC = pSource.GetEffectiveBaseClass();

            if (pDest == pEBC)
            {
                return(true);
            }
            // * From T to any base class of C.
            if (IsBaseClass(pEBC, pDest))
            {
                return(true);
            }
            // * From T to any interface implemented by C.
            if (IsBaseInterface(pEBC, pDest))
            {
                return(true);
            }
            // * From T to any interface type I in T's effective interface set, and
            //   from T to any base interface of I.
            TypeArray pInterfaces = pSource.GetInterfaceBounds();

            for (int i = 0; i < pInterfaces.Count; ++i)
            {
                if (pInterfaces[i] == pDest)
                {
                    return(true);
                }
            }
            // * From T to a type parameter U, provided T depends on U.
            if (pDest.IsTypeParameterType() && pSource.DependsOn(pDest.AsTypeParameterType()))
            {
                return(true);
            }
            return(false);
        }
예제 #3
0
파일: SymbolLoader.cs 프로젝트: jnm2/corefx
        private bool HasImplicitBoxingTypeParameterConversion(
            TypeParameterType pSource, CType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);

            if (pSource.IsRefType())
            {
                // Not a boxing conversion; both source and destination are references.
                return(false);
            }

            // The following implicit conversions exist for a given type parameter T:
            //
            // * From T to its effective base class C.
            AggregateType pEBC = pSource.GetEffectiveBaseClass();

            if (pDest == pEBC)
            {
                return(true);
            }
            // * From T to any base class of C.
            if (IsBaseClass(pEBC, pDest))
            {
                return(true);
            }
            // * From T to any interface implemented by C.
            if (IsBaseInterface(pEBC, pDest))
            {
                return(true);
            }
            // * From T to any interface type I in T's effective interface set, and
            //   from T to any base interface of I.
            TypeArray pInterfaces = pSource.GetInterfaceBounds();

            for (int i = 0; i < pInterfaces.Count; ++i)
            {
                if (pInterfaces[i] == pDest)
                {
                    return(true);
                }
            }
            // * The conversion from T to a type parameter U, provided T depends on U, is not
            //   classified as a boxing conversion because it is not guaranteed to box.
            //   (If both T and U are value types then it is an identity conversion.)

            return(false);
        }
예제 #4
0
            private bool bindImplicitConversionFromTypeVar(TypeParameterType tyVarSrc)
            {
                // 13.1.4
                //
                // For a type-parameter T that is known to be a reference type (25.7), the following implicit
                // reference conversions exist:
                //
                // *   From T to its effective base class C, from T to any base class of C, and from T to any
                //     interface implemented by C.
                // *   From T to an interface-type I in T's effective interface set and from T to any base
                //     interface of I.
                // *   From T to a type parameter U provided that T depends on U (25.7). [Note: Since T is known
                //     to be a reference type, within the scope of T, the run-time type of U will always be a
                //     reference type, even if U is not known to be a reference type at compile-time.]
                // *   From the null type (11.2.7) to T.
                //
                // 13.1.5
                //
                // For a type-parameter T that is not known to be a reference type (25.7), the following conversions
                // involving T are considered to be boxing conversions at compile-time. At run-time, if T is a value
                // type, the conversion is executed as a boxing conversion. At run-time, if T is a reference type,
                // the conversion is executed as an implicit reference conversion or identity conversion.
                //
                // *   From T to its effective base class C, from T to any base class of C, and from T to any
                //     interface implemented by C. [Note: C will be one of the types System.Object, System.ValueType,
                //     or System.Enum (otherwise T would be known to be a reference type and 13.1.4 would apply
                //     instead of this clause).]
                // *   From T to an interface-type I in T's effective interface set and from T to any base
                //     interface of I.
                //
                // 13.1.6 Implicit type parameter conversions
                //
                // This clause details implicit conversions involving type parameters that are not classified as
                // implicit reference conversions or implicit boxing conversions.
                //
                // For a type-parameter T that is not known to be a reference type, there is an implicit conversion
                // from T to a type parameter U provided T depends on U. At run-time, if T is a value type and U is
                // a reference type, the conversion is executed as a boxing conversion. At run-time, if both T and U
                // are value types, then T and U are necessarily the same type and no conversion is performed. At
                // run-time, if T is a reference type, then U is necessarily also a reference type and the conversion
                // is executed as an implicit reference conversion or identity conversion (25.7).

                CType     typeTmp = tyVarSrc.GetEffectiveBaseClass();
                TypeArray bnds    = tyVarSrc.GetBounds();
                int       itype   = -1;

                for (; ;)
                {
                    if (binder.canConvert(typeTmp, typeDest, flags | CONVERTTYPE.NOUDC))
                    {
                        if (!needsExprDest)
                        {
                            return(true);
                        }
                        if (typeDest.IsTypeParameterType())
                        {
                            // For a type var destination we need to cast to object then to the other type var.
                            EXPR      exprT;
                            EXPRCLASS exprObj = GetExprFactory().MakeClass(binder.GetReqPDT(PredefinedType.PT_OBJECT));
                            binder.bindSimpleCast(exprSrc, exprObj, out exprT, EXPRFLAG.EXF_FORCE_BOX);
                            binder.bindSimpleCast(exprT, exprTypeDest, out exprDest, EXPRFLAG.EXF_FORCE_UNBOX);
                        }
                        else
                        {
                            binder.bindSimpleCast(exprSrc, exprTypeDest, out exprDest, EXPRFLAG.EXF_FORCE_BOX);
                        }
                        return(true);
                    }
                    do
                    {
                        if (++itype >= bnds.Size)
                        {
                            return(false);
                        }
                        typeTmp = bnds.Item(itype);
                    }while (!typeTmp.isInterfaceType() && !typeTmp.IsTypeParameterType());
                }
            }
예제 #5
0
        private bool HasImplicitBoxingTypeParameterConversion(
            TypeParameterType pSource, CType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);

            if (pSource.IsRefType())
            {
                // Not a boxing conversion; both source and destination are references.
                return false;
            }

            // The following implicit conversions exist for a given type parameter T:
            //
            // * From T to its effective base class C.
            AggregateType pEBC = pSource.GetEffectiveBaseClass();
            if (pDest == pEBC)
            {
                return true;
            }
            // * From T to any base class of C.
            if (IsBaseClass(pEBC, pDest))
            {
                return true;
            }
            // * From T to any interface implemented by C.
            if (IsBaseInterface(pEBC, pDest))
            {
                return true;
            }
            // * From T to any interface type I in T's effective interface set, and
            //   from T to any base interface of I.
            TypeArray pInterfaces = pSource.GetInterfaceBounds();
            for (int i = 0; i < pInterfaces.Size; ++i)
            {
                if (pInterfaces.Item(i) == pDest)
                {
                    return true;
                }
            }
            // * The conversion from T to a type parameter U, provided T depends on U, is not
            //   classified as a boxing conversion because it is not guaranteed to box.
            //   (If both T and U are value types then it is an identity conversion.)

            return false;
        }
예제 #6
0
        private bool HasImplicitReferenceTypeParameterConversion(
            TypeParameterType pSource, CType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);

            if (!pSource.IsRefType())
            {
                // Not a reference conversion.
                return false;
            }

            // The following implicit conversions exist for a given type parameter T:
            //
            // * From T to its effective base class C.
            AggregateType pEBC = pSource.GetEffectiveBaseClass();
            if (pDest == pEBC)
            {
                return true;
            }
            // * From T to any base class of C.
            if (IsBaseClass(pEBC, pDest))
            {
                return true;
            }
            // * From T to any interface implemented by C.
            if (IsBaseInterface(pEBC, pDest))
            {
                return true;
            }
            // * From T to any interface type I in T's effective interface set, and
            //   from T to any base interface of I.
            TypeArray pInterfaces = pSource.GetInterfaceBounds();
            for (int i = 0; i < pInterfaces.Size; ++i)
            {
                if (pInterfaces.Item(i) == pDest)
                {
                    return true;
                }
            }
            // * From T to a type parameter U, provided T depends on U.
            if (pDest.IsTypeParameterType() && pSource.DependsOn(pDest.AsTypeParameterType()))
            {
                return true;
            }
            return false;
        }
예제 #7
0
            private bool bindImplicitConversionFromTypeVar(TypeParameterType tyVarSrc)
            {
                // 13.1.4
                // 
                // For a type-parameter T that is known to be a reference type (25.7), the following implicit
                // reference conversions exist:
                // 
                // *   From T to its effective base class C, from T to any base class of C, and from T to any 
                //     interface implemented by C.
                // *   From T to an interface-type I in T's effective interface set and from T to any base 
                //     interface of I.
                // *   From T to a type parameter U provided that T depends on U (25.7). [Note: Since T is known
                //     to be a reference type, within the scope of T, the run-time type of U will always be a 
                //     reference type, even if U is not known to be a reference type at compile-time.]
                // *   From the null type (11.2.7) to T.
                //
                // 13.1.5
                //
                // For a type-parameter T that is not known to be a reference type (25.7), the following conversions
                // involving T are considered to be boxing conversions at compile-time. At run-time, if T is a value
                // type, the conversion is executed as a boxing conversion. At run-time, if T is a reference type,
                // the conversion is executed as an implicit reference conversion or identity conversion.
                // 
                // *   From T to its effective base class C, from T to any base class of C, and from T to any 
                //     interface implemented by C. [Note: C will be one of the types System.Object, System.ValueType,
                //     or System.Enum (otherwise T would be known to be a reference type and 13.1.4 would apply
                //     instead of this clause).]
                // *   From T to an interface-type I in T's effective interface set and from T to any base
                //     interface of I.
                //
                // 13.1.6 Implicit type parameter conversions
                // 
                // This clause details implicit conversions involving type parameters that are not classified as 
                // implicit reference conversions or implicit boxing conversions.
                // 
                // For a type-parameter T that is not known to be a reference type, there is an implicit conversion 
                // from T to a type parameter U provided T depends on U. At run-time, if T is a value type and U is
                // a reference type, the conversion is executed as a boxing conversion. At run-time, if both T and U
                // are value types, then T and U are necessarily the same type and no conversion is performed. At 
                // run-time, if T is a reference type, then U is necessarily also a reference type and the conversion
                // is executed as an implicit reference conversion or identity conversion (25.7).

                CType typeTmp = tyVarSrc.GetEffectiveBaseClass();
                TypeArray bnds = tyVarSrc.GetBounds();
                int itype = -1;
                for (; ;)
                {
                    if (_binder.canConvert(typeTmp, _typeDest, _flags | CONVERTTYPE.NOUDC))
                    {
                        if (!_needsExprDest)
                        {
                            return true;
                        }
                        if (_typeDest.IsTypeParameterType())
                        {
                            // For a type var destination we need to cast to object then to the other type var.
                            EXPR exprT;
                            EXPRCLASS exprObj = GetExprFactory().MakeClass(_binder.GetReqPDT(PredefinedType.PT_OBJECT));
                            _binder.bindSimpleCast(_exprSrc, exprObj, out exprT, EXPRFLAG.EXF_FORCE_BOX);
                            _binder.bindSimpleCast(exprT, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_FORCE_UNBOX);
                        }
                        else
                        {
                            _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_FORCE_BOX);
                        }
                        return true;
                    }
                    do
                    {
                        if (++itype >= bnds.Size)
                        {
                            return false;
                        }
                        typeTmp = bnds.Item(itype);
                    }
                    while (!typeTmp.isInterfaceType() && !typeTmp.IsTypeParameterType());
                }
            }