Inheritance: ITypeOrNamespace
Exemple #1
0
 public void CopyItems(int i, int c, CType[] dest)
 {
     for (int j = 0; j < c; ++j)
     {
         dest[j] = _items[i + j];
     }
 }
Exemple #2
0
 public CMethodIterator(CSemanticChecker checker, SymbolLoader symLoader, Name name, TypeArray containingTypes, CType @object, CType qualifyingType, Declaration context, bool allowBogusAndInaccessible, bool allowExtensionMethods, int arity, EXPRFLAG flags, symbmask_t mask)
 {
     Debug.Assert(name != null);
     Debug.Assert(symLoader != null);
     Debug.Assert(checker != null);
     Debug.Assert(containingTypes != null);
     _pSemanticChecker = checker;
     _pSymbolLoader = symLoader;
     _pCurrentType = null;
     _pCurrentSym = null;
     _pName = name;
     _pContainingTypes = containingTypes;
     _pQualifyingType = qualifyingType;
     _pContext = context;
     _bAllowBogusAndInaccessible = allowBogusAndInaccessible;
     _bAllowExtensionMethods = allowExtensionMethods;
     _nArity = arity;
     _flags = flags;
     _mask = mask;
     _nCurrentTypeCount = 0;
     _bIsCheckingInstanceMethods = true;
     _bAtEnd = false;
     _bCurrentSymIsBogus = false;
     _bCurrentSymIsInaccessible = false;
     _bcanIncludeExtensionsInResults = _bAllowExtensionMethods;
     _bEndIterationAtCurrentExtensionList = false;
 }
Exemple #3
0
 public CMethodIterator GetMethodIterator(
     CSemanticChecker pChecker, SymbolLoader pSymLoader, CType pObject, CType pQualifyingType, Declaration pContext, bool allowBogusAndInaccessible, bool allowExtensionMethods, int arity, EXPRFLAG flags, symbmask_t mask)
 {
     Debug.Assert(pSymLoader != null);
     CMethodIterator iterator = new CMethodIterator(pChecker, pSymLoader, _pName, ContainingTypes, pObject, pQualifyingType, pContext, allowBogusAndInaccessible, allowExtensionMethods, arity, flags, mask);
     return iterator;
 }
Exemple #4
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;
        }
Exemple #5
0
 // Generate an error if CType is static.
 public bool CheckForStaticClass(Symbol symCtx, CType CType, ErrorCode err)
 {
     if (!CType.isStaticClass())
         return false;
     ReportStaticClassError(symCtx, CType, err);
     return true;
 }
 public SubstContext(CType[] prgtypeCls, int ctypeCls, CType[] prgtypeMeth, int ctypeMeth, SubstTypeFlags grfst)
 {
     this.prgtypeCls = prgtypeCls;
     this.ctypeCls = ctypeCls;
     this.prgtypeMeth = prgtypeMeth;
     this.ctypeMeth = ctypeMeth;
     this.grfst = grfst;
 }
Exemple #7
0
 public TypeArray(CType[] types)
 {
     _items = types;
     if (_items == null)
     {
         _items = Array.Empty<CType>();
     }
 }
 public void SetBounds(TypeArray pBounds)
 {
     _pBounds = pBounds;
     _pInterfaceBounds = null;
     _pEffectiveBaseClass = null;
     _pDeducedBaseClass = null;
     _bHasRefBound = false;
     _bHasValBound = false;
 }
Exemple #9
0
 public UnaOpFullSig(CType type, PfnBindUnaOp pfn, LiftFlags grflt, UnaOpFuncKind fnkind)
 {
     this.pt = PredefinedType.PT_UNDEFINEDINDEX;
     this.grfuom = UnaOpMask.None;
     this.cuosSkip = 0;
     this.pfn = pfn;
     _type = type;
     _grflt = grflt;
     this.fnkind = fnkind;
 }
Exemple #10
0
 /***************************************************************************************************
     Set the values of the UnaOpFullSig from the given UnaOpSig. The ExpressionBinder is needed to get
     the predefined type. Returns true iff the predef type is found.
 ***************************************************************************************************/
 public UnaOpFullSig(ExpressionBinder fnc, UnaOpSig uos)
 {
     this.pt = uos.pt;
     this.grfuom = uos.grfuom;
     this.cuosSkip = uos.cuosSkip;
     this.pfn = uos.pfn;
     this.fnkind = uos.fnkind;
     _type = pt != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetOptPDT(pt) : null;
     _grflt = LiftFlags.None;
 }
Exemple #11
0
 public ImplicitConversion(ExpressionBinder binder, EXPR exprSrc, CType typeSrc, EXPRTYPEORNAMESPACE typeDest, bool needsExprDest, CONVERTTYPE flags)
 {
     _binder = binder;
     _exprSrc = exprSrc;
     _typeSrc = typeSrc;
     _typeDest = typeDest.TypeOrNamespace.AsType();
     _exprTypeDest = typeDest;
     _needsExprDest = needsExprDest;
     _flags = flags;
     _exprDest = null;
 }
Exemple #12
0
 public EXPRFUNCPTR CreateFunctionPointer(EXPRFLAG nFlags, CType pType, EXPR pObject, MethWithInst MWI)
 {
     Debug.Assert(0 == (nFlags & ~(EXPRFLAG.EXF_BASECALL)));
     EXPRFUNCPTR rval = new EXPRFUNCPTR();
     rval.kind = ExpressionKind.EK_FUNCPTR;
     rval.type = pType;
     rval.flags = nFlags;
     rval.OptionalObject = pObject;
     rval.mwi = new MethWithInst(MWI);
     Debug.Assert(rval != null);
     return (rval);
 }
Exemple #13
0
            // ----------------------------------------------------------------------------
            // BindExplicitConversion
            // ----------------------------------------------------------------------------

            public ExplicitConversion(ExpressionBinder binder, EXPR exprSrc, CType typeSrc, EXPRTYPEORNAMESPACE typeDest, CType pDestinationTypeForLambdaErrorReporting, bool needsExprDest, CONVERTTYPE flags)
            {
                _binder = binder;
                _exprSrc = exprSrc;
                _typeSrc = typeSrc;
                _typeDest = typeDest.TypeOrNamespace.AsType();
                _pDestinationTypeForLambdaErrorReporting = pDestinationTypeForLambdaErrorReporting;
                _exprTypeDest = typeDest;
                _needsExprDest = needsExprDest;
                _flags = flags;
                _exprDest = null;
            }
