예제 #1
0
            private bool bindExplicitConversionToArray(ArrayType arrayDest)
            {
                Debug.Assert(_typeSrc != null);
                Debug.Assert(arrayDest != null);

                if (_typeSrc.IsArrayType())
                {
                    return bindExplicitConversionFromArrayToArray(_typeSrc.AsArrayType(), arrayDest);
                }

                if (bindExplicitConversionFromIListToArray(arrayDest))
                {
                    return true;
                }

                // 13.2.2
                //
                // The explicit reference conversions are:
                //
                // * From System.Array and the interfaces it implements, to any array-type.

                if (_binder.canConvert(_binder.GetReqPDT(PredefinedType.PT_ARRAY), _typeSrc, CONVERTTYPE.NOUDC))
                {
                    if (_needsExprDest)
                        _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK);
                    return true;
                }
                return false;
            }
예제 #2
0
            private bool bindExplicitConversionFromIListToArray(ArrayType arrayDest)
            {
                // 13.2.2
                //
                // The explicit reference conversions are:
                //
                // * From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces 
                //   to a one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from
                //   S[] to System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T
                //   are the same type or there is an implicit or explicit reference conversion from S to T.

                if (arrayDest.rank != 1 || !_typeSrc.isInterfaceType() ||
                    _typeSrc.AsAggregateType().GetTypeArgsAll().Size != 1)
                {
                    return false;
                }

                AggregateSymbol aggIList = GetSymbolLoader().GetOptPredefAgg(PredefinedType.PT_G_ILIST);
                AggregateSymbol aggIReadOnlyList = GetSymbolLoader().GetOptPredefAgg(PredefinedType.PT_G_IREADONLYLIST);

                if ((aggIList == null ||
                    !GetSymbolLoader().IsBaseAggregate(aggIList, _typeSrc.AsAggregateType().getAggregate())) &&
                    (aggIReadOnlyList == null ||
                    !GetSymbolLoader().IsBaseAggregate(aggIReadOnlyList, _typeSrc.AsAggregateType().getAggregate())))
                {
                    return false;
                }

                CType typeArr = arrayDest.GetElementType();
                CType typeLst = _typeSrc.AsAggregateType().GetTypeArgsAll().Item(0);

                Debug.Assert(!typeArr.IsNeverSameType());
                if (typeArr != typeLst && !CConversions.FExpRefConv(GetSymbolLoader(), typeArr, typeLst))
                {
                    return false;
                }
                if (_needsExprDest)
                    _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK);
                return true;
            }
예제 #3
0
            private bool bindExplicitConversionFromArrayToArray(ArrayType arraySrc, ArrayType arrayDest)
            {
                // 13.2.2
                //
                // The explicit reference conversions are:
                //
                // * From an array-type S with an element type SE to an array-type T with an element type
                //   TE, provided all of the following are true:
                //
                //   * S and T differ only in element type. (In other words, S and T have the same number
                //     of dimensions.)
                //
                //   * An explicit reference conversion exists from SE to TE.

                if (arraySrc.rank != arrayDest.rank)
                {
                    return false;  // Ranks do not match.
                }

                if (CConversions.FExpRefConv(GetSymbolLoader(), arraySrc.GetElementType(), arrayDest.GetElementType()))
                {
                    if (_needsExprDest)
                        _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK);
                    return true;
                }

                return false;
            }
예제 #4
0
        private bool TryArrayVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, ArrayType typeSrc, out CType typeDst)
        {
            Debug.Assert(typeSrc != null);

            typeDst = null;

            // We are here because we have an array type with an inaccessible element type. If possible,
            // we should create a new array type that has an accessible element type for which a
            // conversion exists.

            CType elementType = typeSrc.GetElementType();
            if (!elementType.IsRefType())
            {
                // Covariant array conversions exist for reference types only.
                return false;
            }

            CType intermediateType;
            if (GetBestAccessibleType(semanticChecker, bindingContext, elementType, out intermediateType))
            {
                typeDst = this.GetArray(intermediateType, typeSrc.rank);

                Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup()));
                return true;
            }

            return false;
        }
