GetTypeArgsAll() public method

public GetTypeArgsAll ( ) : TypeArray
return TypeArray
Example #1
0
        public virtual ACCESSERROR CheckAccess2(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru)
        {
            Debug.Assert(symCheck != null);
            Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.getAggregate());
            Debug.Assert(typeThru == null ||
                   typeThru.IsAggregateType() ||
                   typeThru.IsTypeParameterType() ||
                   typeThru.IsArrayType() ||
                   typeThru.IsNullableType() ||
                   typeThru.IsErrorType());

#if DEBUG

            switch (symCheck.getKind())
            {
                default:
                    break;
                case SYMKIND.SK_MethodSymbol:
                case SYMKIND.SK_PropertySymbol:
                case SYMKIND.SK_FieldSymbol:
                case SYMKIND.SK_EventSymbol:
                    Debug.Assert(atsCheck != null);
                    break;
            }

#endif // DEBUG

            ACCESSERROR error = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru);
            if (ACCESSERROR.ACCESSERROR_NOERROR != error)
            {
                return error;
            }

            // Check the accessibility of the return CType.
            CType CType = symCheck.getType();
            if (CType == null)
            {
                return ACCESSERROR.ACCESSERROR_NOERROR;
            }

            // For members of AGGSYMs, atsCheck should always be specified!
            Debug.Assert(atsCheck != null);

            if (atsCheck.getAggregate().IsSource())
            {
                // We already check the "at least as accessible as" rules.
                // Does this always work for generics?
                // Could we get a bad CType argument in typeThru?
                // Maybe call CheckTypeAccess on typeThru?
                return ACCESSERROR.ACCESSERROR_NOERROR;
            }

            // Substitute on the CType.
            if (atsCheck.GetTypeArgsAll().size > 0)
            {
                CType = SymbolLoader.GetTypeManager().SubstType(CType, atsCheck);
            }

            return CheckTypeAccess(CType, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS;
        }