Exemple #14
0
        public static bool TypeContainsAnonymousTypes(CType type)
        {
            CType ctype = (CType)type;

        LRecurse:  // Label used for "tail" recursion.
            switch (ctype.GetTypeKind())
            {
                default:
                    Debug.Assert(false, "Bad Symbol kind in TypeContainsAnonymousTypes");
                    return false;

                case TypeKind.TK_NullType:
                case TypeKind.TK_VoidType:
                case TypeKind.TK_NullableType:
                case TypeKind.TK_TypeParameterType:
                case TypeKind.TK_UnboundLambdaType:
                case TypeKind.TK_MethodGroupType:
                    return false;

                case TypeKind.TK_ArrayType:
                case TypeKind.TK_ParameterModifierType:
                case TypeKind.TK_PointerType:
                    ctype = (CType)ctype.GetBaseOrParameterOrElementType();
                    goto LRecurse;

                case TypeKind.TK_AggregateType:
                    if (ctype.AsAggregateType().getAggregate().IsAnonymousType())
                    {
                        return true;
                    }

                    TypeArray typeArgsAll = ctype.AsAggregateType().GetTypeArgsAll();
                    for (int i = 0; i < typeArgsAll.size; i++)
                    {
                        CType typeArg = typeArgsAll.Item(i);

                        if (TypeContainsAnonymousTypes(typeArg))
                        {
                            return true;
                        }
                    }
                    return false;

                case TypeKind.TK_ErrorType:
                    if (ctype.AsErrorType().HasTypeParent())
                    {
                        ctype = ctype.AsErrorType().GetTypeParent();
                        goto LRecurse;
                    }
                    return false;
            }
        }
Exemple #15
0
 public BinOpFullSig(CType type1, CType type2, PfnBindBinOp pfn, OpSigFlags grfos,
     LiftFlags grflt, BinOpFuncKind fnkind)
 {
     this.pt1 = PredefinedType.PT_UNDEFINEDINDEX;
     this.pt2 = PredefinedType.PT_UNDEFINEDINDEX;
     this.mask = BinOpMask.None;
     this.cbosSkip = 0;
     this.pfn = pfn;
     this.grfos = grfos;
     _type1 = type1;
     _type2 = type2;
     _grflt = grflt;
     this.fnkind = fnkind;
 }
Exemple #16
0
 public EXPRFIELD CreateField(EXPRFLAG nFlags, CType pType, EXPR pOptionalObject, uint nOffset, FieldWithType FWT, EXPR pOptionalLHS)
 {
     Debug.Assert(0 == (nFlags & ~(EXPRFLAG.EXF_MEMBERSET | EXPRFLAG.EXF_MASK_ANY)));
     EXPRFIELD rval = new EXPRFIELD();
     rval.kind = ExpressionKind.EK_FIELD;
     rval.type = pType;
     rval.flags = nFlags;
     rval.SetOptionalObject(pOptionalObject);
     if (FWT != null)
     {
         rval.fwt = FWT;
     }
     Debug.Assert(rval != null);
     return (rval);
 }
Exemple #17
0
        public AggregateType GetAts(ErrorHandling errorContext)
        {
            AggregateSymbol aggNullable = typeManager.GetNullable();
            if (aggNullable == null)
            {
                throw Error.InternalCompilerError();
            }

            if (ats == null)
            {
                CType typePar = GetUnderlyingType();
                CType[] typeParArray = new CType[] { typePar };
                TypeArray ta = symmgr.AllocParams(1, typeParArray);
                ats = typeManager.GetAggregate(aggNullable, ta);
            }
            return ats;
        }
Exemple #18
0
        public AggregateType GetAts(ErrorHandling errorContext)
        {
            AggregateSymbol aggNullable = typeManager.GetNullable();
            if (aggNullable == null)
            {
                throw Error.InternalCompilerError();
            }

            if (ats == null)
            {
                if (aggNullable == null)
                {
                    typeManager.ReportMissingPredefTypeError(errorContext, PredefinedType.PT_G_OPTIONAL);
                    return null;
                }

                CType typePar = GetUnderlyingType();
                CType[] typeParArray = new CType[] { typePar };
                TypeArray ta = symmgr.AllocParams(1, typeParArray);
                ats = typeManager.GetAggregate(aggNullable, ta);
            }
            return ats;
        }
Exemple #19
0
        public EXPRCALL CreateCall(EXPRFLAG nFlags, CType pType, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags &
               ~(
                   EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL |
                   EXPRFLAG.EXF_NEWSTRUCTASSG |
                   EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY
               )
              ));

            EXPRCALL rval = new EXPRCALL();
            rval.kind = ExpressionKind.EK_CALL;
            rval.type = pType;
            rval.flags = nFlags;
            rval.SetOptionalArguments(pOptionalArguments);
            rval.SetMemberGroup(pMemberGroup);
            rval.nubLiftKind = NullableCallLiftKind.NotLifted;
            rval.castOfNonLiftedResultToLiftedType = null;

            rval.mwi = MWI;
            Debug.Assert(rval != null);
            return (rval);
        }
 public ExprProperty CreateProperty(CType type, Expr optionalObjectThrough, Expr arguments, ExprMemberGroup memberGroup, PropWithType property, MethWithType setMethod) =>
 new ExprProperty(type, optionalObjectThrough, arguments, memberGroup, property, setMethod);
 public ExprCast CreateCast(EXPRFLAG flags, CType type, Expr argument) => new ExprCast(flags, type, argument);
 public ExprUserLogicalOp CreateUserLogOp(CType type, Expr trueFalseCall, ExprCall operatorCall) =>
 new ExprUserLogicalOp(type, trueFalseCall, operatorCall);
 public ExprMulti CreateMulti(EXPRFLAG flags, CType type, Expr left, Expr op) =>
 new ExprMulti(type, flags, left, op);
Exemple #24
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);
        }