예제 #5
0
        // Derived types - parent is base type
        public ArrayType CreateArray(Name name, CType pElementType, int rank)
        {
            ArrayType type = new ArrayType();

            type.SetName(name);
            type.rank = rank;
            type.SetElementType(pElementType);

            type.SetTypeKind(TypeKind.TK_ArrayType);
            return type;
        }
예제 #6
0
 private bool HasCovariantArrayConversion(ArrayType pSource, ArrayType pDest)
 {
     Debug.Assert(pSource != null);
     Debug.Assert(pDest != null);
     // * S and T differ only in element type. In other words, S and T have the same number of dimensions.
     // * Both SE and TE are reference types.
     // * An implicit reference conversion exists from SE to TE.
     return (pSource.rank == pDest.rank) &&
         HasImplicitReferenceConversion(pSource.GetElementType(), pDest.GetElementType());
 }
예제 #7
0
        private bool HasArrayConversionToInterface(ArrayType pSource, CType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);
            if (pSource.rank != 1)
            {
                return false;
            }
            if (!pDest.isInterfaceType())
            {
                return false;
            }

            // * From a single-dimensional array type S[] to IList<T> or IReadOnlyList<T> and their base
            //   interfaces, provided that there is an implicit identity or reference
            //   conversion from S to T.

            // We only have six interfaces to check. IList<T>, IReadOnlyList<T> and their bases:
            // * The base interface of IList<T> is ICollection<T>.
            // * The base interface of ICollection<T> is IEnumerable<T>.
            // * The base interface of IEnumerable<T> is IEnumerable.
            // * The base interface of IReadOnlyList<T> is IReadOnlyCollection<T>.
            // * The base interface of IReadOnlyCollection<T> is IEnumerable<T>.

            if (pDest.isPredefType(PredefinedType.PT_IENUMERABLE))
            {
                return true;
            }

            AggregateType atsDest = pDest.AsAggregateType();
            AggregateSymbol aggDest = pDest.getAggregate();
            if (!aggDest.isPredefAgg(PredefinedType.PT_G_ILIST) &&
                !aggDest.isPredefAgg(PredefinedType.PT_G_ICOLLECTION) &&
                !aggDest.isPredefAgg(PredefinedType.PT_G_IENUMERABLE) &&
                !aggDest.isPredefAgg(PredefinedType.PT_G_IREADONLYCOLLECTION) &&
                !aggDest.isPredefAgg(PredefinedType.PT_G_IREADONLYLIST))
            {
                return false;
            }

            Debug.Assert(atsDest.GetTypeArgsAll().Size == 1);

            CType pSourceElement = pSource.GetElementType();
            CType pDestTypeArgument = atsDest.GetTypeArgsAll().Item(0);
            return HasIdentityOrImplicitReferenceConversion(pSourceElement, pDestTypeArgument);
        }