Example #2
0
        //////////////////////////////////////////////////////////////////////////////

        private bool HasVariantConversion(AggregateType pSource, AggregateType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);
            if (pSource == pDest)
            {
                return(true);
            }
            AggregateSymbol pAggSym = pSource.getAggregate();

            if (pAggSym != pDest.getAggregate())
            {
                return(false);
            }

            TypeArray pTypeParams = pAggSym.GetTypeVarsAll();
            TypeArray pSourceArgs = pSource.GetTypeArgsAll();
            TypeArray pDestArgs   = pDest.GetTypeArgsAll();

            Debug.Assert(pTypeParams.Count == pSourceArgs.Count);
            Debug.Assert(pTypeParams.Count == pDestArgs.Count);

            for (int iParam = 0; iParam < pTypeParams.Count; ++iParam)
            {
                CType pSourceArg = pSourceArgs[iParam];
                CType pDestArg   = pDestArgs[iParam];
                // If they're identical then this one is automatically good, so skip it.
                if (pSourceArg == pDestArg)
                {
                    continue;
                }
                TypeParameterType pParam = (TypeParameterType)pTypeParams[iParam];
                if (pParam.Invariant)
                {
                    return(false);
                }
                if (pParam.Covariant)
                {
                    if (!HasImplicitReferenceConversion(pSourceArg, pDestArg))
                    {
                        return(false);
                    }
                }
                if (pParam.Contravariant)
                {
                    if (!HasImplicitReferenceConversion(pDestArg, pSourceArg))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Example #3
0
        public virtual ACCESSERROR CheckAccess2(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru)
        {
            Debug.Assert(symCheck != null);
            Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.getAggregate());
            Debug.Assert(typeThru == null ||
                         typeThru.IsAggregateType() ||
                         typeThru.IsTypeParameterType() ||
                         typeThru.IsArrayType() ||
                         typeThru.IsNullableType() ||
                         typeThru.IsErrorType());

#if DEBUG
            switch (symCheck.getKind())
            {
            default:
                break;

            case SYMKIND.SK_MethodSymbol:
            case SYMKIND.SK_PropertySymbol:
            case SYMKIND.SK_FieldSymbol:
            case SYMKIND.SK_EventSymbol:
                Debug.Assert(atsCheck != null);
                break;
            }
#endif // DEBUG

            ACCESSERROR error = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru);
            if (ACCESSERROR.ACCESSERROR_NOERROR != error)
            {
                return(error);
            }

            // Check the accessibility of the return CType.
            CType CType = symCheck.getType();
            if (CType == null)
            {
                return(ACCESSERROR.ACCESSERROR_NOERROR);
            }

            // For members of AGGSYMs, atsCheck should always be specified!
            Debug.Assert(atsCheck != null);

            // Substitute on the CType.
            if (atsCheck.GetTypeArgsAll().Count > 0)
            {
                CType = SymbolLoader.GetTypeManager().SubstType(CType, atsCheck);
            }

            return(CheckTypeAccess(CType, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS);
        }
Example #4
0
        private AggregateType SubstTypeCore(AggregateType type, SubstContext ctx)
        {
            TypeArray args = type.GetTypeArgsAll();

            if (args.Count > 0)
            {
                TypeArray typeArgs = SubstTypeArray(args, ctx);
                if (args != typeArgs)
                {
                    return(GetAggregate(type.getAggregate(), typeArgs));
                }
            }

            return(type);
        }
Example #5
0
        public AggregateType GetBaseClass()
        {
#if CSEE
            AggregateType atsBase = getAggregate().GetBaseClass();
            if (!atsBase || GetTypeArgsAll().size == 0 || atsBase.GetTypeArgsAll().size == 0)
                return atsBase;

            return getAggregate().GetTypeManager().SubstType(atsBase, GetTypeArgsAll()).AsAggregateType();
#else // !CSEE

            if (_baseType == null)
            {
                _baseType = getAggregate().GetTypeManager().SubstType(getAggregate().GetBaseClass(), GetTypeArgsAll()) as AggregateType;
            }

            return _baseType;
#endif // !CSEE
        }
Example #6
0
        public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs)
        {
            Debug.Assert(agg.GetTypeManager() == this);
            Debug.Assert(atsOuter == null || atsOuter.getAggregate() == agg.Parent, "");

            if (typeArgs == null)
            {
                typeArgs = BSYMMGR.EmptyTypeArray();
            }

            Debug.Assert(agg.GetTypeVars().Count == typeArgs.Count);
            AggregateType pAggregate = _typeTable.LookupAggregate(agg, atsOuter, typeArgs);

            if (pAggregate == null)
            {
                pAggregate = _typeFactory.CreateAggregateType(
                    agg,
                    typeArgs,
                    atsOuter
                    );

                Debug.Assert(!pAggregate.fConstraintsChecked && !pAggregate.fConstraintError);

                pAggregate.SetErrors(false);
                _typeTable.InsertAggregate(agg, atsOuter, typeArgs, pAggregate);
            }
            else
            {
                Debug.Assert(!pAggregate.HasErrors());
            }

            Debug.Assert(pAggregate.getAggregate() == agg);
            Debug.Assert(pAggregate.GetTypeArgsThis() != null && pAggregate.GetTypeArgsAll() != null);
            Debug.Assert(pAggregate.GetTypeArgsThis() == typeArgs);

            return(pAggregate);
        }