Exemple #25
0
        public bool HasImplicitReferenceConversion(CType pSource, CType pDest)
        {
            Debug.Assert(pSource != null);
            Debug.Assert(pDest != null);

            // The implicit reference conversions are:
            // * From any reference type to Object.
            if (pSource.IsRefType() && pDest.isPredefType(PredefinedType.PT_OBJECT))
            {
                return(true);
            }
            // * From any class type S to any class type T provided S is derived from T.
            if (pSource.isClassType() && pDest.isClassType() && IsBaseClass(pSource, pDest))
            {
                return(true);
            }

            // ORIGINAL RULES:
            //    // * From any class type S to any interface type T provided S implements T.
            //    if (pSource.isClassType() && pDest.isInterfaceType() && IsBaseInterface(pSource, pDest))
            //    {
            //        return true;
            //    }
            //    // * from any interface type S to any interface type T, provided S is derived from T.
            //    if (pSource.isInterfaceType() && pDest.isInterfaceType() && IsBaseInterface(pSource, pDest))
            //    {
            //        return true;
            //    }

            // VARIANCE EXTENSIONS:
            // * From any class type S to any interface type T provided S implements an interface
            //   convertible to T.
            // * From any interface type S to any interface type T provided S implements an interface
            //   convertible to T.
            // * From any interface type S to any interface type T provided S is not T and S is
            //   an interface convertible to T.

            if (pSource.isClassType() && pDest.isInterfaceType() && HasAnyBaseInterfaceConversion(pSource, pDest))
            {
                return(true);
            }
            if (pSource.isInterfaceType() && pDest.isInterfaceType() && HasAnyBaseInterfaceConversion(pSource, pDest))
            {
                return(true);
            }
            if (pSource.isInterfaceType() && pDest.isInterfaceType() && pSource != pDest &&
                HasInterfaceConversion(pSource.AsAggregateType(), pDest.AsAggregateType()))
            {
                return(true);
            }

            // * From an array type S with an element type SE to an array type T with element type TE
            //   provided that 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.
            //   * Both SE and TE are reference types.
            //   * An implicit reference conversion exists from SE to TE.
            if (pSource.IsArrayType() && pDest.IsArrayType() &&
                HasCovariantArrayConversion(pSource.AsArrayType(), pDest.AsArrayType()))
            {
                return(true);
            }
            // * From any array type to System.Array or any interface implemented by System.Array.
            if (pSource.IsArrayType() && (pDest.isPredefType(PredefinedType.PT_ARRAY) ||
                                          IsBaseInterface(GetReqPredefType(PredefinedType.PT_ARRAY, false), pDest)))
            {
                return(true);
            }
            // * From a single-dimensional array type S[] to IList<T> and its base
            //   interfaces, provided that there is an implicit identity or reference
            //   conversion from S to T.
            if (pSource.IsArrayType() && HasArrayConversionToInterface(pSource.AsArrayType(), pDest))
            {
                return(true);
            }

            // * From any delegate type to System.Delegate
            //
            // SPEC OMISSION:
            //
            // The spec should actually say
            //
            // * From any delegate type to System.Delegate
            // * From any delegate type to System.MulticastDelegate
            // * From any delegate type to any interface implemented by System.MulticastDelegate
            if (pSource.isDelegateType() &&
                (pDest.isPredefType(PredefinedType.PT_MULTIDEL) ||
                 pDest.isPredefType(PredefinedType.PT_DELEGATE) ||
                 IsBaseInterface(GetReqPredefType(PredefinedType.PT_MULTIDEL, false), pDest)))
            {
                return(true);
            }

            // VARIANCE EXTENSION:
            // * From any delegate type S to a delegate type T provided S is not T and
            //   S is a delegate convertible to T

            if (pSource.isDelegateType() && pDest.isDelegateType() &&
                HasDelegateConversion(pSource.AsAggregateType(), pDest.AsAggregateType()))
            {
                return(true);
            }

            // * From the null literal to any reference type
            // NOTE: We extend the specification here. The C# 3.0 spec does not describe
            // a "null type". Rather, it says that the null literal is typeless, and is
            // convertible to any reference or nullable type. However, the C# 2.0 and 3.0
            // implementations have a "null type" which some expressions other than the
            // null literal may have. (For example, (null??null), which is also an
            // extension to the specification.)
            if (pSource.IsNullType() && pDest.IsRefType())
            {
                return(true);
            }
            if (pSource.IsNullType() && pDest.IsNullableType())
            {
                return(true);
            }

            // * Implicit conversions involving type parameters that are known to be reference types.
            if (pSource.IsTypeParameterType() &&
                HasImplicitReferenceTypeParameterConversion(pSource.AsTypeParameterType(), pDest))
            {
                return(true);
            }

            return(false);
        }