예제 #8
0
        /***************************************************************************************************
        *   Determine whether there is an explicit or implicit reference conversion (or identity conversion)
        *   from typeSrc to typeDst. This is when:
        *
        *  13.2.3 Explicit reference conversions
        *
        *  The explicit reference conversions are:
        *   From object to any reference-type.
        *   From any class-type S to any class-type T, provided S is a base class of T.
        *   From any class-type S to any interface-type T, provided S is not sealed and provided S does not implement T.
        *   From any interface-type S to any class-type T, provided T is not sealed or provided T implements S.
        *   From any interface-type S to any interface-type T, provided S is not derived from T.
        *   From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true:
        *   o   S and T differ only in element type. (In other words, S and T have the same number of dimensions.)
        *   o   An explicit reference conversion exists from SE to TE.
        *   From System.Array and the interfaces it implements, to any array-type.
        *   From System.Delegate and the interfaces it implements, to any delegate-type.
        *   From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces, provided there is an explicit reference conversion from S to T.
        *   From a generic delegate type S to generic delegate type  T, provided all of the follow are true:
        *   o Both types are constructed generic types of the same generic delegate type, D<X1,... Xk>.That is,
        *     S is D<S1,... Sk> and T is D<T1,... Tk>.
        *   o S is not compatible with or identical to T.
        *   o If type parameter Xi is declared to be invariant then Si must be identical to Ti.
        *   o If type parameter Xi is declared to be covariant ("out") then Si must be convertible
        *     to Ti via an identify conversion,  implicit reference conversion, or explicit reference conversion.
        *   o If type parameter Xi is declared to be contravariant ("in") then either Si must be identical to Ti,
        *      or Si and Ti must both be reference types.
        *   From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces to a one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from S[] to System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T are the same type or there is an implicit or explicit reference conversion from S to T.
        *
        *  For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist:
        *   From the effective base class C of T to T and from any base class of C to T.
        *   From any interface-type to T.
        *   From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I.
        *   From a type-parameter U to T 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. end note]
        *
        * Both src and dst are reference types and there is a builtin explicit conversion from
        *     src to dst.
        * Or src is a reference type and dst is a base type of src (in which case the conversion is
        *     implicit as well).
        * Or dst is a reference type and src is a base type of dst.
        *
        *   The latter two cases can happen with type variables even though the other type variable is not
        *   a reference type.
        ***************************************************************************************************/
        public static bool FExpRefConv(SymbolLoader loader, CType typeSrc, CType typeDst)
        {
            Debug.Assert(typeSrc != null);
            Debug.Assert(typeDst != null);
            if (typeSrc.IsRefType() && typeDst.IsRefType())
            {
                // is there an implicit reference conversion in either direction?
                // this handles the bulk of the cases ...
                if (loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst) ||
                    loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc))
                {
                    return(true);
                }

                // For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist:
                // •    From any interface-type to T.
                // •    From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I.
                if (typeSrc.isInterfaceType() && typeDst.IsTypeParameterType())
                {
                    return(true);
                }
                if (typeSrc.IsTypeParameterType() && typeDst.isInterfaceType())
                {
                    return(true);
                }

                // * From any class-type S to any interface-type T, provided S is not sealed
                // * From any interface-type S to any class-type T, provided T is not sealed
                // * From any interface-type S to any interface-type T, provided S is not derived from T.
                if (typeSrc.IsAggregateType() && typeDst.IsAggregateType())
                {
                    AggregateSymbol aggSrc  = typeSrc.AsAggregateType().getAggregate();
                    AggregateSymbol aggDest = typeDst.AsAggregateType().getAggregate();

                    if ((aggSrc.IsClass() && !aggSrc.IsSealed() && aggDest.IsInterface()) ||
                        (aggSrc.IsInterface() && aggDest.IsClass() && !aggDest.IsSealed()) ||
                        (aggSrc.IsInterface() && aggDest.IsInterface()))
                    {
                        return(true);
                    }
                }

                // *    From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true:
                //     o    S and T differ only in element type. (In other words, S and T have the same number of dimensions.)
                //     o    An explicit reference conversion exists from SE to TE.
                if (typeSrc.IsArrayType() && typeDst.IsArrayType())
                {
                    return(typeSrc.AsArrayType().rank == typeDst.AsArrayType().rank&& FExpRefConv(loader, typeSrc.AsArrayType().GetElementType(), typeDst.AsArrayType().GetElementType()));
                }

                // *    From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T>
                //      and their base interfaces, provided there is an explicit reference conversion from S to T.
                if (typeSrc.IsArrayType())
                {
                    if (typeSrc.AsArrayType().rank != 1 ||
                        !typeDst.isInterfaceType() || typeDst.AsAggregateType().GetTypeArgsAll().Count != 1)
                    {
                        return(false);
                    }

                    AggregateSymbol aggIList         = loader.GetOptPredefAgg(PredefinedType.PT_G_ILIST);
                    AggregateSymbol aggIReadOnlyList = loader.GetOptPredefAgg(PredefinedType.PT_G_IREADONLYLIST);

                    if ((aggIList == null ||
                         !loader.IsBaseAggregate(aggIList, typeDst.AsAggregateType().getAggregate())) &&
                        (aggIReadOnlyList == null ||
                         !loader.IsBaseAggregate(aggIReadOnlyList, typeDst.AsAggregateType().getAggregate())))
                    {
                        return(false);
                    }

                    return(FExpRefConv(loader, typeSrc.AsArrayType().GetElementType(), typeDst.AsAggregateType().GetTypeArgsAll()[0]));
                }

                if (typeDst.IsArrayType() && typeSrc.IsAggregateType())
                {
                    // * From System.Array and the interfaces it implements, to any array-type.
                    if (loader.HasIdentityOrImplicitReferenceConversion(loader.GetReqPredefType(PredefinedType.PT_ARRAY), typeSrc))
                    {
                        return(true);
                    }

                    // *    From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces to a
                    //      one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from S[] to
                    //      System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T
                    //      are the same type or there is an implicit or explicit reference conversion from S to T.
                    ArrayType     arrayDest  = typeDst.AsArrayType();
                    AggregateType aggtypeSrc = typeSrc.AsAggregateType();
                    if (arrayDest.rank != 1 || !typeSrc.isInterfaceType() ||
                        aggtypeSrc.GetTypeArgsAll().Count != 1)
                    {
                        return(false);
                    }

                    AggregateSymbol aggIList         = loader.GetOptPredefAgg(PredefinedType.PT_G_ILIST);
                    AggregateSymbol aggIReadOnlyList = loader.GetOptPredefAgg(PredefinedType.PT_G_IREADONLYLIST);

                    if ((aggIList == null ||
                         !loader.IsBaseAggregate(aggIList, aggtypeSrc.getAggregate())) &&
                        (aggIReadOnlyList == null ||
                         !loader.IsBaseAggregate(aggIReadOnlyList, aggtypeSrc.getAggregate())))
                    {
                        return(false);
                    }

                    CType typeArr = arrayDest.GetElementType();
                    CType typeLst = aggtypeSrc.GetTypeArgsAll()[0];

                    Debug.Assert(!typeArr.IsNeverSameType());
                    return(typeArr == typeLst || FExpRefConv(loader, typeArr, typeLst));
                }
                if (HasGenericDelegateExplicitReferenceConversion(loader, typeSrc, typeDst))
                {
                    return(true);
                }
            }
            else if (typeSrc.IsRefType())
            {
                // conversion of T . U, where T : class, U
                // .. these constraints implies where U : class
                return(loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst));
            }
            else if (typeDst.IsRefType())
            {
                // conversion of T . U, where U : class, T
                // .. these constraints implies where T : class
                return(loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc));
            }
            return(false);
        }