Example #7
0
        private CType SubstTypeCore(CType type, SubstContext pctx)
        {
            CType typeSrc;
            CType typeDst;

            switch (type.GetTypeKind())
            {
            default:
                Debug.Assert(false);
                return(type);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
            case TypeKind.TK_MethodGroupType:
            case TypeKind.TK_ArgumentListType:
                return(type);

            case TypeKind.TK_ParameterModifierType:
                ParameterModifierType mod = (ParameterModifierType)type;
                typeDst = SubstTypeCore(typeSrc = mod.GetParameterType(), pctx);
                return((typeDst == typeSrc) ? type : GetParameterModifier(typeDst, mod.isOut));

            case TypeKind.TK_ArrayType:
                var arr = (ArrayType)type;
                typeDst = SubstTypeCore(typeSrc = arr.GetElementType(), pctx);
                return((typeDst == typeSrc) ? type : GetArray(typeDst, arr.rank, arr.IsSZArray));

            case TypeKind.TK_PointerType:
                typeDst = SubstTypeCore(typeSrc = ((PointerType)type).GetReferentType(), pctx);
                return((typeDst == typeSrc) ? type : GetPointer(typeDst));

            case TypeKind.TK_NullableType:
                typeDst = SubstTypeCore(typeSrc = ((NullableType)type).GetUnderlyingType(), pctx);
                return((typeDst == typeSrc) ? type : GetNullable(typeDst));

            case TypeKind.TK_AggregateType:
                AggregateType ats = (AggregateType)type;
                if (ats.GetTypeArgsAll().Count > 0)
                {
                    TypeArray typeArgs = SubstTypeArray(ats.GetTypeArgsAll(), pctx);
                    if (ats.GetTypeArgsAll() != typeArgs)
                    {
                        return(GetAggregate(ats.getAggregate(), typeArgs));
                    }
                }
                return(type);

            case TypeKind.TK_ErrorType:
                ErrorType err = (ErrorType)type;
                if (err.HasParent)
                {
                    Debug.Assert(err.nameText != null && err.typeArgs != null);
                    TypeArray typeArgs = SubstTypeArray(err.typeArgs, pctx);
                    if (typeArgs != err.typeArgs)
                    {
                        return(GetErrorType(err.nameText, typeArgs));
                    }
                }

                return(type);

            case TypeKind.TK_TypeParameterType:
            {
                TypeParameterSymbol tvs = ((TypeParameterType)type).GetTypeParameterSymbol();
                int index = tvs.GetIndexInTotalParameters();
                if (tvs.IsMethodTypeParameter())
                {
                    if ((pctx.grfst & SubstTypeFlags.DenormMeth) != 0 && tvs.parent != null)
                    {
                        return(type);
                    }
                    Debug.Assert(tvs.GetIndexInOwnParameters() == tvs.GetIndexInTotalParameters());
                    if (index < pctx.ctypeMeth)
                    {
                        Debug.Assert(pctx.prgtypeMeth != null);
                        return(pctx.prgtypeMeth[index]);
                    }
                    else
                    {
                        return((pctx.grfst & SubstTypeFlags.NormMeth) != 0 ? GetStdMethTypeVar(index) : type);
                    }
                }
                if ((pctx.grfst & SubstTypeFlags.DenormClass) != 0 && tvs.parent != null)
                {
                    return(type);
                }
                return(index < pctx.ctypeCls ? pctx.prgtypeCls[index] :
                       ((pctx.grfst & SubstTypeFlags.NormClass) != 0 ? GetStdClsTypeVar(index) : type));
            }
            }
        }
Example #8
0
        ////////////////////////////////////////////////////////////////////////////////

        private void ExactTypeArgumentInference(
            AggregateType pSource, AggregateType pDest)

        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);
            Debug.Assert(pSource.GetOwningAggregate() == pDest.GetOwningAggregate());

            TypeArray pSourceArgs = pSource.GetTypeArgsAll();
            TypeArray pDestArgs = pDest.GetTypeArgsAll();

            Debug.Assert(pSourceArgs != null);
            Debug.Assert(pDestArgs != null);
            Debug.Assert(pSourceArgs.size == pDestArgs.size);

            for (int arg = 0; arg < pSourceArgs.size; ++arg)
            {
                ExactInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
            }
        }