Exemple #26
0
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        // RUNTIME BINDER ONLY CHANGE
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        internal bool GetBestAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, CType typeSrc, out CType typeDst)
        {
            // This method implements the "best accessible type" algorithm for determining the type
            // of untyped arguments in the runtime binder. It is also used in method type inference
            // to fix type arguments to types that are accessible.

            // The new type is returned in an out parameter. The result will be true (and the out param
            // non-null) only when the algorithm could find a suitable accessible type.

            Debug.Assert(semanticChecker != null);
            Debug.Assert(bindingContext != null);
            Debug.Assert(typeSrc != null);

            typeDst = null;

            if (semanticChecker.CheckTypeAccess(typeSrc, bindingContext.ContextForMemberLookup))
            {
                // If we already have an accessible type, then use it. This is the terminal point of the recursion.
                typeDst = typeSrc;
                return(true);
            }

            // These guys have no accessibility concerns.
            Debug.Assert(!(typeSrc is VoidType) && !(typeSrc is ErrorType) && !(typeSrc is TypeParameterType));

            if (typeSrc is ParameterModifierType || typeSrc is PointerType)
            {
                // We cannot vary these.
                return(false);
            }

            CType intermediateType;

            if (typeSrc is AggregateType aggSrc && (aggSrc.isInterfaceType() || aggSrc.isDelegateType()) && TryVarianceAdjustmentToGetAccessibleType(semanticChecker, bindingContext, aggSrc, out intermediateType))
            {
                // If we have an interface or delegate type, then it can potentially be varied by its type arguments
                // to produce an accessible type, and if that's the case, then return that.
                // Example: IEnumerable<PrivateConcreteFoo> --> IEnumerable<PublicAbstractFoo>
                typeDst = intermediateType;

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

            if (typeSrc is ArrayType arrSrc && TryArrayVarianceAdjustmentToGetAccessibleType(semanticChecker, bindingContext, arrSrc, out intermediateType))
            {
                // Similarly to the interface and delegate case, arrays are covariant in their element type and
                // so we can potentially produce an array type that is accessible.
                // Example: PrivateConcreteFoo[] --> PublicAbstractFoo[]
                typeDst = intermediateType;

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

            if (typeSrc is NullableType)
            {
                // We have an inaccessible nullable type, which means that the best we can do is System.ValueType.
                typeDst = GetPredefAgg(PredefinedType.PT_VALUE).getThisType();

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

            if (typeSrc is ArrayType)
            {
                // We have an inaccessible array type for which we could not earlier find a better array type
                // with a covariant conversion, so the best we can do is System.Array.
                typeDst = GetPredefAgg(PredefinedType.PT_ARRAY).getThisType();

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

            Debug.Assert(typeSrc is AggregateType);

            if (typeSrc is AggregateType aggType)
            {
                // We have an AggregateType, so recurse on its base class.
                AggregateType baseType = aggType.GetBaseClass();

                if (baseType == null)
                {
                    // This happens with interfaces, for instance. But in that case, the
                    // conversion to object does exist, is an implicit reference conversion,
                    // and so we will use it.
                    baseType = GetPredefAgg(PredefinedType.PT_OBJECT).getThisType();
                }

                return(GetBestAccessibleType(semanticChecker, bindingContext, baseType, out typeDst));
            }

            return(false);
        }
Exemple #27
0
        private bool TryVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, AggregateType typeSrc, out CType typeDst)
        {
            Debug.Assert(typeSrc != null);
            Debug.Assert(typeSrc.isInterfaceType() || typeSrc.isDelegateType());

            typeDst = null;

            AggregateSymbol aggSym      = typeSrc.GetOwningAggregate();
            AggregateType   aggOpenType = aggSym.getThisType();

            if (!semanticChecker.CheckTypeAccess(aggOpenType, bindingContext.ContextForMemberLookup))
            {
                // if the aggregate symbol itself is not accessible, then forget it, there is no
                // variance that will help us arrive at an accessible type.
                return(false);
            }

            TypeArray typeArgs   = typeSrc.GetTypeArgsThis();
            TypeArray typeParams = aggOpenType.GetTypeArgsThis();

            CType[] newTypeArgsTemp = new CType[typeArgs.Count];

            for (int i = 0; i < typeArgs.Count; i++)
            {
                if (semanticChecker.CheckTypeAccess(typeArgs[i], bindingContext.ContextForMemberLookup))
                {
                    // we have an accessible argument, this position is not a problem.
                    newTypeArgsTemp[i] = typeArgs[i];
                    continue;
                }

                if (!typeArgs[i].IsRefType() || !((TypeParameterType)typeParams[i]).Covariant)
                {
                    // This guy is inaccessible, and we are not going to be able to vary him, so we need to fail.
                    return(false);
                }

                CType intermediateTypeArg;
                if (GetBestAccessibleType(semanticChecker, bindingContext, typeArgs[i], out intermediateTypeArg))
                {
                    // now we either have a value type (which must be accessible due to the above
                    // check, OR we have an inaccessible type (which must be a ref type). In either
                    // case, the recursion worked out and we are OK to vary this argument.
                    newTypeArgsTemp[i] = intermediateTypeArg;
                    continue;
                }
                else
                {
                    Debug.Assert(false, "GetBestAccessibleType unexpectedly failed on a type that was used as a type parameter");
                    return(false);
                }
            }

            TypeArray newTypeArgs      = semanticChecker.getBSymmgr().AllocParams(typeArgs.Count, newTypeArgsTemp);
            CType     intermediateType = this.GetAggregate(aggSym, typeSrc.outerType, newTypeArgs);

            // All type arguments were varied successfully, which means now we must be accessible. But we could
            // have violated constraints. Let's check that out.

            if (!TypeBind.CheckConstraints(semanticChecker, null /*ErrorHandling*/, intermediateType, CheckConstraintsFlags.NoErrors))
            {
                return(false);
            }

            typeDst = intermediateType;
            Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup));
            return(true);
        }
Exemple #28
0
 public bool SubstEqualTypes(CType typeDst, CType typeSrc, CType typeCls)
 {
     return(SubstEqualTypes(typeDst, typeSrc, typeCls, (TypeArray)null));
 }
Exemple #29
0
 private bool SubstEqualTypes(CType typeDst, CType typeSrc, CType typeCls, TypeArray typeArgsMeth)
 {
     return(SubstEqualTypes(typeDst, typeSrc, (typeCls as AggregateType)?.GetTypeArgsAll(), typeArgsMeth, SubstTypeFlags.NormNone));
 }
Exemple #30
0
 public CType SubstType(CType typeSrc, CType typeCls, TypeArray typeArgsMeth)
 {
     return(SubstType(typeSrc, (typeCls as AggregateType)?.GetTypeArgsAll(), typeArgsMeth));
 }
Exemple #31
0
 public CType SubstType(CType typeSrc, AggregateType atsCls, TypeArray typeArgsMeth)
 {
     return(SubstType(typeSrc, atsCls?.GetTypeArgsAll(), typeArgsMeth));
 }
 private static bool isEnumToDecimalConversion(CType argtype, CType desttype)
 {
     CType strippedArgType = argtype.IsNullableType() ? argtype.StripNubs() : argtype;
     CType strippedDestType = desttype.IsNullableType() ? desttype.StripNubs() : desttype;
     return strippedArgType.isEnumType() && strippedDestType.isPredefType(PredefinedType.PT_DECIMAL);
 }
Exemple #33
0
 public ExprMemberGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, MethodOrPropertySymbol pMPS, Expr optionalObject, CMemberLookupResults memberLookupResults)
     : base(ExpressionKind.MemberGroup, MethodGroupType.Instance)
 {
     Debug.Assert(
         (flags & ~(EXPRFLAG.EXF_CTOR | EXPRFLAG.EXF_INDEXER | EXPRFLAG.EXF_OPERATOR | EXPRFLAG.EXF_NEWOBJCALL
                    | EXPRFLAG.EXF_DELEGATE | EXPRFLAG.EXF_USERCALLABLE
                    | EXPRFLAG.EXF_MASK_ANY)) == 0);
     Flags               = flags;
     Name                = name;
     TypeArgs            = typeArgs ?? BSYMMGR.EmptyTypeArray();
     SymKind             = symKind;
     ParentType          = parentType;
     OptionalObject      = optionalObject;
     MemberLookupResults = memberLookupResults;
 }
 protected virtual EXPR GenerateConversionWithSource(EXPR pTarget, CType pType, bool bChecked)
 {
     PREDEFMETH pdm = bChecked ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT;
     EXPR pTypeOf = CreateTypeOf(pType);
     return GenerateCall(pdm, pTarget, pTypeOf);
 }