예제 #9
0
 public static void InsertArray(CType elementType, int rankNum, ArrayType pArray)
 {
     Debug.Assert(LookupArray(elementType, rankNum) == null);
     s_arrayTable.Add(new KeyPair <CType, int>(elementType, rankNum), pArray);
 }
예제 #10
0
        private bool SubstEqualTypesCore(CType typeDst, CType typeSrc, SubstContext pctx)
        {
LRecurse:   // Label used for "tail" recursion.

            if (typeDst == typeSrc || typeDst.Equals(typeSrc))
            {
                return(true);
            }

            switch (typeSrc.GetTypeKind())
            {
            default:
                Debug.Assert(false, "Bad Symbol kind in SubstEqualTypesCore");
                return(false);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
            case TypeKind.TK_OpenTypePlaceholderType:
                // There should only be a single instance of these.
                Debug.Assert(typeDst.GetTypeKind() != typeSrc.GetTypeKind());
                return(false);

            case TypeKind.TK_ArrayType:
                ArrayType arrSrc = (ArrayType)typeSrc;
                if (!(typeDst is ArrayType arrDst) || arrDst.rank != arrSrc.rank || arrDst.IsSZArray != arrSrc.IsSZArray)
                {
                    return(false);
                }
                goto LCheckBases;

            case TypeKind.TK_ParameterModifierType:
                if (!(typeDst is ParameterModifierType modDest) ||
                    ((pctx.grfst & SubstTypeFlags.NoRefOutDifference) == 0 &&
                     modDest.isOut != ((ParameterModifierType)typeSrc).isOut))
                {
                    return(false);
                }
                goto LCheckBases;

            case TypeKind.TK_PointerType:
            case TypeKind.TK_NullableType:
                if (typeDst.GetTypeKind() != typeSrc.GetTypeKind())
                {
                    return(false);
                }
LCheckBases:
                typeSrc = typeSrc.GetBaseOrParameterOrElementType();
                typeDst = typeDst.GetBaseOrParameterOrElementType();
                goto LRecurse;

            case TypeKind.TK_AggregateType:
                if (!(typeDst is AggregateType atsDst))
                {
                    return(false);
                }
                {     // BLOCK
                    AggregateType atsSrc = (AggregateType)typeSrc;

                    if (atsSrc.getAggregate() != atsDst.getAggregate())
                    {
                        return(false);
                    }

                    Debug.Assert(atsSrc.GetTypeArgsAll().Count == atsDst.GetTypeArgsAll().Count);

                    // All the args must unify.
                    for (int i = 0; i < atsSrc.GetTypeArgsAll().Count; i++)
                    {
                        if (!SubstEqualTypesCore(atsDst.GetTypeArgsAll()[i], atsSrc.GetTypeArgsAll()[i], pctx))
                        {
                            return(false);
                        }
                    }
                }
                return(true);

            case TypeKind.TK_ErrorType:
                ErrorType errSrc = (ErrorType)typeSrc;
                if (!(typeDst is ErrorType errDst) || !errSrc.HasParent() || !errDst.HasParent())
                {
                    return(false);
                }
                {
                    Debug.Assert(errSrc.nameText != null && errSrc.typeArgs != null);
                    Debug.Assert(errDst.nameText != null && errDst.typeArgs != null);

                    if (errSrc.nameText != errDst.nameText || errSrc.typeArgs.Count != errDst.typeArgs.Count)
                    {
                        return(false);
                    }

                    if (errSrc.HasTypeParent() != errDst.HasTypeParent())
                    {
                        return(false);
                    }
                    if (errSrc.HasTypeParent())
                    {
                        if (errSrc.GetTypeParent() != errDst.GetTypeParent())
                        {
                            return(false);
                        }
                        if (!SubstEqualTypesCore(errDst.GetTypeParent(), errSrc.GetTypeParent(), pctx))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (errSrc.GetNSParent() != errDst.GetNSParent())
                        {
                            return(false);
                        }
                    }

                    // All the args must unify.
                    for (int i = 0; i < errSrc.typeArgs.Count; i++)
                    {
                        if (!SubstEqualTypesCore(errDst.typeArgs[i], errSrc.typeArgs[i], pctx))
                        {
                            return(false);
                        }
                    }
                }
                return(true);

            case TypeKind.TK_TypeParameterType:
            {         // BLOCK
                TypeParameterSymbol tvs = ((TypeParameterType)typeSrc).GetTypeParameterSymbol();
                int index = tvs.GetIndexInTotalParameters();

                if (tvs.IsMethodTypeParameter())
                {
                    if ((pctx.grfst & SubstTypeFlags.DenormMeth) != 0 && tvs.parent != null)
                    {
                        // typeDst == typeSrc was handled above.
                        Debug.Assert(typeDst != typeSrc);
                        return(false);
                    }
                    Debug.Assert(tvs.GetIndexInOwnParameters() == tvs.GetIndexInTotalParameters());
                    Debug.Assert(pctx.prgtypeMeth == null || tvs.GetIndexInTotalParameters() < pctx.ctypeMeth);
                    if (index < pctx.ctypeMeth && pctx.prgtypeMeth != null)
                    {
                        return(typeDst == pctx.prgtypeMeth[index]);
                    }
                    if ((pctx.grfst & SubstTypeFlags.NormMeth) != 0)
                    {
                        return(typeDst == GetStdMethTypeVar(index));
                    }
                }
                else
                {
                    if ((pctx.grfst & SubstTypeFlags.DenormClass) != 0 && tvs.parent != null)
                    {
                        // typeDst == typeSrc was handled above.
                        Debug.Assert(typeDst != typeSrc);
                        return(false);
                    }
                    Debug.Assert(pctx.prgtypeCls == null || tvs.GetIndexInTotalParameters() < pctx.ctypeCls);
                    if (index < pctx.ctypeCls)
                    {
                        return(typeDst == pctx.prgtypeCls[index]);
                    }
                    if ((pctx.grfst & SubstTypeFlags.NormClass) != 0)
                    {
                        return(typeDst == GetStdClsTypeVar(index));
                    }
                }
            }
                return(false);
            }
        }
