IsNullType() public method

public IsNullType ( ) : bool
return bool
Ejemplo n.º 1
0
        ////////////////////////////////////////////////////////////////////////////////

        private static bool IsReallyAType(CType pType)
        {
            if (pType.IsNullType() || pType.IsBoundLambdaType() ||
                pType.IsVoidType() ||
                pType.IsMethodGroupType())
            {
                return false;
            }
            return true;
        }
Ejemplo n.º 2
0
        private 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);
        }
Ejemplo n.º 3
0
            /*
             * BindImplicitConversion
             *
             * This is a complex routine with complex parameters. Generally, this should
             * be called through one of the helper methods that insulates you
             * from the complexity of the interface. This routine handles all the logic
             * associated with implicit conversions.
             *
             * exprSrc - the expression being converted. Can be null if only type conversion
             *           info is being supplied.
             * typeSrc - type of the source
             * typeDest - type of the destination
             * exprDest - returns an expression of the src converted to the dest. If null, we
             *            only care about whether the conversion can be attempted, not the
             *            expression tree.
             * flags    - flags possibly customizing the conversions allowed. E.g., can suppress
             *            user-defined conversions.
             *
             * returns true if the conversion can be made, false if not.
             */
            public bool Bind()
            {
                // 13.1 Implicit conversions
                //
                // The following conversions are classified as implicit conversions:
                //
                // *   Identity conversions
                // *   Implicit numeric conversions
                // *   Implicit enumeration conversions
                // *   Implicit reference conversions
                // *   Boxing conversions
                // *   Implicit type parameter conversions
                // *   Implicit constant expression conversions
                // *   User-defined implicit conversions
                // *   Implicit conversions from an anonymous method expression to a compatible delegate type
                // *   Implicit conversion from a method group to a compatible delegate type
                // *   Conversions from the null type (11.2.7) to any nullable type
                // *   Implicit nullable conversions
                // *   Lifted user-defined implicit conversions
                //
                // Implicit conversions can occur in a variety of situations, including function member invocations
                // (14.4.3), cast expressions (14.6.6), and assignments (14.14).

                // Can't convert to or from the error type.
                if (typeSrc == null || typeDest == null || typeDest.IsNeverSameType())
                {
                    return(false);
                }

                Debug.Assert(typeSrc != null && typeDest != null);         // types must be supplied.
                Debug.Assert(exprSrc == null || typeSrc == exprSrc.type);  // type of source should be correct if source supplied
                Debug.Assert(!needsExprDest || exprSrc != null);           // need source expr to create dest expr

                switch (typeDest.GetTypeKind())
                {
                case TypeKind.TK_ErrorType:
                    Debug.Assert(typeDest.AsErrorType().HasTypeParent() || typeDest.AsErrorType().HasNSParent());
                    if (typeSrc != typeDest)
                    {
                        return(false);
                    }
                    if (needsExprDest)
                    {
                        exprDest = exprSrc;
                    }
                    return(true);

                case TypeKind.TK_NullType:
                    // Can only convert to the null type if src is null.
                    if (!typeSrc.IsNullType())
                    {
                        return(false);
                    }
                    if (needsExprDest)
                    {
                        exprDest = exprSrc;
                    }
                    return(true);

                case TypeKind.TK_MethodGroupType:
                    VSFAIL("Something is wrong with Type.IsNeverSameType()");
                    return(false);

                case TypeKind.TK_NaturalIntegerType:
                case TypeKind.TK_ArgumentListType:
                    return(typeSrc == typeDest);

                case TypeKind.TK_VoidType:
                    return(false);

                default:
                    break;
                }

                if (typeSrc.IsErrorType())
                {
                    Debug.Assert(!typeDest.IsErrorType());
                    return(false);
                }

                // 13.1.1 Identity conversion
                //
                // An identity conversion converts from any type to the same type. This conversion exists only
                // such that an entity that already has a required type can be said to be convertible to that type.

                if (typeSrc == typeDest &&
                    ((flags & CONVERTTYPE.ISEXPLICIT) == 0 || (!typeSrc.isPredefType(PredefinedType.PT_FLOAT) && !typeSrc.isPredefType(PredefinedType.PT_DOUBLE))))
                {
                    if (needsExprDest)
                    {
                        exprDest = exprSrc;
                    }
                    return(true);
                }

                if (typeDest.IsNullableType())
                {
                    return(BindNubConversion(typeDest.AsNullableType()));
                }

                if (typeSrc.IsNullableType())
                {
                    return(bindImplicitConversionFromNullable(typeSrc.AsNullableType()));
                }

                if ((flags & CONVERTTYPE.ISEXPLICIT) != 0)
                {
                    flags |= CONVERTTYPE.NOUDC;
                }

                // Get the fundamental types of destination.
                FUNDTYPE ftDest = typeDest.fundType();

                Debug.Assert(ftDest != FUNDTYPE.FT_NONE || typeDest.IsParameterModifierType());

                switch (typeSrc.GetTypeKind())
                {
                default:
                    VSFAIL("Bad type symbol kind");
                    break;

                case TypeKind.TK_MethodGroupType:
                    if (exprSrc.isMEMGRP())
                    {
                        EXPRCALL outExpr;
                        bool     retVal = binder.BindGrpConversion(exprSrc.asMEMGRP(), typeDest, needsExprDest, out outExpr, false);
                        exprDest = outExpr;
                        return(retVal);
                    }
                    return(false);

                case TypeKind.TK_VoidType:
                case TypeKind.TK_ErrorType:
                case TypeKind.TK_ParameterModifierType:
                case TypeKind.TK_ArgumentListType:
                    return(false);

                case TypeKind.TK_NullType:
                    if (bindImplicitConversionFromNull())
                    {
                        return(true);
                    }
                    // If not, try user defined implicit conversions.
                    break;

                case TypeKind.TK_ArrayType:
                    if (bindImplicitConversionFromArray())
                    {
                        return(true);
                    }
                    // If not, try user defined implicit conversions.
                    break;

                case TypeKind.TK_PointerType:
                    if (bindImplicitConversionFromPointer())
                    {
                        return(true);
                    }
                    // If not, try user defined implicit conversions.
                    break;

                case TypeKind.TK_TypeParameterType:
                    if (bindImplicitConversionFromTypeVar(typeSrc.AsTypeParameterType()))
                    {
                        return(true);
                    }
                    // If not, try user defined implicit conversions.
                    break;

                case TypeKind.TK_AggregateType:
                    // TypeReference and ArgIterator can't be boxed (or converted to anything else)
                    if (typeSrc.isSpecialByRefType())
                    {
                        return(false);
                    }
                    if (bindImplicitConversionFromAgg(typeSrc.AsAggregateType()))
                    {
                        return(true);
                    }
                    // If not, try user defined implicit conversions.
                    break;
                }

                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // RUNTIME BINDER ONLY CHANGE
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //
                // Every incoming dynamic operand should be implicitly convertible
                // to any type that it is an instance of.

                if (exprSrc != null &&
                    exprSrc.RuntimeObject != null &&
                    typeDest.AssociatedSystemType.IsInstanceOfType(exprSrc.RuntimeObject) &&
                    binder.GetSemanticChecker().CheckTypeAccess(typeDest, binder.Context.ContextForMemberLookup()))
                {
                    if (needsExprDest)
                    {
                        binder.bindSimpleCast(exprSrc, exprTypeDest, out exprDest, exprSrc.flags & EXPRFLAG.EXF_CANTBENULL);
                    }
                    return(true);
                }

                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // END RUNTIME BINDER ONLY CHANGE
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                // 13.1.8 User-defined implicit conversions
                //
                // A user-defined implicit conversion consists of an optional standard implicit conversion,
                // followed by execution of a user-defined implicit conversion operator, followed by another
                // optional standard implicit conversion. The exact rules for evaluating user-defined
                // conversions are described in 13.4.3.

                if (0 == (flags & CONVERTTYPE.NOUDC))
                {
                    return(binder.bindUserDefinedConversion(exprSrc, typeSrc, typeDest, needsExprDest, out exprDest, true));
                }

                // No conversion was found.

                return(false);
            }
Ejemplo n.º 4
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;
        }