Exemple #35
0
            /***************************************************************************************************
            *   Called by BindImplicitConversion when the destination type is Nullable<T>. The following
            *   conversions are handled by this method:
            *
            * For S in { object, ValueType, interfaces implemented by underlying type} there is an explicit
            *     unboxing conversion S => T?
            * System.Enum => T? there is an unboxing conversion if T is an enum type
            * null => T? implemented as default(T?)
            *
            * Implicit T?* => T?+ implemented by either wrapping or calling GetValueOrDefault the
            *     appropriate number of times.
            * If imp/exp S => T then imp/exp S => T?+ implemented by converting to T then wrapping the
            *     appropriate number of times.
            * If imp/exp S => T then imp/exp S?+ => T?+ implemented by calling GetValueOrDefault (m-1) times
            *     then calling HasValue, producing a null if it returns false, otherwise calling Value,
            *     converting to T then wrapping the appropriate number of times.
            *
            *   The 3 rules above can be summarized with the following recursive rules:
            *
            * If imp/exp S => T? then imp/exp S? => T? implemented as
            *     qs.HasValue ? (T?)(qs.Value) : default(T?)
            * If imp/exp S => T then imp/exp S => T? implemented as new T?((T)s)
            *
            *   This method also handles calling bindUserDefinedConverion. This method does NOT handle
            *   the following conversions:
            *
            * Implicit boxing conversion from S? to { object, ValueType, Enum, ifaces implemented by S }. (Handled by BindImplicitConversion.)
            * If imp/exp S => T then explicit S?+ => T implemented by calling Value the appropriate number
            *     of times. (Handled by BindExplicitConversion.)
            *
            *   The recursive equivalent is:
            *
            * If imp/exp S => T and T is not nullable then explicit S? => T implemented as qs.Value
            *
            *   Some nullable conversion are NOT standard conversions. In particular, if S => T is implicit
            *   then S? => T is not standard. Similarly if S => T is not implicit then S => T? is not standard.
            ***************************************************************************************************/
            private bool BindNubConversion(NullableType nubDst)
            {
                // This code assumes that STANDARD and ISEXPLICIT are never both set.
                // bindUserDefinedConversion should ensure this!
                Debug.Assert(0 != (~_flags & (CONVERTTYPE.STANDARD | CONVERTTYPE.ISEXPLICIT)));
                Debug.Assert(_exprSrc == null || _exprSrc.Type == _typeSrc);
                Debug.Assert(!_needsExprDest || _exprSrc != null);
                Debug.Assert(_typeSrc != nubDst); // BindImplicitConversion should have taken care of this already.
                AggregateType atsDst = nubDst.GetAts(GetErrorContext());

                if (atsDst == null)
                {
                    return(false);
                }

                // Check for the unboxing conversion. This takes precedence over the wrapping conversions.
                if (GetSymbolLoader().HasBaseConversion(nubDst.GetUnderlyingType(), _typeSrc) && !CConversions.FWrappingConv(_typeSrc, nubDst))
                {
                    // These should be different! Fix the caller if typeSrc is an AggregateType of Nullable.
                    Debug.Assert(atsDst != _typeSrc);

                    // typeSrc is a base type of the destination nullable type so there is an explicit
                    // unboxing conversion.
                    if (0 == (_flags & CONVERTTYPE.ISEXPLICIT))
                    {
                        return(false);
                    }

                    if (_needsExprDest)
                    {
                        _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_UNBOX);
                    }
                    return(true);
                }

                int       cnubDst;
                int       cnubSrc;
                CType     typeDstBase     = nubDst.StripNubs(out cnubDst);
                ExprClass exprTypeDstBase = GetExprFactory().MakeClass(typeDstBase);
                CType     typeSrcBase     = _typeSrc.StripNubs(out cnubSrc);

                ConversionFunc pfn = (_flags & CONVERTTYPE.ISEXPLICIT) != 0 ?
                                     (ConversionFunc)_binder.BindExplicitConversion :
                                     (ConversionFunc)_binder.BindImplicitConversion;

                if (cnubSrc == 0)
                {
                    Debug.Assert(_typeSrc == typeSrcBase);

                    // The null type can be implicitly converted to T? as the default value.
                    if (_typeSrc.IsNullType())
                    {
                        // If we have the constant null, generate it as a default value of T?.  If we have
                        // some crazy expression which has been determined to be always null, like (null??null)
                        // keep it in its expression form and transform it in the nullable rewrite pass.
                        if (_needsExprDest)
                        {
                            if (_exprSrc.isCONSTANT_OK())
                            {
                                _exprDest = GetExprFactory().CreateZeroInit(nubDst);
                            }
                            else
                            {
                                _exprDest = GetExprFactory().CreateCast(0x00, _typeDest, _exprSrc);
                            }
                        }
                        return(true);
                    }

                    Expr exprTmp = _exprSrc;

                    // If there is an implicit/explicit S => T then there is an implicit/explicit S => T?
                    if (_typeSrc == typeDstBase || pfn(_exprSrc, _typeSrc, exprTypeDstBase, nubDst, _needsExprDest, out exprTmp, _flags | CONVERTTYPE.NOUDC))
                    {
                        if (_needsExprDest)
                        {
                            ExprUserDefinedConversion exprUDC = exprTmp as ExprUserDefinedConversion;
                            if (exprUDC != null)
                            {
                                exprTmp = exprUDC.UserDefinedCall;
                            }

                            // This logic is left over from the days when T?? was legal. However there are error/LAF cases that necessitates the loop.
                            // typeSrc is not nullable so just wrap the required number of times. For legal code (cnubDst <= 0).

                            for (int i = 0; i < cnubDst; i++)
                            {
                                ExprCall call = _binder.BindNubNew(exprTmp);
                                exprTmp = call;
                                call.NullableCallLiftKind = NullableCallLiftKind.NullableConversionConstructor;
                            }
                            if (exprUDC != null)
                            {
                                exprUDC.UserDefinedCall = exprTmp;
                                exprUDC.Type            = (CType)exprTmp.Type;
                                exprTmp = exprUDC;
                            }
                            Debug.Assert(exprTmp.Type == nubDst);
                            _exprDest = exprTmp;
                        }
                        return(true);
                    }

                    // No builtin conversion. Maybe there is a user defined conversion....
                    return(0 == (_flags & CONVERTTYPE.NOUDC) && _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, nubDst, _needsExprDest, out _exprDest, 0 == (_flags & CONVERTTYPE.ISEXPLICIT)));
                }

                // Both are Nullable so there is only a conversion if there is a conversion between the base types.
                // That is, if there is an implicit/explicit S => T then there is an implicit/explicit S?+ => T?+.
                if (typeSrcBase != typeDstBase && !pfn(null, typeSrcBase, exprTypeDstBase, nubDst, false, out _exprDest, _flags | CONVERTTYPE.NOUDC))
                {
                    // No builtin conversion. Maybe there is a user defined conversion....
                    return(0 == (_flags & CONVERTTYPE.NOUDC) && _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, nubDst, _needsExprDest, out _exprDest, 0 == (_flags & CONVERTTYPE.ISEXPLICIT)));
                }

                if (_needsExprDest)
                {
                    MethWithInst    mwi       = new MethWithInst(null, null);
                    ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                    ExprCall        exprDst   = GetExprFactory().CreateCall(0, nubDst, _exprSrc, pMemGroup, null);

                    // Here we want to first check whether or not the conversions work on the base types.

                    Expr      arg1 = _binder.mustCast(_exprSrc, typeSrcBase);
                    ExprClass arg2 = GetExprFactory().MakeClass(typeDstBase);

                    bool convertible;
                    if (0 != (_flags & CONVERTTYPE.ISEXPLICIT))
                    {
                        convertible = _binder.BindExplicitConversion(arg1, arg1.Type, arg2, typeDstBase, out arg1, _flags | CONVERTTYPE.NOUDC);
                    }
                    else
                    {
                        convertible = _binder.BindImplicitConversion(arg1, arg1.Type, arg2, typeDstBase, out arg1, _flags | CONVERTTYPE.NOUDC);
                    }
                    if (!convertible)
                    {
                        VSFAIL("bind(Im|Ex)plicitConversion failed unexpectedly");
                        return(false);
                    }

                    exprDst.CastOfNonLiftedResultToLiftedType = _binder.mustCast(arg1, nubDst, 0);
                    exprDst.NullableCallLiftKind = NullableCallLiftKind.NullableConversion;
                    exprDst.PConversions         = exprDst.CastOfNonLiftedResultToLiftedType;
                    _exprDest = exprDst;
                }

                return(true);
            }
        protected virtual EXPR GenerateUserDefinedConversion(EXPR arg, CType CType, EXPR target, MethWithInst method)
        {
            // The user-defined explicit conversion from enum? to decimal or decimal? requires
            // that we convert the enum? to its nullable underlying CType.
            if (isEnumToDecimalConversion(arg.type, CType))
            {
                // Special case: If we have enum? to decimal? then we need to emit 
                // a conversion from enum? to its nullable underlying CType first.
                // This is unfortunate; we ought to reorganize how conversions are 
                // represented in the EXPR tree so that this is more transparent.

                // converting an enum to its underlying CType never fails, so no need to check it.
                CType underlyingType = arg.type.StripNubs().underlyingEnumType();
                CType nullableType = GetSymbolLoader().GetTypeManager().GetNullable(underlyingType);
                EXPR typeofNubEnum = CreateTypeOf(nullableType);
                target = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, target, typeofNubEnum);
            }

            // If the methodinfo does not return the target CType AND this is not a lifted conversion
            // from one value CType to another, then we need to wrap the whole thing in another conversion,
            // e.g. if we have a user-defined conversion from int to S? and we have (S)myint, then we need to generate 
            // Convert(Convert(myint, typeof(S?), op_implicit), typeof(S))

            CType pMethodReturnType = GetSymbolLoader().GetTypeManager().SubstType(method.Meth().RetType,
                method.GetType(), method.TypeArgs);
            bool fDontLiftReturnType = (pMethodReturnType == CType || (IsNullableValueType(arg.type) && IsNullableValueType(CType)));

            EXPR typeofInner = CreateTypeOf(fDontLiftReturnType ? CType : pMethodReturnType);
            EXPR methodInfo = GetExprFactory().CreateMethodInfo(method);
            PREDEFMETH pdmInner = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED;
            EXPR callUserDefinedConversion = GenerateCall(pdmInner, target, typeofInner, methodInfo);

            if (fDontLiftReturnType)
            {
                return callUserDefinedConversion;
            }

            PREDEFMETH pdmOuter = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT;
            EXPR typeofOuter = CreateTypeOf(CType);
            return GenerateCall(pdmOuter, callUserDefinedConversion, typeofOuter);
        }