예제 #11
0
        private bool TryArrayVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, ArrayType typeSrc, out CType typeDst)
        {
            Debug.Assert(typeSrc != null);

            typeDst = null;

            // We are here because we have an array type with an inaccessible element type. If possible,
            // we should create a new array type that has an accessible element type for which a
            // conversion exists.

            CType elementType = typeSrc.GetElementType();

            if (!elementType.IsRefType())
            {
                // Covariant array conversions exist for reference types only.
                return(false);
            }

            CType intermediateType;

            if (GetBestAccessibleType(semanticChecker, bindingContext, elementType, out intermediateType))
            {
                typeDst = this.GetArray(intermediateType, typeSrc.rank, typeSrc.IsSZArray);

                Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup));
                return(true);
            }

            return(false);
        }
예제 #12
0
        private bool SubstEqualTypesCore(CType typeDst, CType typeSrc, SubstContext pctx)
        {
LRecurse:   // Label used for "tail" recursion.

            if (typeDst == typeSrc || typeDst.Equals(typeSrc))
            {
                return(true);
            }

            switch (typeSrc.TypeKind)
            {
            default:
                Debug.Assert(false, "Bad Symbol kind in SubstEqualTypesCore");
                return(false);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
                // There should only be a single instance of these.
                Debug.Assert(typeDst.TypeKind != typeSrc.TypeKind);
                return(false);

            case TypeKind.TK_ArrayType:
                ArrayType arrSrc = (ArrayType)typeSrc;
                if (!(typeDst is ArrayType arrDst) || arrDst.Rank != arrSrc.Rank || arrDst.IsSZArray != arrSrc.IsSZArray)
                {
                    return(false);
                }
                goto LCheckBases;

            case TypeKind.TK_ParameterModifierType:
                if (!(typeDst is ParameterModifierType modDest) || modDest.IsOut != ((ParameterModifierType)typeSrc).IsOut)
                {
                    return(false);
                }

                goto LCheckBases;

            case TypeKind.TK_PointerType:
            case TypeKind.TK_NullableType:
                if (typeDst.TypeKind != typeSrc.TypeKind)
                {
                    return(false);
                }
LCheckBases:
                typeSrc = typeSrc.BaseOrParameterOrElementType;
                typeDst = typeDst.BaseOrParameterOrElementType;
                goto LRecurse;

            case TypeKind.TK_AggregateType:
                if (!(typeDst is AggregateType atsDst))
                {
                    return(false);
                }
                {     // BLOCK
                    AggregateType atsSrc = (AggregateType)typeSrc;

                    if (atsSrc.OwningAggregate != atsDst.OwningAggregate)
                    {
                        return(false);
                    }

                    Debug.Assert(atsSrc.TypeArgsAll.Count == atsDst.TypeArgsAll.Count);

                    // All the args must unify.
                    for (int i = 0; i < atsSrc.TypeArgsAll.Count; i++)
                    {
                        if (!SubstEqualTypesCore(atsDst.TypeArgsAll[i], atsSrc.TypeArgsAll[i], pctx))
                        {
                            return(false);
                        }
                    }
                }
                return(true);

            case TypeKind.TK_TypeParameterType:
            {         // BLOCK
                TypeParameterSymbol tvs = ((TypeParameterType)typeSrc).Symbol;
                int index = tvs.GetIndexInTotalParameters();

                if (tvs.IsMethodTypeParameter())
                {
                    if (pctx.DenormMeth && tvs.parent != null)
                    {
                        // typeDst == typeSrc was handled above.
                        Debug.Assert(typeDst != typeSrc);
                        return(false);
                    }

                    Debug.Assert(tvs.GetIndexInOwnParameters() == index);
                    Debug.Assert(tvs.GetIndexInTotalParameters() < pctx.MethodTypes.Length);
                    if (index < pctx.MethodTypes.Length)
                    {
                        return(typeDst == pctx.MethodTypes[index]);
                    }
                }
                else
                {
                    Debug.Assert(index < pctx.ClassTypes.Length);
                    if (index < pctx.ClassTypes.Length)
                    {
                        return(typeDst == pctx.ClassTypes[index]);
                    }
                }
            }
                return(false);
            }
        }
