GetBaseOrParameterOrElementType() 공개 메소드

public GetBaseOrParameterOrElementType ( ) : CType
리턴 CType
예제 #1
0
파일: Type.cs 프로젝트: wenchaoli/corefx
        ////////////////////////////////////////////////////////////////////////////////
        // Strips off ArrayType, ParameterModifierType, PointerType, PinnedType and optionally NullableType
        // and returns the result.
        public CType GetNakedType(bool fStripNub)
        {
            for (CType type = this; ;)
            {
                switch (type.GetTypeKind())
                {
                default:
                    return(type);

                case TypeKind.TK_NullableType:
                    if (!fStripNub)
                    {
                        return(type);
                    }
                    type = type.GetBaseOrParameterOrElementType();
                    break;

                case TypeKind.TK_ArrayType:
                case TypeKind.TK_ParameterModifierType:
                case TypeKind.TK_PointerType:
                    type = type.GetBaseOrParameterOrElementType();
                    break;
                }
            }
        }
예제 #2
0
        public static bool TypeContainsType(CType type, CType typeFind)
        {
LRecurse:   // Label used for "tail" recursion.

            if (type == typeFind || type.Equals(typeFind))
            {
                return(true);
            }

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

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

            case TypeKind.TK_ArrayType:
            case TypeKind.TK_NullableType:
            case TypeKind.TK_ParameterModifierType:
            case TypeKind.TK_PointerType:
                type = type.GetBaseOrParameterOrElementType();
                goto LRecurse;

            case TypeKind.TK_AggregateType:
            {         // BLOCK
                AggregateType ats = (AggregateType)type;

                for (int i = 0; i < ats.GetTypeArgsAll().Count; i++)
                {
                    if (TypeContainsType(ats.GetTypeArgsAll()[i], typeFind))
                    {
                        return(true);
                    }
                }
            }
                return(false);

            case TypeKind.TK_ErrorType:
            case TypeKind.TK_TypeParameterType:
                return(false);
            }
        }
예제 #3
0
        public static bool TypeContainsTyVars(CType type, TypeArray typeVars)
        {
LRecurse:   // Label used for "tail" recursion.
            switch (type.GetTypeKind())
            {
            default:
                Debug.Assert(false, "Bad Symbol kind in TypeContainsTyVars");
                return(false);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
            case TypeKind.TK_MethodGroupType:
            case TypeKind.TK_ErrorType:
                return(false);

            case TypeKind.TK_ArrayType:
            case TypeKind.TK_NullableType:
            case TypeKind.TK_ParameterModifierType:
            case TypeKind.TK_PointerType:
                type = type.GetBaseOrParameterOrElementType();
                goto LRecurse;

            case TypeKind.TK_AggregateType:
            {         // BLOCK
                AggregateType ats = (AggregateType)type;

                for (int i = 0; i < ats.GetTypeArgsAll().Count; i++)
                {
                    if (TypeContainsTyVars(ats.GetTypeArgsAll()[i], typeVars))
                    {
                        return(true);
                    }
                }
            }
                return(false);

            case TypeKind.TK_TypeParameterType:
                if (typeVars != null && typeVars.Count > 0)
                {
                    int ivar = ((TypeParameterType)type).GetIndexInTotalParameters();
                    return(ivar < typeVars.Count && type == typeVars[ivar]);
                }
                return(true);
            }
        }