Exemple #37
0
        private static bool CheckSingleConstraint(CSemanticChecker checker, ErrorHandling errHandling, Symbol symErr, TypeParameterType var, CType arg, TypeArray typeArgsCls, TypeArray typeArgsMeth, CheckConstraintsFlags flags)
        {
            bool fReportErrors = 0 == (flags & CheckConstraintsFlags.NoErrors);

            if (arg.IsOpenTypePlaceholderType())
            {
                return(true);
            }

            if (arg.IsErrorType())
            {
                // Error should have been reported previously.
                return(false);
            }

            if (checker.CheckBogus(arg))
            {
                if (fReportErrors)
                {
                    errHandling.ErrorRef(ErrorCode.ERR_BogusType, arg);
                }

                return(false);
            }

            if (arg.IsPointerType())
            {
                if (fReportErrors)
                {
                    errHandling.Error(ErrorCode.ERR_BadTypeArgument, arg);
                }

                return(false);
            }

            if (arg.isStaticClass())
            {
                if (fReportErrors)
                {
                    checker.ReportStaticClassError(null, arg, ErrorCode.ERR_GenericArgIsStaticClass);
                }

                return(false);
            }

            bool fError = false;

            if (var.HasRefConstraint() && !arg.IsRefType())
            {
                if (fReportErrors)
                {
                    errHandling.ErrorRef(ErrorCode.ERR_RefConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg);
                }

                fError = true;
            }

            TypeArray bnds     = checker.GetSymbolLoader().GetTypeManager().SubstTypeArray(var.GetBounds(), typeArgsCls, typeArgsMeth);
            int       itypeMin = 0;

            if (var.HasValConstraint())
            {
                // If we have a type variable that is constrained to a value type, then we
                // want to check if its a nullable type, so that we can report the
                // constraint error below. In order to do this however, we need to check
                // that either the type arg is not a value type, or it is a nullable type.
                //
                // To check whether or not its a nullable type, we need to get the resolved
                // bound from the type argument and check against that.

                bool bIsValueType = arg.IsValType();
                bool bIsNullable  = arg.IsNullableType();
                if (bIsValueType && arg.IsTypeParameterType())
                {
                    TypeArray pArgBnds = arg.AsTypeParameterType().GetBounds();
                    if (pArgBnds.Count > 0)
                    {
                        bIsNullable = pArgBnds[0].IsNullableType();
                    }
                }

                if (!bIsValueType || bIsNullable)
                {
                    if (fReportErrors)
                    {
                        errHandling.ErrorRef(ErrorCode.ERR_ValConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg);
                    }

                    fError = true;
                }

                // Since FValCon() is set it is redundant to check System.ValueType as well.
                if (bnds.Count != 0 && bnds[0].isPredefType(PredefinedType.PT_VALUE))
                {
                    itypeMin = 1;
                }
            }

            for (int j = itypeMin; j < bnds.Count; j++)
            {
                CType typeBnd = bnds[j];
                if (!SatisfiesBound(checker, arg, typeBnd))
                {
                    if (fReportErrors)
                    {
                        // The bound isn't satisfied because of a constraint type. Explain to the user why not.
                        // There are 4 main cases, based on the type of the supplied type argument:
                        //  - reference type, or type parameter known to be a reference type
                        //  - nullable type, from which there is a boxing conversion to the constraint type(see below for details)
                        //  - type variable
                        //  - value type
                        // These cases are broken out because: a) The sets of conversions which can be used
                        // for constraint satisfaction is different based on the type argument supplied,
                        // and b) Nullable is one funky type, and user's can use all the help they can get
                        // when using it.
                        ErrorCode error;
                        if (arg.IsRefType())
                        {
                            // A reference type can only satisfy bounds to types
                            // to which they have an implicit reference conversion
                            error = ErrorCode.ERR_GenericConstraintNotSatisfiedRefType;
                        }
                        else if (arg.IsNullableType() && checker.GetSymbolLoader().HasBaseConversion(arg.AsNullableType().GetUnderlyingType(), typeBnd))    // This is inlining FBoxingConv
                        {
                            // nullable types do not satisfy bounds to every type that they are boxable to
                            // They only satisfy bounds of object and ValueType
                            if (typeBnd.isPredefType(PredefinedType.PT_ENUM) || arg.AsNullableType().GetUnderlyingType() == typeBnd)
                            {
                                // Nullable types don't satisfy bounds of EnumType, or the underlying type of the enum
                                // even though the conversion from Nullable to these types is a boxing conversion
                                // This is a rare case, because these bounds can never be directly stated ...
                                // These bounds can only occur when one type paramter is constrained to a second type parameter
                                // and the second type parameter is instantiated with Enum or the underlying type of the first type
                                // parameter
                                error = ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum;
                            }
                            else
                            {
                                // Nullable types don't satisfy the bounds of any interface type
                                // even when there is a boxing conversion from the Nullable type to
                                // the interface type. This will be a relatively common scenario
                                // so we cal it out separately from the previous case.
                                Debug.Assert(typeBnd.isInterfaceType());
                                error = ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface;
                            }
                        }
                        else if (arg.IsTypeParameterType())
                        {
                            // Type variables can satisfy bounds through boxing and type variable conversions
                            Debug.Assert(!arg.IsRefType());
                            error = ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar;
                        }
                        else
                        {
                            // Value types can only satisfy bounds through boxing conversions.
                            // Note that the exceptional case of Nullable types and boxing is handled above.
                            error = ErrorCode.ERR_GenericConstraintNotSatisfiedValType;
                        }
                        errHandling.Error(error, new ErrArgRef(symErr), new ErrArg(typeBnd, ErrArgFlags.Unique), var, new ErrArgRef(arg, ErrArgFlags.Unique));
                    }
                    fError = true;
                }
            }

            // Check the newable constraint.
            if (!var.HasNewConstraint() || arg.IsValType())
            {
                return(!fError);
            }

            if (arg.isClassType())
            {
                AggregateSymbol agg = arg.AsAggregateType().getAggregate();

                // Due to late binding nature of IDE created symbols, the AggregateSymbol might not
                // have all the information necessary yet, if it is not fully bound.
                // by calling LookupAggMember, it will ensure that we will update all the
                // information necessary at least for the given method.
                checker.GetSymbolLoader().LookupAggMember(NameManager.GetPredefinedName(PredefinedName.PN_CTOR), agg, symbmask_t.MASK_ALL);

                if (agg.HasPubNoArgCtor() && !agg.IsAbstract())
                {
                    return(!fError);
                }
            }
            else if (arg.IsTypeParameterType() && arg.AsTypeParameterType().HasNewConstraint())
            {
                return(!fError);
            }

            if (fReportErrors)
            {
                errHandling.ErrorRef(ErrorCode.ERR_NewConstraintNotSatisfied, symErr, new ErrArgNoRef(var), arg);
            }

            return(false);
        }
 protected EXPRTYPEOF CreateTypeOf(CType CType)
 {
     return GetExprFactory().CreateTypeOf(CType);
 }
 public ExprMultiGet CreateMultiGet(EXPRFLAG flags, CType type, ExprMulti multi) =>
 new ExprMultiGet(type, flags, multi);