예제 #13
0
파일: Type.cs 프로젝트: stantoxt/corefx
        private static Type CalculateAssociatedSystemType(CType src)
        {
            Type result = null;

            switch (src.GetTypeKind())
            {
            case TypeKind.TK_ArrayType:
                ArrayType a           = (ArrayType)src;
                Type      elementType = a.GetElementType().AssociatedSystemType;
                result = a.IsSZArray ? elementType.MakeArrayType() : elementType.MakeArrayType(a.rank);
                break;

            case TypeKind.TK_NullableType:
                NullableType n = (NullableType)src;
                Type         underlyingType = n.GetUnderlyingType().AssociatedSystemType;
                result = typeof(Nullable <>).MakeGenericType(underlyingType);
                break;

            case TypeKind.TK_PointerType:
                PointerType p            = (PointerType)src;
                Type        referentType = p.GetReferentType().AssociatedSystemType;
                result = referentType.MakePointerType();
                break;

            case TypeKind.TK_ParameterModifierType:
                ParameterModifierType r = (ParameterModifierType)src;
                Type parameterType      = r.GetParameterType().AssociatedSystemType;
                result = parameterType.MakeByRefType();
                break;

            case TypeKind.TK_AggregateType:
                result = CalculateAssociatedSystemTypeForAggregate((AggregateType)src);
                break;

            case TypeKind.TK_TypeParameterType:
                TypeParameterType t = (TypeParameterType)src;
                if (t.IsMethodTypeParameter())
                {
                    MethodInfo meth = ((MethodSymbol)t.GetOwningSymbol()).AssociatedMemberInfo as MethodInfo;
                    result = meth.GetGenericArguments()[t.GetIndexInOwnParameters()];
                }
                else
                {
                    Type parentType = ((AggregateSymbol)t.GetOwningSymbol()).AssociatedSystemType;
                    result = parentType.GetGenericArguments()[t.GetIndexInOwnParameters()];
                }
                break;

            case TypeKind.TK_ArgumentListType:
            case TypeKind.TK_BoundLambdaType:
            case TypeKind.TK_ErrorType:
            case TypeKind.TK_MethodGroupType:
            case TypeKind.TK_NaturalIntegerType:
            case TypeKind.TK_NullType:
            case TypeKind.TK_OpenTypePlaceholderType:
            case TypeKind.TK_UnboundLambdaType:
            case TypeKind.TK_VoidType:

            default:
                break;
            }

            Debug.Assert(result != null || src.GetTypeKind() == TypeKind.TK_AggregateType);
            return(result);
        }
예제 #14
0
 public void InsertArray(Name pName, CType pElementType, ArrayType pArray)
 {
     Debug.Assert(LookupArray(pName, pElementType) == null);
     _pArrayTable.Add(new KeyPair <CType, Name>(pElementType, pName), pArray);
 }