GetNullable() public method

public GetNullable ( ) : AggregateSymbol
return AggregateSymbol
示例#1
0
        // Create an expr for new T?(exprSrc) where T is exprSrc.type.
        private static ExprCall BindNubNew(Expr exprSrc)
        {
            Debug.Assert(exprSrc != null);

            NullableType    pNubSourceType = TypeManager.GetNullable(exprSrc.Type);
            AggregateType   pSourceType    = pNubSourceType.GetAts();
            MethodSymbol    meth           = PredefinedMembers.GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR);
            MethWithInst    methwithinst   = new MethWithInst(meth, pSourceType, TypeArray.Empty);
            ExprMemberGroup memgroup       = ExprFactory.CreateMemGroup(null, methwithinst);

            return(ExprFactory.CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, exprSrc, memgroup, methwithinst));
        }
示例#2
0
        public AggregateType GetAts()
        {
            if (ats == null)
            {
                AggregateSymbol aggNullable  = typeManager.GetNullable();
                CType           typePar      = GetUnderlyingType();
                CType[]         typeParArray = { typePar };
                TypeArray       ta           = symmgr.AllocParams(1, typeParArray);
                ats = typeManager.GetAggregate(aggNullable, ta);
            }

            return(ats);
        }
示例#3
0
        private static void FixLiftedUserDefinedBinaryOperators(ExprBinOp expr, ref Expr pp1, ref Expr pp2)
        {
            // If we have lifted T1 op T2 to T1? op T2?, and we have an expression T1 op T2? or T1? op T2 then
            // we need to ensure that the unlifted actual arguments are promoted to their nullable CType.
            Debug.Assert(expr != null);
            Debug.Assert(pp1 != null);
            Debug.Assert(pp1 != null);
            Debug.Assert(pp2 != null);
            Debug.Assert(pp2 != null);
            MethodSymbol method = expr.UserDefinedCallMethod.Meth();
            Expr         orig1  = expr.OptionalLeftChild;
            Expr         orig2  = expr.OptionalRightChild;

            Debug.Assert(orig1 != null && orig2 != null);
            Expr  new1    = pp1;
            Expr  new2    = pp2;
            CType fptype1 = method.Params[0];
            CType fptype2 = method.Params[1];
            CType aatype1 = orig1.Type;
            CType aatype2 = orig2.Type;

            // Is the operator even a candidate for lifting?
            if (!(fptype1 is AggregateType fat1) ||
                !fat1.OwningAggregate.IsValueType() ||
                !(fptype2 is AggregateType fat2) ||
                !fat2.OwningAggregate.IsValueType())
            {
                return;
            }

            CType nubfptype1 = TypeManager.GetNullable(fptype1);
            CType nubfptype2 = TypeManager.GetNullable(fptype2);

            // If we have null op X, or T1 op T2?, or T1 op null, lift first arg to T1?
            if (aatype1 is NullType || aatype1 == fptype1 && (aatype2 == nubfptype2 || aatype2 is NullType))
            {
                new1 = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, new1, CreateTypeOf(nubfptype1));
            }

            // If we have X op null, or T1? op T2, or null op T2, lift second arg to T2?
            if (aatype2 is NullType || aatype2 == fptype2 && (aatype1 == nubfptype1 || aatype1 is NullType))
            {
                new2 = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, new2, CreateTypeOf(nubfptype2));
            }
            pp1 = new1;
            pp2 = new2;
        }
示例#4
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);
        }
示例#5
0
        private static 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   = TypeManager.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 = TypeManager.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  = ExprFactory.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));
        }
示例#6
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);
        }
示例#7
0
 public AggregateType GetAts() => _ats ?? (_ats = _typeManager.GetAggregate(
                                               _typeManager.GetNullable(), _symmgr.AllocParams(UnderlyingType)));
示例#8
0
 public override AggregateType GetAts() =>
 _ats ?? (_ats = TypeManager.GetAggregate(TypeManager.GetNullable(), TypeArray.Allocate(UnderlyingType)));