Exemple #40
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeArray GetMethodTypeParameters(MethodInfo method, MethodSymbol parent)
        {
            if (method.IsGenericMethod)
            {
                Type[] genericArguments = method.GetGenericArguments();
                CType[] ctypes = new CType[genericArguments.Length];
                for (int i = 0; i < genericArguments.Length; i++)
                {
                    Type t = genericArguments[i];
                    ctypes[i] = LoadMethodTypeParameter(parent, t);
                }

                // After we load the type parameters, we need to resolve their bounds.
                for (int i = 0; i < genericArguments.Length; i++)
                {
                    Type t = genericArguments[i];
                    ctypes[i].AsTypeParameterType().GetTypeParameterSymbol().SetBounds(
                        _bsymmgr.AllocParams(
                        GetCTypeArrayFromTypes(t.GetTypeInfo().GetGenericParameterConstraints())));
                }
                return _bsymmgr.AllocParams(ctypes.Length, ctypes);
            }
            return BSYMMGR.EmptyTypeArray();
        }
 public ExprTypeOf CreateTypeOf(CType sourceType) =>
 new ExprTypeOf(Types.GetPredefAgg(PredefinedType.PT_TYPE).getThisType(), sourceType);
 public ExprArrayInit CreateArrayInit(CType type, Expr arguments, Expr argumentDimensions, int[] dimSizes, int dimSize) =>
 new ExprArrayInit(type, arguments, argumentDimensions, dimSizes, dimSize);
 public ExprCast CreateCast(CType type, Expr argument) => CreateCast(0, type, argument);