Example #9
0
        private static Type CalculateAssociatedSystemTypeForAggregate(AggregateType aggtype)
        {
            AggregateSymbol agg = aggtype.GetOwningAggregate();
            TypeArray typeArgs = aggtype.GetTypeArgsAll();

            List<Type> list = new List<Type>();

            // Get each type arg.
            for (int i = 0; i < typeArgs.size; i++)
            {
                // Unnamed type parameter types are just placeholders.
                if (typeArgs.Item(i).IsTypeParameterType() && typeArgs.Item(i).AsTypeParameterType().GetTypeParameterSymbol().name == null)
                {
                    return null;
                }
                list.Add(typeArgs.Item(i).AssociatedSystemType);
            }

            Type[] systemTypeArgs = list.ToArray();
            Type uninstantiatedType = agg.AssociatedSystemType;

            if (uninstantiatedType.GetTypeInfo().IsGenericType)
            {
                try
                {
                    return uninstantiatedType.MakeGenericType(systemTypeArgs);
                }
                catch (ArgumentException)
                {
                    // If the constraints don't work, just return the type without substituting it.
                    return uninstantiatedType;
                }
            }
            return uninstantiatedType;
        }
Example #10
0
 public TypeArray SubstTypeArray(TypeArray taSrc, AggregateType atsCls, TypeArray typeArgsMeth)
 {
     return(SubstTypeArray(taSrc, atsCls?.GetTypeArgsAll(), typeArgsMeth));
 }
