public GetBaseOrParameterOrElementType ( ) : |
||
리턴 |
//////////////////////////////////////////////////////////////////////////////// // 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; } } }
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); } }
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); } }
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); }
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); } }
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; } }
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; } }
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; } }
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('.'); } }