Exemple #44
0
 protected bool AreTypesEqualForConversion(CType pType1, CType pType2)
 {
     return(pType1.Equals(pType2));
 }
 public ExprMemberGroup CreateMemGroup(EXPRFLAG flags, Name name, TypeArray typeArgs, SYMKIND symKind, CType parentType, MethodOrPropertySymbol memberSymbol, Expr obj, CMemberLookupResults memberLookupResults) =>
 new ExprMemberGroup(flags, name, typeArgs, symKind, parentType, memberSymbol, obj, memberLookupResults);
Exemple #46
0
 public bool isManagedType(CType type)
 {
     return(type.computeManagedType(this));
 }
Exemple #47
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);
        }
Exemple #48
0
 public NullableType(CType underlyingType)
     : base(TypeKind.TK_NullableType)
 {
     UnderlyingType = underlyingType;
 }
 protected bool IsNullableValueType(CType pType)
 {
     if (pType.IsNullableType())
     {
         CType pStrippedType = pType.StripNubs();
         return pStrippedType.IsAggregateType() && pStrippedType.AsAggregateType().getAggregate().IsValueType();
     }
     return false;
 }
Exemple #50
0
 public CType SubstType(CType typeSrc, TypeArray typeArgsCls)
 {
     return(SubstType(typeSrc, typeArgsCls, null, SubstTypeFlags.NormNone));
 }
 protected virtual EXPR GenerateConversion(EXPR arg, CType CType, bool bChecked)
 {
     return GenerateConversionWithSource(Visit(arg), CType, bChecked || arg.isChecked());
 }
Exemple #52
0
 private CType SubstType(CType typeSrc, TypeArray typeArgsCls, TypeArray typeArgsMeth)
 {
     return(SubstType(typeSrc, typeArgsCls, typeArgsMeth, SubstTypeFlags.NormNone));
 }
 protected virtual EXPR GenerateUserDefinedConversion(EXPR arg, CType type, MethWithInst method)
 {
     EXPR target = Visit(arg);
     return GenerateUserDefinedConversion(arg, type, target, method);
 }
Exemple #54
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_OpenTypePlaceholderType:
            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);

                    CType pParentType = null;
                    if (err.HasTypeParent())
                    {
                        pParentType = SubstTypeCore(err.GetTypeParent(), pctx);
                    }

                    TypeArray typeArgs = SubstTypeArray(err.typeArgs, pctx);
                    if (typeArgs != err.typeArgs || (err.HasTypeParent() && pParentType != err.GetTypeParent()))
                    {
                        return(GetErrorType(pParentType, err.GetNSParent(), 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));
            }
            }
        }
 protected virtual EXPR GenerateParameter(string name, CType CType)
 {
     GetSymbolLoader().GetReqPredefType(PredefinedType.PT_STRING);  // force an ensure state
     EXPRCONSTANT nameString = GetExprFactory().CreateStringConstant(name);
     EXPRTYPEOF pTypeOf = CreateTypeOf(CType);
     return GenerateCall(PREDEFMETH.PM_EXPRESSION_PARAMETER, pTypeOf, nameString);
 }
Exemple #56
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);
            }
        }
 public void SetDefaultParameterValue(int index, CType type, CONSTVAL cv)
 {
     Debug.Assert(_defaultParameterIndex != null);
     ConstValFactory factory = new ConstValFactory();
     _defaultParameterIndex[index] = true;
     _defaultParameters[index] = factory.Copy(type.constValKind(), cv);
     _defaultParameterConstValTypes[index] = type;
 }
Exemple #58
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 = (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);
                        }
                    }
                    if (err.HasTypeParent())
                    {
                        type = err.GetTypeParent();
                        goto LRecurse;
                    }
                }
                return(false);

            case TypeKind.TK_TypeParameterType:
                return(false);
            }
        }
Exemple #59
0
        /////////////////////////////////////////////////////////////////////////////////

        internal CType[] GetCTypeArrayFromTypes(IList<Type> types)
        {
            if (types == null)
            {
                return null;
            }

            CType[] ctypes = new CType[types.Count];

            int i = 0;
            foreach (Type t in types)
            {
                Debug.Assert(t != null);
                ctypes[i++] = GetCTypeFromType(t);
            }

            return ctypes;
        }
Exemple #60
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_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 = (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);
                        }
                    }
                    if (err.HasTypeParent())
                    {
                        type = err.GetTypeParent();
                        goto LRecurse;
                    }
                }
                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);
            }
        }