示例#9
0
        private Expr GenerateBuiltInBinaryOperator(ExprBinOp expr)
        {
            Debug.Assert(expr != null);

            PREDEFMETH pdm = expr.Kind switch
            {
                ExpressionKind.LeftShirt => PREDEFMETH.PM_EXPRESSION_LEFTSHIFT,
                ExpressionKind.RightShift => PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT,
                ExpressionKind.BitwiseExclusiveOr => PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR,
                ExpressionKind.BitwiseOr => PREDEFMETH.PM_EXPRESSION_OR,
                ExpressionKind.BitwiseAnd => PREDEFMETH.PM_EXPRESSION_AND,
                ExpressionKind.LogicalAnd => PREDEFMETH.PM_EXPRESSION_ANDALSO,
                ExpressionKind.LogicalOr => PREDEFMETH.PM_EXPRESSION_ORELSE,
                ExpressionKind.StringEq => PREDEFMETH.PM_EXPRESSION_EQUAL,
                ExpressionKind.Eq => PREDEFMETH.PM_EXPRESSION_EQUAL,
                ExpressionKind.StringNotEq => PREDEFMETH.PM_EXPRESSION_NOTEQUAL,
                ExpressionKind.NotEq => PREDEFMETH.PM_EXPRESSION_NOTEQUAL,
                ExpressionKind.GreaterThanOrEqual => PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL,
                ExpressionKind.LessThanOrEqual => PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL,
                ExpressionKind.LessThan => PREDEFMETH.PM_EXPRESSION_LESSTHAN,
                ExpressionKind.GreaterThan => PREDEFMETH.PM_EXPRESSION_GREATERTHAN,
                ExpressionKind.Modulo => PREDEFMETH.PM_EXPRESSION_MODULO,
                ExpressionKind.Divide => PREDEFMETH.PM_EXPRESSION_DIVIDE,
                ExpressionKind.Multiply => expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED : PREDEFMETH.PM_EXPRESSION_MULTIPLY,
                ExpressionKind.Subtract => expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED : PREDEFMETH.PM_EXPRESSION_SUBTRACT,
                ExpressionKind.Add => expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_ADDCHECKED : PREDEFMETH.PM_EXPRESSION_ADD,

                _ => throw Error.InternalCompilerError(),
            };
            Expr origL = expr.OptionalLeftChild;
            Expr origR = expr.OptionalRightChild;

            Debug.Assert(origL != null);
            Debug.Assert(origR != null);
            CType typeL = origL.Type;
            CType typeR = origR.Type;

            Expr newL = Visit(origL);
            Expr newR = Visit(origR);

            bool  didEnumConversion = false;
            CType convertL          = null;
            CType convertR          = null;

            if (typeL.IsEnumType)
            {
                // We have already inserted casts if not lifted, so we should never see an enum.
                Debug.Assert(expr.IsLifted);
                convertL          = TypeManager.GetNullable(typeL.UnderlyingEnumType);
                typeL             = convertL;
                didEnumConversion = true;
            }
            else if (typeL is NullableType nubL && nubL.UnderlyingType.IsEnumType)
            {
                Debug.Assert(expr.IsLifted);
                convertL          = TypeManager.GetNullable(nubL.UnderlyingType.UnderlyingEnumType);
                typeL             = convertL;
                didEnumConversion = true;
            }
            if (typeR.IsEnumType)
            {
                Debug.Assert(expr.IsLifted);
                convertR          = TypeManager.GetNullable(typeR.UnderlyingEnumType);
                typeR             = convertR;
                didEnumConversion = true;
            }
            else if (typeR is NullableType nubR && nubR.UnderlyingType.IsEnumType)
            {
                Debug.Assert(expr.IsLifted);
                convertR          = TypeManager.GetNullable(nubR.UnderlyingType.UnderlyingEnumType);
                typeR             = convertR;
                didEnumConversion = true;
            }
            if (typeL is NullableType nubL2 && nubL2.UnderlyingType == typeR)
            {
                convertR = typeL;
            }
            if (typeR is NullableType nubR2 && nubR2.UnderlyingType == typeL)
            {
                convertL = typeR;
            }

            if (convertL != null)
            {
                newL = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, newL, CreateTypeOf(convertL));
            }
            if (convertR != null)
            {
                newR = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, newR, CreateTypeOf(convertR));
            }

            Expr call = GenerateCall(pdm, newL, newR);

            if (didEnumConversion && expr.Type.StripNubs().IsEnumType)
            {
                call = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, CreateTypeOf(expr.Type));
            }

            return(call);
        }