예제 #4
0
        public BetterType CompareTypes(TypeArray ta1, TypeArray ta2)
        {
            if (ta1 == ta2)
            {
                return(BetterType.Same);
            }
            if (ta1.Size != ta2.Size)
            {
                // The one with more parameters is more specific.
                return(ta1.Size > ta2.Size ? BetterType.Left : BetterType.Right);
            }

            BetterType nTot = BetterType.Neither;

            for (int i = 0; i < ta1.Size; i++)
            {
                CType      type1  = ta1.Item(i);
                CType      type2  = ta2.Item(i);
                BetterType nParam = BetterType.Neither;

LAgain:
                if (type1.GetTypeKind() != type2.GetTypeKind())
                {
                    if (type1.IsTypeParameterType())
                    {
                        nParam = BetterType.Right;
                    }
                    else if (type2.IsTypeParameterType())
                    {
                        nParam = BetterType.Left;
                    }
                }
                else
                {
                    switch (type1.GetTypeKind())
                    {
                    default:
                        Debug.Assert(false, "Bad kind in CompareTypes");
                        break;

                    case TypeKind.TK_TypeParameterType:
                    case TypeKind.TK_ErrorType:
                        break;

                    case TypeKind.TK_PointerType:
                    case TypeKind.TK_ParameterModifierType:
                    case TypeKind.TK_ArrayType:
                    case TypeKind.TK_NullableType:
                        type1 = type1.GetBaseOrParameterOrElementType();
                        type2 = type2.GetBaseOrParameterOrElementType();
                        goto LAgain;

                    case TypeKind.TK_AggregateType:
                        nParam = CompareTypes(type1.AsAggregateType().GetTypeArgsAll(), type2.AsAggregateType().GetTypeArgsAll());
                        break;
                    }
                }

                if (nParam == BetterType.Right || nParam == BetterType.Left)
                {
                    if (nTot == BetterType.Same || nTot == BetterType.Neither)
                    {
                        nTot = nParam;
                    }
                    else if (nParam != nTot)
                    {
                        return(BetterType.Neither);
                    }
                }
            }

            return(nTot);
        }
예제 #5
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:
                // 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 ||
                        errSrc.HasParent != errDst.HasParent)
                    {
                        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);
            }
        }
예제 #6
0
        public static bool TypeContainsTyVars(CType type, TypeArray typeVars)
        {
        LRecurse:  // Label used for "tail" recursion.
            switch (type.GetTypeKind())
            {
                default:
                    Debug.Assert(false, "Bad Symbol kind in TypeContainsTyVars");
                    return false;

                case TypeKind.TK_UnboundLambdaType:
                case TypeKind.TK_BoundLambdaType:
                case TypeKind.TK_NullType:
                case TypeKind.TK_VoidType:
                case TypeKind.TK_OpenTypePlaceholderType:
                case TypeKind.TK_MethodGroupType:
                    return false;

                case TypeKind.TK_ArrayType:
                case TypeKind.TK_NullableType:
                case TypeKind.TK_ParameterModifierType:
                case TypeKind.TK_PointerType:
                    type = type.GetBaseOrParameterOrElementType();
                    goto LRecurse;

                case TypeKind.TK_AggregateType:
                    { // BLOCK
                        AggregateType ats = type.AsAggregateType();

                        for (int i = 0; i < ats.GetTypeArgsAll().Size; i++)
                        {
                            if (TypeContainsTyVars(ats.GetTypeArgsAll().Item(i), typeVars))
                            {
                                return true;
                            }
                        }
                    }
                    return false;

                case TypeKind.TK_ErrorType:
                    if (type.AsErrorType().HasParent())
                    {
                        ErrorType err = type.AsErrorType();
                        Debug.Assert(err.nameText != null && err.typeArgs != null);

                        for (int i = 0; i < err.typeArgs.Size; i++)
                        {
                            if (TypeContainsTyVars(err.typeArgs.Item(i), typeVars))
                            {
                                return true;
                            }
                        }
                        if (err.HasTypeParent())
                        {
                            type = err.GetTypeParent();
                            goto LRecurse;
                        }
                    }
                    return false;

                case TypeKind.TK_TypeParameterType:
                    if (typeVars != null && typeVars.Size > 0)
                    {
                        int ivar = type.AsTypeParameterType().GetIndexInTotalParameters();
                        return ivar < typeVars.Size && type == typeVars.Item(ivar);
                    }
                    return true;
            }
        }