Example #11
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:
                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_ErrorType:
                ErrorType err = (ErrorType)type;
                if (err.HasParent)
                {
                    Debug.Assert(err.nameText != null && err.typeArgs != null);

                    for (int i = 0; i < err.typeArgs.Count; i++)
                    {
                        if (TypeContainsTyVars(err.typeArgs[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);
            }
        }
Example #12
0
        //////////////////////////////////////////////////////////////////////////////

        private bool HasVariantConversion(AggregateType pSource, AggregateType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);
            if (pSource == pDest)
            {
                return true;
            }
            AggregateSymbol pAggSym = pSource.getAggregate();
            if (pAggSym != pDest.getAggregate())
            {
                return false;
            }

            TypeArray pTypeParams = pAggSym.GetTypeVarsAll();
            TypeArray pSourceArgs = pSource.GetTypeArgsAll();
            TypeArray pDestArgs = pDest.GetTypeArgsAll();

            Debug.Assert(pTypeParams.size == pSourceArgs.size);
            Debug.Assert(pTypeParams.size == pDestArgs.size);

            for (int iParam = 0; iParam < pTypeParams.size; ++iParam)
            {
                CType pSourceArg = pSourceArgs.Item(iParam);
                CType pDestArg = pDestArgs.Item(iParam);
                // If they're identical then this one is automatically good, so skip it.
                if (pSourceArg == pDestArg)
                {
                    continue;
                }
                TypeParameterType pParam = pTypeParams.Item(iParam).AsTypeParameterType();
                if (pParam.Invariant)
                {
                    return false;
                }
                if (pParam.Covariant)
                {
                    if (!HasImplicitReferenceConversion(pSourceArg, pDestArg))
                    {
                        return false;
                    }
                }
                if (pParam.Contravariant)
                {
                    if (!HasImplicitReferenceConversion(pDestArg, pSourceArg))
                    {
                        return false;
                    }
                }
            }
            return true;
        }
Example #13
0
        // Check the constraints of any type arguments in the given Type.
        public static bool CheckConstraints(CSemanticChecker checker, ErrorHandling errHandling, CType type, CheckConstraintsFlags flags)
        {
            type = type.GetNakedType(false);

            if (type.IsNullableType())
            {
                CType typeT = type.AsNullableType().GetAts(checker.GetErrorContext());
                if (typeT != null)
                {
                    type = typeT;
                }
                else
                {
                    type = type.GetNakedType(true);
                }
            }

            if (!type.IsAggregateType())
            {
                return(true);
            }

            AggregateType ats = type.AsAggregateType();

            if (ats.GetTypeArgsAll().Count == 0)
            {
                // Common case: there are no type vars, so there are no constraints.
                ats.fConstraintsChecked = true;
                ats.fConstraintError    = false;
                return(true);
            }

            if (ats.fConstraintsChecked)
            {
                // Already checked.
                if (!ats.fConstraintError || (flags & CheckConstraintsFlags.NoDupErrors) != 0)
                {
                    // No errors or no need to report errors again.
                    return(!ats.fConstraintError);
                }
            }

            TypeArray typeVars     = ats.getAggregate().GetTypeVars();
            TypeArray typeArgsThis = ats.GetTypeArgsThis();
            TypeArray typeArgsAll  = ats.GetTypeArgsAll();

            Debug.Assert(typeVars.Count == typeArgsThis.Count);

            if (!ats.fConstraintsChecked)
            {
                ats.fConstraintsChecked = true;
                ats.fConstraintError    = false;
            }

            // Check the outer type first. If CheckConstraintsFlags.Outer is not specified and the
            // outer type has already been checked then don't bother checking it.
            if (ats.outerType != null && ((flags & CheckConstraintsFlags.Outer) != 0 || !ats.outerType.fConstraintsChecked))
            {
                CheckConstraints(checker, errHandling, ats.outerType, flags);
                ats.fConstraintError |= ats.outerType.fConstraintError;
            }

            if (typeVars.Count > 0)
            {
                ats.fConstraintError |= !CheckConstraintsCore(checker, errHandling, ats.getAggregate(), typeVars, typeArgsThis, typeArgsAll, null, (flags & CheckConstraintsFlags.NoErrors));
            }

            // Now check type args themselves.
            for (int i = 0; i < typeArgsThis.Count; i++)
            {
                CType arg = typeArgsThis[i].GetNakedType(true);
                if (arg.IsAggregateType() && !arg.AsAggregateType().fConstraintsChecked)
                {
                    CheckConstraints(checker, errHandling, arg.AsAggregateType(), flags | CheckConstraintsFlags.Outer);
                    if (arg.AsAggregateType().fConstraintError)
                    {
                        ats.fConstraintError = true;
                    }
                }
            }
            return(!ats.fConstraintError);
        }
Example #14
0
 private bool IsDelegateType(CType pSrcType, AggregateType pAggType)
 {
     CType pInstantiatedType = GetSymbolLoader().GetTypeManager().SubstType(pSrcType, pAggType, pAggType.GetTypeArgsAll());
     return pInstantiatedType.isDelegateType();
 }
Example #15
0
 public SubstContext(AggregateType type, TypeArray typeArgsMeth, SubstTypeFlags grfst)
 {
     Init(type != null ? type.GetTypeArgsAll() : null, typeArgsMeth, grfst);
 }
Example #16
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);
            }
        }
Example #17
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:
                ErrorType err = (ErrorType)type;
                if (err.HasParent)
                {
                    Debug.Assert(err.nameText != null && err.typeArgs != null);

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

                return(false);

            case TypeKind.TK_TypeParameterType:
                return(false);
            }
        }
Example #18
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 is TypeParameterType)
                {
                    return(true);
                }
                if (typeSrc is TypeParameterType && 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 is AggregateType atSrc && typeDst is AggregateType atDst)
                {
                    AggregateSymbol aggSrc  = atSrc.getAggregate();
                    AggregateSymbol aggDest = atDst.getAggregate();

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

                if (typeSrc is ArrayType arrSrc)
                {
                    // *    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 (typeDst is ArrayType arrDst)
                    {
                        return(arrSrc.rank == arrDst.rank &&
                               arrSrc.IsSZArray == arrDst.IsSZArray &&
                               FExpRefConv(loader, arrSrc.GetElementType(), arrDst.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 (!arrSrc.IsSZArray ||
                        !typeDst.isInterfaceType())
                    {
                        return(false);
                    }

                    AggregateType aggDst      = (AggregateType)typeDst;
                    TypeArray     typeArgsAll = aggDst.GetTypeArgsAll();

                    if (typeArgsAll.Count != 1)
                    {
                        return(false);
                    }

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

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

                    return(FExpRefConv(loader, arrSrc.GetElementType(), typeArgsAll[0]));
                }

                if (typeDst is ArrayType arrayDest && typeSrc is AggregateType aggtypeSrc)
                {
                    // * From System.Array and the interfaces it implements, to any array-type.
                    if (loader.HasIdentityOrImplicitReferenceConversion(loader.GetPredefindType(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.
                    if (!arrayDest.IsSZArray || !typeSrc.isInterfaceType() ||
                        aggtypeSrc.GetTypeArgsAll().Count != 1)
                    {
                        return(false);
                    }

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

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

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

                    Debug.Assert(!(typeArr is MethodGroupType));
                    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);
        }
Example #19
0
 public CType SubstType(CType typeSrc, AggregateType atsCls, TypeArray typeArgsMeth)
 {
     return(SubstType(typeSrc, atsCls?.GetTypeArgsAll(), typeArgsMeth));
 }
Example #20
0
 public CType SubstType(CType typeSrc, AggregateType atsCls, TypeArray typeArgsMeth)
 {
     return SubstType(typeSrc, atsCls != null ? atsCls.GetTypeArgsAll() : null, typeArgsMeth);
 }
Example #21
0
 public SubstContext(AggregateType type, TypeArray typeArgsMeth, SubstTypeFlags grfst)
 {
     Init(type != null ? type.GetTypeArgsAll() : null, typeArgsMeth, grfst);
 }
Example #22
0
 public TypeArray SubstTypeArray(TypeArray taSrc, AggregateType atsCls, TypeArray typeArgsMeth)
 {
     return SubstTypeArray(taSrc, atsCls != null ? atsCls.GetTypeArgsAll() : null, typeArgsMeth);
 }
Example #23
0
 private SubstContext(AggregateType type, TypeArray typeArgsMeth, SubstTypeFlags grfst)
 {
     Init(type?.GetTypeArgsAll(), typeArgsMeth, grfst);
 }
Example #24
0
 public NullableType GetNubFromNullable(AggregateType ats)
 {
     Debug.Assert(ats.isPredefType(PredefinedType.PT_G_OPTIONAL));
     return GetNullable(ats.GetTypeArgsAll().Item(0));
 }
Example #25
0
        ////////////////////////////////////////////////////////////////////////////////

        private void UpperBoundTypeArgumentInference(
            AggregateType pSource, AggregateType pDest)
        {
            // SPEC: The choice of inference for the i-th CType argument is made
            // SPEC: based on the declaration of the i-th CType parameter of C, as
            // SPEC: follows:
            // SPEC:  if Ui is known to be of reference CType and the i-th CType parameter
            // SPEC:   was declared as covariant then an upper-bound inference is made.
            // SPEC:  if Ui is known to be of reference CType and the i-th CType parameter
            // SPEC:   was declared as contravariant then a lower-bound inference is made.
            // SPEC:  otherwise, an exact inference is made.

            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);
            Debug.Assert(pSource.GetOwningAggregate() == pDest.GetOwningAggregate());

            TypeArray pTypeParams = pSource.GetOwningAggregate().GetTypeVarsAll();
            TypeArray pSourceArgs = pSource.GetTypeArgsAll();
            TypeArray pDestArgs = pDest.GetTypeArgsAll();

            Debug.Assert(pTypeParams != null);
            Debug.Assert(pSourceArgs != null);
            Debug.Assert(pDestArgs != null);

            Debug.Assert(pTypeParams.size == pSourceArgs.size);
            Debug.Assert(pTypeParams.size == pDestArgs.size);

            for (int arg = 0; arg < pSourceArgs.size; ++arg)
            {
                TypeParameterType pTypeParam = pTypeParams.ItemAsTypeParameterType(arg);
                CType pSourceArg = pSourceArgs.Item(arg);
                CType pDestArg = pDestArgs.Item(arg);

                if (pSourceArg.IsRefType() && pTypeParam.Covariant)
                {
                    UpperBoundInference(pSourceArg, pDestArg);
                }
                else if (pSourceArg.IsRefType() && pTypeParam.Contravariant)
                {
                    LowerBoundInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
                }
                else
                {
                    ExactInference(pSourceArgs.Item(arg), pDestArgs.Item(arg));
                }
            }
        }
Example #26
0
        public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs)
        {
            Debug.Assert(agg.GetTypeManager() == this);
            Debug.Assert(atsOuter == null || atsOuter.getAggregate() == agg.Parent, "");

            if (typeArgs == null)
            {
                typeArgs = BSYMMGR.EmptyTypeArray();
            }

            Debug.Assert(agg.GetTypeVars().Count == typeArgs.Count);

            Name name = _BSymmgr.GetNameFromPtrs(typeArgs, atsOuter);

            Debug.Assert(name != null);

            AggregateType pAggregate = _typeTable.LookupAggregate(name, agg);

            if (pAggregate == null)
            {
                pAggregate = _typeFactory.CreateAggregateType(
                    name,
                    agg,
                    typeArgs,
                    atsOuter
                    );

                Debug.Assert(!pAggregate.fConstraintsChecked && !pAggregate.fConstraintError);

                pAggregate.SetErrors(false);
                _typeTable.InsertAggregate(name, agg, pAggregate);

                // If we have a generic type definition, then we need to set the
                // base class to be our current base type, and use that to calculate
                // our agg type and its base, then set it to be the generic version of the
                // base type. This is because:
                //
                // Suppose we have Foo<T> : IFoo<T>
                //
                // Initially, the BaseType will be IFoo<Foo.T>, which gives us the substitution
                // that we want to use for our agg type's base type. However, in the Symbol chain,
                // we want the base type to be IFoo<IFoo.T>. Thats why we need to do this little trick.
                //
                // If we don't have a generic type definition, then we just need to set our base
                // class. This is so that if we have a base type that's generic, we'll be
                // getting the correctly instantiated base type.

                var baseType = pAggregate.AssociatedSystemType?.BaseType;
                if (baseType != null)
                {
                    // Store the old base class.

                    AggregateType oldBaseType = agg.GetBaseClass();
                    agg.SetBaseClass(_symbolTable.GetCTypeFromType(baseType) as AggregateType);
                    pAggregate.GetBaseClass(); // Get the base type for the new agg type we're making.

                    agg.SetBaseClass(oldBaseType);
                }
            }
            else
            {
                Debug.Assert(!pAggregate.HasErrors());
            }

            Debug.Assert(pAggregate.getAggregate() == agg);
            Debug.Assert(pAggregate.GetTypeArgsThis() != null && pAggregate.GetTypeArgsAll() != null);
            Debug.Assert(pAggregate.GetTypeArgsThis() == typeArgs);

            return(pAggregate);
        }
Example #27
0
        private bool IsDelegateType(CType pSrcType, AggregateType pAggType)
        {
            CType pInstantiatedType = GetSymbolLoader().GetTypeManager().SubstType(pSrcType, pAggType, pAggType.GetTypeArgsAll());

            return(pInstantiatedType.isDelegateType());
        }
Example #28
0
 public NullableType GetNubFromNullable(AggregateType ats)
 {
     Debug.Assert(ats.isPredefType(PredefinedType.PT_G_OPTIONAL));
     return(GetNullable(ats.GetTypeArgsAll()[0]));
 }