예제 #7
0
        public static bool TypeContainsType(CType type, CType typeFind)
        {
        LRecurse:  // Label used for "tail" recursion.

            if (type == typeFind || type.Equals(typeFind))
                return true;

            switch (type.GetTypeKind())
            {
                default:
                    Debug.Assert(false, "Bad Symbol kind in TypeContainsType");
                    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(typeFind.GetTypeKind() != type.GetTypeKind());
                    return false;

                case TypeKind.TK_ArrayType:
                case TypeKind.TK_NullableType:
                case TypeKind.TK_ParameterModifierType:
                case TypeKind.TK_PointerType:
                    type = type.GetBaseOrParameterOrElementType();
                    goto LRecurse;

                case TypeKind.TK_AggregateType:
                    { // BLOCK
                        AggregateType ats = type.AsAggregateType();

                        for (int i = 0; i < ats.GetTypeArgsAll().Size; i++)
                        {
                            if (TypeContainsType(ats.GetTypeArgsAll().Item(i), typeFind))
                                return true;
                        }
                    }
                    return false;

                case TypeKind.TK_ErrorType:
                    if (type.AsErrorType().HasParent())
                    {
                        ErrorType err = type.AsErrorType();
                        Debug.Assert(err.nameText != null && err.typeArgs != null);

                        for (int i = 0; i < err.typeArgs.Size; i++)
                        {
                            if (TypeContainsType(err.typeArgs.Item(i), typeFind))
                                return true;
                        }
                        if (err.HasTypeParent())
                        {
                            type = err.GetTypeParent();
                            goto LRecurse;
                        }
                    }
                    return false;

                case TypeKind.TK_TypeParameterType:
                    return false;
            }
        }
예제 #8
0
        public 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:
                    if (typeDst.GetTypeKind() != TypeKind.TK_ArrayType || typeDst.AsArrayType().rank != typeSrc.AsArrayType().rank)
                        return false;
                    goto LCheckBases;

                case TypeKind.TK_ParameterModifierType:
                    if (typeDst.GetTypeKind() != TypeKind.TK_ParameterModifierType ||
                        ((pctx.grfst & SubstTypeFlags.NoRefOutDifference) == 0 &&
                         typeDst.AsParameterModifierType().isOut != typeSrc.AsParameterModifierType().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.GetTypeKind() != TypeKind.TK_AggregateType)
                        return false;
                    { // BLOCK
                        AggregateType atsSrc = typeSrc.AsAggregateType();
                        AggregateType atsDst = typeDst.AsAggregateType();

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

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

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

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

                        if (errSrc.nameText != errDst.nameText || errSrc.typeArgs.Size != errDst.typeArgs.Size)
                            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.Size; i++)
                        {
                            if (!SubstEqualTypesCore(errDst.typeArgs.Item(i), errSrc.typeArgs.Item(i), pctx))
                                return false;
                        }
                    }
                    return true;

                case TypeKind.TK_TypeParameterType:
                    { // BLOCK
                        TypeParameterSymbol tvs = typeSrc.AsTypeParameterType().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;
            }
        }
예제 #9
0
 protected void ErrAppendParentType(CType pType, SubstContext pctx)
 {
     if (pType.IsErrorType())
     {
         if (pType.AsErrorType().HasTypeParent())
         {
             ErrAppendType(pType.AsErrorType().GetTypeParent(), null);
             ErrAppendChar('.');
         }
         else
         {
             ErrAppendParentCore(pType.AsErrorType().GetNSParent(), pctx);
         }
     }
     else if (pType.IsAggregateType())
     {
         ErrAppendParentCore(pType.AsAggregateType().GetOwningAggregate(), pctx);
     }
     else if (pType.GetBaseOrParameterOrElementType() != null)
     {
         ErrAppendType(pType.GetBaseOrParameterOrElementType(), null);
         ErrAppendChar('.');
     }
 }