상속: MethPropWithType
예제 #1
0
        // Value
        public Expr BindValue(Expr exprSrc)
        {
            Debug.Assert(exprSrc != null && exprSrc.Type is NullableType);

            // For new T?(x), the answer is x.
            if (IsNullableConstructor(exprSrc, out ExprCall call))
            {
                var args = call.OptionalArguments;
                Debug.Assert(args != null && !(args is ExprList));
                return(args);
            }

            NullableType   nubSrc   = (NullableType)exprSrc.Type;
            CType          typeBase = nubSrc.GetUnderlyingType();
            AggregateType  ats      = nubSrc.GetAts();
            PropertySymbol prop     = GetSymbolLoader().getBSymmgr().propNubValue;

            if (prop == null)
            {
                prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE);
                Debug.Assert(prop != null);
                GetSymbolLoader().getBSymmgr().propNubValue = prop;
            }

            PropWithType     pwt       = new PropWithType(prop, ats);
            MethPropWithInst mpwi      = new MethPropWithInst(prop, ats);
            ExprMemberGroup  pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi);

            return(GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, null));
        }
예제 #2
0
        public ExprProperty CreateProperty(CType pType, Expr pOptionalObject)
        {
            MethPropWithInst mwi       = new MethPropWithInst();
            ExprMemberGroup  pMemGroup = CreateMemGroup(pOptionalObject, mwi);

            return(CreateProperty(pType, null, null, pMemGroup, null, null, null));
        }
 public GroupToArgsBinderResult()
 {
     BestResult         = new MethPropWithInst();
     AmbiguousResult    = new MethPropWithInst();
     InaccessibleResult = new MethPropWithInst();
     UninferableResult  = new MethPropWithInst();
 }
        public EXPRPROP CreateProperty(CType pType, EXPR pOptionalObject)
        {
            MethPropWithInst mwi       = new MethPropWithInst();
            EXPRMEMGRP       pMemGroup = CreateMemGroup(pOptionalObject, mwi);

            return(CreateProperty(pType, null, null, pMemGroup, null, null, null));
        }
예제 #5
0
        public static ExprMemberGroup CreateMemGroup(Expr obj, MethPropWithInst method)
        {
            Name name = method.Sym?.name;

            return(CreateMemGroup(
                       0, name, method.TypeArgs, method.MethProp()?.getKind() ?? SYMKIND.SK_MethodSymbol, method.GetType(),
                       obj, new CMemberLookupResults(TypeArray.Allocate((CType)method.GetType()), name)));
        }
예제 #6
0
 public GroupToArgsBinderResult()
 {
     BestResult = new MethPropWithInst();
     AmbiguousResult = new MethPropWithInst();
     InaccessibleResult = new MethPropWithInst();
     UninferrableResult = new MethPropWithInst();
     InconvertibleResult = new MethPropWithInst();
     _inconvertibleResults = new List<MethPropWithInst>();
 }
예제 #7
0
 public GroupToArgsBinderResult()
 {
     BestResult            = new MethPropWithInst();
     AmbiguousResult       = new MethPropWithInst();
     InaccessibleResult    = new MethPropWithInst();
     UninferableResult     = new MethPropWithInst();
     InconvertibleResult   = new MethPropWithInst();
     _inconvertibleResults = new List <MethPropWithInst>();
 }
예제 #8
0
 public ExprUnaryOp(ExpressionKind kind, CType type, Expr operand, Expr call, MethPropWithInst userMethod)
     : base(kind, type, call, userMethod)
 {
     Debug.Assert(kind.IsUnaryOperator());
     Debug.Assert(operand != null);
     Debug.Assert(type != null);
     Debug.Assert(call != null);
     Debug.Assert(userMethod != null);
     Child = operand;
 }
예제 #9
0
 protected ExprOperator(ExpressionKind kind, CType type, Expr call, MethPropWithInst userDefinedMethod)
     : this(kind, type)
 {
     OptionalUserDefinedCall = call;
     UserDefinedCallMethod   = userDefinedMethod;
     if (call.HasError)
     {
         SetError();
     }
 }
예제 #10
0
        ////////////////////////////////////////////////////////////////////////////////
        // We need to rearange the method parameters so that the type of any specified named argument
        // appears in the same place as the named argument. Consider the example below:
        //    Foo(int x = 4, string y = "", long l = 4)
        //    Foo(string y = "", string x="", long l = 5)
        // and the call site:
        //    Foo(y:"a")
        // After rearranging the parameter types we will have:
        //   (string, int, long) and (string, string, long)
        // By rearranging the arguments as such we make sure that any specified named arguments appear in the same position for both
        // methods and we also maintain the relative order of the other parameters (the type long appears after int in the above example)

        private TypeArray RearrangeNamedArguments(TypeArray pta, MethPropWithInst mpwi,
                                                  CType pTypeThrough, ArgInfos args)
        {
#if DEBUG
            // We never have a named argument that is in a position in the argument
            // list past the end of what would be the formal parameter list.
            for (int i = pta.Count; i < args.carg; i++)
            {
                Debug.Assert(!(args.prgexpr[i] is ExprNamedArgumentSpecification));
            }
#endif
            // If we've no args we can skip. If the last argument isn't named then either we
            // have no named arguments, and we can skip, or we have non-trailing named arguments
            // and we MUST skip!
            if (args.carg == 0 || !(args.prgexpr[args.carg - 1] is ExprNamedArgumentSpecification))
            {
                return(pta);
            }

            CType   type     = pTypeThrough != null ? pTypeThrough : mpwi.GetType();
            CType[] typeList = new CType[pta.Count];
            MethodOrPropertySymbol methProp = GroupToArgsBinder.FindMostDerivedMethod(GetSymbolLoader(), mpwi.MethProp(), type);

            // We initialize the new type array with the parameters for the method.
            for (int iParam = 0; iParam < pta.Count; iParam++)
            {
                typeList[iParam] = pta[iParam];
            }

            var prgexpr = args.prgexpr;
            // We then go over the specified arguments and put the type for any named argument in the right position in the array.
            for (int iParam = 0; iParam < args.carg; iParam++)
            {
                if (prgexpr[iParam] is ExprNamedArgumentSpecification named)
                {
                    // We find the index of the type of the argument in the method parameter list and store that in a temp
                    int   index    = FindName(methProp.ParameterNames, named.Name);
                    CType tempType = pta[index];

                    // Starting from the current position in the type list up until the location of the type of the optional argument
                    //  We shift types by one:
                    //   before: (int, string, long)
                    //   after: (string, int, long)
                    // We only touch the types between the current position and the position of the type we need to move
                    for (int iShift = iParam; iShift < index; iShift++)
                    {
                        typeList[iShift + 1] = typeList[iShift];
                    }

                    typeList[iParam] = tempType;
                }
            }

            return(GetSymbolLoader().getBSymmgr().AllocParams(pta.Count, typeList));
        }
예제 #11
0
        public ExprMemberGroup CreateMemGroup(
            Expr pObject,
            MethPropWithInst mwi)
        {
            Name pName = mwi.Sym?.name;
            MethodOrPropertySymbol methProp = mwi.MethProp();

            CType pType = mwi.GetType() ?? (CType)GetTypes().GetErrorSym();

            return(CreateMemGroup(0, pName, mwi.TypeArgs, methProp?.getKind() ?? SYMKIND.SK_MethodSymbol, mwi.GetType(), methProp, pObject, new CMemberLookupResults(GetGlobalSymbols().AllocParams(1, new CType[] { pType }), pName)));
        }
예제 #12
0
        public ExprMemberGroup CreateMemGroup(Expr obj, MethPropWithInst method)
        {
            Name name = method.Sym?.name;
            MethodOrPropertySymbol methProp = method.MethProp();

            CType type = method.GetType() ?? (CType)Types.GetErrorSym();

            return(CreateMemGroup(
                       0, name, method.TypeArgs, methProp?.getKind() ?? SYMKIND.SK_MethodSymbol, method.GetType(), methProp,
                       obj, new CMemberLookupResults(GlobalSymbols.AllocParams(1, new[] { type }), name)));
        }
예제 #13
0
        ////////////////////////////////////////////////////////////////////////////////
        // We need to rearange the method parameters so that the type of any specified named argument
        // appears in the same place as the named argument. Consider the example below:
        //    Foo(int x = 4, string y = "", long l = 4)
        //    Foo(string y = "", string x="", long l = 5)
        // and the call site:
        //    Foo(y:"a")
        // After rearanging the parameter types we will have:
        //   (string, int, long) and (string, string, long)
        // By rearanging the arguments as such we make sure that any specified named arguments appear in the same position for both
        // methods and we also maintain the relative order of the other parameters (the type long appears after int in the above example)

        private TypeArray RearrangeNamedArguments(TypeArray pta, MethPropWithInst mpwi,
                                                  CType pTypeThrough, ArgInfos args)
        {
            if (!args.fHasExprs)
            {
                return(pta);
            }

        #if DEBUG
            // We never have a named argument that is in a position in the argument
            // list past the end of what would be the formal parameter list.
            for (int i = pta.size; i < args.carg; i++)
            {
                Debug.Assert(!args.prgexpr[i].isNamedArgumentSpecification());
            }
        #endif

            CType   type     = pTypeThrough != null ? pTypeThrough : mpwi.GetType();
            CType[] typeList = new CType[pta.size];
            MethodOrPropertySymbol methProp = GroupToArgsBinder.FindMostDerivedMethod(GetSymbolLoader(), mpwi.MethProp(), type);

            // We initialize the new type array with the parameters for the method.
            for (int iParam = 0; iParam < pta.size; iParam++)
            {
                typeList[iParam] = pta.Item(iParam);
            }

            // We then go over the specified arguments and put the type for any named argument in the right position in the array.
            for (int iParam = 0; iParam < args.carg; iParam++)
            {
                EXPR arg = args.prgexpr[iParam];
                if (arg.isNamedArgumentSpecification())
                {
                    // We find the index of the type of the argument in the method parameter list and store that in a temp
                    int   index    = FindName(methProp.ParameterNames, arg.asNamedArgumentSpecification().Name);
                    CType tempType = pta.Item(index);

                    // Starting from the current position in the type list up until the location of the type of the optional argument
                    //  We shift types by one:
                    //   before: (int, string, long)
                    //   after: (string, int, long)
                    // We only touch the types between the current position and the position of the type we need to move
                    for (int iShift = iParam; iShift < index; iShift++)
                    {
                        typeList[iShift + 1] = typeList[iShift];
                    }

                    typeList[iParam] = tempType;
                }
            }

            return(GetSymbolLoader().getBSymmgr().AllocParams(pta.size, typeList));
        }
        public EXPRMEMGRP CreateMemGroup(
            EXPR pObject,
            MethPropWithInst mwi)
        {
            Name pName = mwi.Sym != null ? mwi.Sym.name : null;
            MethodOrPropertySymbol methProp = mwi.MethProp();

            CType pType = mwi.GetType();

            if (pType == null)
            {
                pType = GetTypes().GetErrorSym();
            }

            return(CreateMemGroup(0, pName, mwi.TypeArgs, methProp != null ? methProp.getKind() : SYMKIND.SK_MethodSymbol, mwi.GetType(), methProp, pObject, new CMemberLookupResults(GetGlobalSymbols().AllocParams(1, new CType[] { pType }), pName)));
        }
예제 #15
0
파일: Nullable.cs 프로젝트: jnm2/corefx
        // Value
        public Expr BindValue(Expr exprSrc)
        {
            Debug.Assert(exprSrc != null && exprSrc.Type.IsNullableType());

            // For new T?(x), the answer is x.
            if (IsNullableConstructor(exprSrc, out ExprCall call))
            {
                var args = call.OptionalArguments;
                Debug.Assert(args != null && !(args is ExprList));
                return(args);
            }

            CType         typeBase = exprSrc.Type.AsNullableType().GetUnderlyingType();
            AggregateType ats      = exprSrc.Type.AsNullableType().GetAts(GetErrorContext());

            if (ats == null)
            {
                ExprProperty rval = GetExprFactory().CreateProperty(typeBase, exprSrc);
                rval.SetError();
                return(rval);
            }

            PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue;

            if (prop == null)
            {
                prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE);
                GetSymbolLoader().getBSymmgr().propNubValue = prop;
            }

            PropWithType     pwt       = new PropWithType(prop, ats);
            MethWithType     mwt       = new MethWithType(prop?.methGet, ats);
            MethPropWithInst mpwi      = new MethPropWithInst(prop, ats);
            ExprMemberGroup  pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi);
            ExprProperty     exprRes   = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null);

            if (prop == null)
            {
                exprRes.SetError();
            }

            return(exprRes);
        }
예제 #16
0
        // Value
        public EXPR BindValue(EXPR exprSrc)
        {
            Debug.Assert(exprSrc != null && exprSrc.type.IsNullableType());

            // For new T?(x), the answer is x.
            if (CNullable.IsNullableConstructor(exprSrc))
            {
                Debug.Assert(exprSrc.asCALL().GetOptionalArguments() != null && !exprSrc.asCALL().GetOptionalArguments().isLIST());
                return(exprSrc.asCALL().GetOptionalArguments());
            }

            CType         typeBase = exprSrc.type.AsNullableType().GetUnderlyingType();
            AggregateType ats      = exprSrc.type.AsNullableType().GetAts(GetErrorContext());

            if (ats == null)
            {
                EXPRPROP rval = GetExprFactory().CreateProperty(typeBase, exprSrc);
                rval.SetError();
                return(rval);
            }

            // UNDONE: move this to transform pass ...
            PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue;

            if (prop == null)
            {
                prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE);
                GetSymbolLoader().getBSymmgr().propNubValue = prop;
            }

            PropWithType     pwt       = new PropWithType(prop, ats);
            MethWithType     mwt       = new MethWithType(prop != null ? prop.methGet : null, ats);
            MethPropWithInst mpwi      = new MethPropWithInst(prop, ats);
            EXPRMEMGRP       pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi);
            EXPRPROP         exprRes   = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null);

            if (prop == null)
            {
                exprRes.SetError();
            }

            return(exprRes);
        }
예제 #17
0
 public static ExprMethodInfo CreateMethodInfo(MethPropWithInst mwi) =>
 CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs);
예제 #18
0
 // The call may be lifted, but we do not mark the outer binop as lifted.
 public static ExprUnaryOp CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType type, Expr operand, ExprCall call, MethPropWithInst userMethod) =>
 new ExprUnaryOp(exprKind, type, operand, call, userMethod);
        public EXPRUNARYOP CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType pType, EXPR pOperand, EXPR call, MethPropWithInst pmpwi)
        {
            Debug.Assert(pType != null);
            Debug.Assert(pOperand != null);
            Debug.Assert(call != null);
            Debug.Assert(pmpwi != null);
            EXPRUNARYOP rval = new EXPRUNARYOP();

            rval.kind  = exprKind;
            rval.type  = pType;
            rval.flags = 0;
            rval.Child = pOperand;
            // The call may be lifted, but we do not mark the outer binop as lifted.
            rval.OptionalUserDefinedCall = call;
            rval.UserDefinedCallMethod   = pmpwi;
            if (call.HasError())
            {
                rval.SetError();
            }
            Debug.Assert(rval != null);
            return(rval);
        }
 public EXPRMETHODINFO CreateMethodInfo(MethPropWithInst mwi)
 {
     return(CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs));
 }
예제 #21
0
 public EXPRBINOP CreateUserDefinedBinop(ExpressionKind exprKind, CType pType, EXPR p1, EXPR p2, EXPR call, MethPropWithInst pmpwi)
 {
     Debug.Assert(p1 != null);
     Debug.Assert(p2 != null);
     Debug.Assert(call != null);
     EXPRBINOP rval = new EXPRBINOP();
     rval.kind = exprKind;
     rval.type = pType;
     rval.flags = EXPRFLAG.EXF_BINOP;
     rval.SetOptionalLeftChild(p1);
     rval.SetOptionalRightChild(p2);
     // The call may be lifted, but we do not mark the outer binop as lifted.
     rval.isLifted = false;
     rval.SetOptionalUserDefinedCall(call);
     rval.SetUserDefinedCallMethod(pmpwi);
     if (call.HasError())
     {
         rval.SetError();
     }
     Debug.Assert(rval != null);
     return (rval);
 }
예제 #22
0
        public ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType pType, Expr p1, Expr p2, Expr call, MethPropWithInst pmpwi)
        {
            Debug.Assert(p1 != null);
            Debug.Assert(p2 != null);
            Debug.Assert(call != null);
            ExprBinOp rval = new ExprBinOp();

            rval.Kind               = exprKind;
            rval.Type               = pType;
            rval.Flags              = EXPRFLAG.EXF_BINOP;
            rval.OptionalLeftChild  = p1;
            rval.OptionalRightChild = p2;
            // The call may be lifted, but we do not mark the outer binop as lifted.
            rval.IsLifted = false;
            rval.OptionalUserDefinedCall = call;
            rval.UserDefinedCallMethod   = pmpwi;
            if (call.HasError)
            {
                rval.SetError();
            }
            Debug.Assert(rval != null);
            return(rval);
        }
예제 #23
0
        public ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType pType, Expr p1, Expr p2, Expr call, MethPropWithInst pmpwi)
        {
            Debug.Assert(p1 != null);
            Debug.Assert(p2 != null);
            Debug.Assert(call != null);
            ExprBinOp rval = new ExprBinOp(exprKind, pType);

            rval.Flags                   = EXPRFLAG.EXF_BINOP;
            rval.OptionalLeftChild       = p1;
            rval.OptionalRightChild      = p2;
            rval.OptionalUserDefinedCall = call;
            rval.UserDefinedCallMethod   = pmpwi;
            if (call.HasError)
            {
                rval.SetError();
            }
            return(rval);
        }
예제 #24
0
        public ExprUnaryOp CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType pType, Expr pOperand, ExprCall call, MethPropWithInst pmpwi)
        {
            Debug.Assert(pType != null);
            Debug.Assert(pOperand != null);
            Debug.Assert(call != null);
            Debug.Assert(pmpwi != null);
            ExprUnaryOp rval = new ExprUnaryOp(exprKind, pType);

            rval.Child = pOperand;
            // The call may be lifted, but we do not mark the outer binop as lifted.
            rval.OptionalUserDefinedCall = call;
            rval.UserDefinedCallMethod   = pmpwi;
            if (call.HasError)
            {
                rval.SetError();
            }
            return(rval);
        }
예제 #25
0
        private EXPRCALL BindLiftedUDUnop(EXPR arg, CType typeArg, MethPropWithInst mpwi)
        {
            CType typeRaw = typeArg.StripNubs();
            if (!arg.type.IsNullableType() || !canConvert(arg.type.StripNubs(), typeRaw, CONVERTTYPE.NOUDC))
            {
                // Convert then lift.
                arg = mustConvert(arg, typeArg);
            }
            Debug.Assert(arg.type.IsNullableType());

            CType typeRet = GetTypes().SubstType(mpwi.Meth().RetType, mpwi.GetType());
            if (!typeRet.IsNullableType())
            {
                typeRet = GetTypes().GetNullable(typeRet);
            }

            // First bind the non-lifted version for errors.
            EXPR nonLiftedArg = mustCast(arg, typeRaw);
            EXPRCALL nonLiftedResult = BindUDUnopCall(nonLiftedArg, typeRaw, mpwi);

            EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi);
            EXPRCALL call = GetExprFactory().CreateCall(0, typeRet, arg, pMemGroup, null);
            call.mwi = new MethWithInst(mpwi);
            call.castOfNonLiftedResultToLiftedType = mustCast(nonLiftedResult, typeRet, 0);
            call.nubLiftKind = NullableCallLiftKind.Operator;
            return call;
        }
예제 #26
0
파일: WithType.cs 프로젝트: jnm2/corefx
 public MethWithInst(MethPropWithInst mpwi)
 {
     Set(mpwi.Sym.AsMethodSymbol(), mpwi.Ats, mpwi.TypeArgs);
 }
예제 #27
0
파일: Operators.cs 프로젝트: ESgarbi/corefx
        private EXPRCALL BindUDBinop(ExpressionKind ek, EXPR arg1, EXPR arg2, bool fDontLift, out MethPropWithInst ppmpwi)
        {
            List<CandidateFunctionMember> methFirst = new List<CandidateFunctionMember>();

            ppmpwi = null;

            AggregateType[] rgats = { null, null };
            int cats = GetUserDefinedBinopArgumentTypes(arg1.type, arg2.type, rgats);
            if (cats == 0)
            {
                return null;
            }
            else if (cats == 1)
            {
                GetApplicableUserDefinedBinaryOperatorCandidatesInBaseTypes(methFirst, ek,
                    rgats[0], arg1, arg2, fDontLift, null);
            }
            else
            {
                Debug.Assert(cats == 2);
                AggregateType atsStop = GetApplicableUserDefinedBinaryOperatorCandidatesInBaseTypes(methFirst, ek,
                    rgats[0], arg1, arg2, fDontLift, null);
                GetApplicableUserDefinedBinaryOperatorCandidatesInBaseTypes(methFirst, ek,
                    rgats[1], arg1, arg2, fDontLift, atsStop);
            }
            if (methFirst.IsEmpty())
            {
                return null;
            }

            EXPRLIST args = GetExprFactory().CreateList(arg1, arg2);
            ArgInfos info = new ArgInfos();
            info.carg = 2;
            FillInArgInfoFromArgList(info, args);
            CandidateFunctionMember pmethAmbig1;
            CandidateFunctionMember pmethAmbig2;
            CandidateFunctionMember pmethBest = FindBestMethod(methFirst, null, info, out pmethAmbig1, out pmethAmbig2);

            if (pmethBest == null)
            {
                // No winner, so its an ambiguous call...
                GetErrorContext().Error(ErrorCode.ERR_AmbigCall, pmethAmbig1.mpwi, pmethAmbig2.mpwi);

                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, pmethAmbig1.mpwi);
                EXPRCALL rval = GetExprFactory().CreateCall(0, null, GetExprFactory().CreateList(arg1, arg2), pMemGroup, null);
                rval.SetError();
                return rval;
            }

            if (GetSemanticChecker().CheckBogus(pmethBest.mpwi.Meth()))
            {
                GetErrorContext().ErrorRef(ErrorCode.ERR_BindToBogus, pmethBest.mpwi);

                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, pmethBest.mpwi);
                EXPRCALL rval = GetExprFactory().CreateCall(0, null, GetExprFactory().CreateList(arg1, arg2), pMemGroup, null);
                rval.SetError();
                return rval;
            }

            ppmpwi = pmethBest.mpwi;

            if (pmethBest.ctypeLift != 0)
            {
                Debug.Assert(pmethBest.ctypeLift == 2);

                return BindLiftedUDBinop(ek, arg1, arg2, pmethBest.@params, pmethBest.mpwi);
            }

            CType typeRetRaw = GetTypes().SubstType(pmethBest.mpwi.Meth().RetType, pmethBest.mpwi.GetType());

            return BindUDBinopCall(arg1, arg2, pmethBest.@params, typeRetRaw, pmethBest.mpwi);
        }
예제 #28
0
        // Value
        public EXPR BindValue(EXPR exprSrc)
        {
            Debug.Assert(exprSrc != null && exprSrc.type.IsNullableType());

            // For new T?(x), the answer is x.
            if (CNullable.IsNullableConstructor(exprSrc))
            {
                Debug.Assert(exprSrc.asCALL().GetOptionalArguments() != null && !exprSrc.asCALL().GetOptionalArguments().isLIST());
                return exprSrc.asCALL().GetOptionalArguments();
            }

            CType typeBase = exprSrc.type.AsNullableType().GetUnderlyingType();
            AggregateType ats = exprSrc.type.AsNullableType().GetAts(GetErrorContext());
            if (ats == null)
            {
                EXPRPROP rval = GetExprFactory().CreateProperty(typeBase, exprSrc);
                rval.SetError();
                return rval;
            }

            PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue;
            if (prop == null)
            {
                prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE);
                GetSymbolLoader().getBSymmgr().propNubValue = prop;
            }

            PropWithType pwt = new PropWithType(prop, ats);
            MethWithType mwt = new MethWithType(prop != null ? prop.methGet : null, ats);
            MethPropWithInst mpwi = new MethPropWithInst(prop, ats);
            EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi);
            EXPRPROP exprRes = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null);

            if (prop == null)
            {
                exprRes.SetError();
            }

            return exprRes;
        }
예제 #29
0
파일: Better.cs 프로젝트: dotnet/corefx
        ////////////////////////////////////////////////////////////////////////////////
        // We need to rearange the method parameters so that the type of any specified named argument
        // appears in the same place as the named argument. Consider the example below:
        //    Foo(int x = 4, string y = "", long l = 4)
        //    Foo(string y = "", string x="", long l = 5)
        // and the call site:
        //    Foo(y:"a")
        // After rearranging the parameter types we will have:
        //   (string, int, long) and (string, string, long)
        // By rearranging the arguments as such we make sure that any specified named arguments appear in the same position for both
        // methods and we also maintain the relative order of the other parameters (the type long appears after int in the above example)

        private TypeArray RearrangeNamedArguments(TypeArray pta, MethPropWithInst mpwi,
            CType pTypeThrough, ArgInfos args)
        {
            if (!args.fHasExprs)
            {
                return pta;
            }

#if DEBUG
            // We never have a named argument that is in a position in the argument
            // list past the end of what would be the formal parameter list.
            for (int i = pta.size; i < args.carg; i++)
            {
                Debug.Assert(!args.prgexpr[i].isNamedArgumentSpecification());
            }
#endif

            CType type = pTypeThrough != null ? pTypeThrough : mpwi.GetType();
            CType[] typeList = new CType[pta.size];
            MethodOrPropertySymbol methProp = GroupToArgsBinder.FindMostDerivedMethod(GetSymbolLoader(), mpwi.MethProp(), type);

            // We initialize the new type array with the parameters for the method. 
            for (int iParam = 0; iParam < pta.size; iParam++)
            {
                typeList[iParam] = pta.Item(iParam);
            }

            // We then go over the specified arguments and put the type for any named argument in the right position in the array.
            for (int iParam = 0; iParam < args.carg; iParam++)
            {
                EXPR arg = args.prgexpr[iParam];
                if (arg.isNamedArgumentSpecification())
                {
                    // We find the index of the type of the argument in the method parameter list and store that in a temp
                    int index = FindName(methProp.ParameterNames, arg.asNamedArgumentSpecification().Name);
                    CType tempType = pta.Item(index);

                    // Starting from the current position in the type list up until the location of the type of the optional argument
                    //  We shift types by one:
                    //   before: (int, string, long)
                    //   after: (string, int, long)
                    // We only touch the types between the current position and the position of the type we need to move
                    for (int iShift = iParam; iShift < index; iShift++)
                    {
                        typeList[iShift + 1] = typeList[iShift];
                    }

                    typeList[iParam] = tempType;
                }
            }

            return GetSymbolLoader().getBSymmgr().AllocParams(pta.size, typeList);
        }
예제 #30
0
파일: Operators.cs 프로젝트: ESgarbi/corefx
        private EXPRCALL BindUDBinopCall(EXPR arg1, EXPR arg2, TypeArray Params, CType typeRet, MethPropWithInst mpwi)
        {
            arg1 = mustConvert(arg1, Params.Item(0));
            arg2 = mustConvert(arg2, Params.Item(1));
            EXPRLIST args = GetExprFactory().CreateList(arg1, arg2);

            checkUnsafe(arg1.type); // added to the binder so we don't bind to pointer ops
            checkUnsafe(arg2.type); // added to the binder so we don't bind to pointer ops
            checkUnsafe(typeRet); // added to the binder so we don't bind to pointer ops


            EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi);
            EXPRCALL call = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, null);
            call.mwi = new MethWithInst(mpwi);
            verifyMethodArgs(call, mpwi.GetType());
            return call;
        }
예제 #31
0
파일: Operators.cs 프로젝트: ESgarbi/corefx
        private EXPRCALL BindLiftedUDBinop(ExpressionKind ek, EXPR arg1, EXPR arg2, TypeArray Params, MethPropWithInst mpwi)
        {
            EXPR exprVal1 = arg1;
            EXPR exprVal2 = arg2;
            TypeArray paramsRaw;
            CType typeRet;
            CType typeRetRaw = GetTypes().SubstType(mpwi.Meth().RetType, mpwi.GetType());

            // This is a lifted user defined operator.  We know that both arguments
            // go to the nullable formal parameter types, and that at least one
            // of the arguments does not go to the non-nullable formal parameter type.
            // (If both went to the non-nullable types then we would not be lifting.)
            // We also know that the non-nullable type of the argument goes to the
            // non-nullable type of formal parameter.  However, if it does so only via
            // a user-defined conversion then we should bind the conversion from the
            // argument to the nullable formal parameter type first, before we then
            // do the cast for the non-nullable call.

            paramsRaw = GetTypes().SubstTypeArray(mpwi.Meth().Params, mpwi.GetType());
            Debug.Assert(Params != paramsRaw);
            Debug.Assert(paramsRaw.Item(0) == Params.Item(0).GetBaseOrParameterOrElementType());
            Debug.Assert(paramsRaw.Item(1) == Params.Item(1).GetBaseOrParameterOrElementType());

            if (!canConvert(arg1.type.StripNubs(), paramsRaw.Item(0), CONVERTTYPE.NOUDC))
            {
                exprVal1 = mustConvert(arg1, Params.Item(0));
            }
            if (!canConvert(arg2.type.StripNubs(), paramsRaw.Item(1), CONVERTTYPE.NOUDC))
            {
                exprVal2 = mustConvert(arg2, Params.Item(1));
            }
            EXPR nonLiftedArg1 = mustCast(exprVal1, paramsRaw.Item(0));
            EXPR nonLiftedArg2 = mustCast(exprVal2, paramsRaw.Item(1));
            switch (ek)
            {
                default:
                    typeRet = GetTypes().GetNullable(typeRetRaw);
                    break;
                case ExpressionKind.EK_EQ:
                case ExpressionKind.EK_NE:
                    Debug.Assert(paramsRaw.Item(0) == paramsRaw.Item(1));
                    Debug.Assert(typeRetRaw.isPredefType(PredefinedType.PT_BOOL));
                    // These ones don't lift the return type. Instead, if either side is null, the result is false.
                    typeRet = typeRetRaw;
                    break;
                case ExpressionKind.EK_GT:
                case ExpressionKind.EK_GE:
                case ExpressionKind.EK_LT:
                case ExpressionKind.EK_LE:
                    Debug.Assert(typeRetRaw.isPredefType(PredefinedType.PT_BOOL));
                    // These ones don't lift the return type. Instead, if either side is null, the result is false.
                    typeRet = typeRetRaw;
                    break;
            }

            // Now get the result for the pre-lifted call.

            Debug.Assert(!(ek == ExpressionKind.EK_EQ || ek == ExpressionKind.EK_NE) || nonLiftedArg1.type == nonLiftedArg2.type);

            EXPRCALL nonLiftedResult = BindUDBinopCall(nonLiftedArg1, nonLiftedArg2, paramsRaw, typeRetRaw, mpwi);

            EXPRLIST args = GetExprFactory().CreateList(exprVal1, exprVal2);
            EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi);
            EXPRCALL call = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, null);
            call.mwi = new MethWithInst(mpwi);

            switch (ek)
            {
                case ExpressionKind.EK_EQ:
                    call.nubLiftKind = NullableCallLiftKind.EqualityOperator;
                    break;

                case ExpressionKind.EK_NE:
                    call.nubLiftKind = NullableCallLiftKind.InequalityOperator;
                    break;

                default:
                    call.nubLiftKind = NullableCallLiftKind.Operator;
                    break;
            }

            call.castOfNonLiftedResultToLiftedType = mustCast(nonLiftedResult, typeRet, 0);
            return call;
        }
예제 #32
0
        private BetterType WhichMethodIsBetterTieBreaker(
            CandidateFunctionMember node1,
            CandidateFunctionMember node2,
            CType pTypeThrough,
            ArgInfos args)
        {
            MethPropWithInst mpwi1 = node1.mpwi;
            MethPropWithInst mpwi2 = node2.mpwi;

            // Same signatures. If they have different lifting numbers, the smaller number wins.
            // Otherwise, if one is generic and the other isn't then the non-generic wins.
            // Otherwise, if one is expanded and the other isn't then the non-expanded wins.
            // Otherwise, if one has fewer modopts than the other then it wins.
            if (node1.ctypeLift != node2.ctypeLift)
            {
                return(node1.ctypeLift < node2.ctypeLift ? BetterType.Left : BetterType.Right);
            }

            // Non-generic wins.
            if (mpwi1.TypeArgs.Count != 0)
            {
                if (mpwi2.TypeArgs.Count == 0)
                {
                    return(BetterType.Right);
                }
            }
            else if (mpwi2.TypeArgs.Count != 0)
            {
                return(BetterType.Left);
            }

            // Non-expanded wins
            if (node1.fExpanded)
            {
                if (!node2.fExpanded)
                {
                    return(BetterType.Right);
                }
            }
            else if (node2.fExpanded)
            {
                return(BetterType.Left);
            }

            // See if one's parameter types (un-instantiated) are more specific.
            BetterType nT = GetGlobalSymbols().CompareTypes(
                RearrangeNamedArguments(mpwi1.MethProp().Params, mpwi1, pTypeThrough, args),
                RearrangeNamedArguments(mpwi2.MethProp().Params, mpwi2, pTypeThrough, args));

            if (nT == BetterType.Left || nT == BetterType.Right)
            {
                return(nT);
            }

            // Fewer modopts wins.
            if (mpwi1.MethProp().modOptCount != mpwi2.MethProp().modOptCount)
            {
                return(mpwi1.MethProp().modOptCount < mpwi2.MethProp().modOptCount ? BetterType.Left : BetterType.Right);
            }

            // Bona-fide tie.
            return(BetterType.Neither);
        }
예제 #33
0
 public EXPRPROP CreateProperty(CType pType, EXPR pOptionalObject)
 {
     MethPropWithInst mwi = new MethPropWithInst();
     EXPRMEMGRP pMemGroup = CreateMemGroup(pOptionalObject, mwi);
     return CreateProperty(pType, null, null, pMemGroup, null, null, null);
 }
예제 #34
0
 public ExprMethodInfo CreateMethodInfo(MethPropWithInst mwi)
 {
     return(CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs));
 }
예제 #35
0
        ////////////////////////////////////////////////////////////////////////////////

        internal EXPR BindToField(EXPR pOptionalObject, FieldWithType fwt, BindingFlag bindFlags, EXPR pOptionalLHS)
        {
            Debug.Assert(fwt.GetType() != null && fwt.Field().getClass() == fwt.GetType().getAggregate());

            CType pFieldType = GetTypes().SubstType(fwt.Field().GetType(), fwt.GetType());
            if (pOptionalObject != null && !pOptionalObject.isOK())
            {
                EXPRFIELD pField = GetExprFactory().CreateField(0, pFieldType, pOptionalObject, 0, fwt, pOptionalLHS);
                pField.SetError();
                return pField;
            }

            EXPR pOriginalObject = pOptionalObject;
            bool bIsMatchingStatic;
            bool pfConstrained;
            pOptionalObject = AdjustMemberObject(fwt, pOptionalObject, out pfConstrained, out bIsMatchingStatic);

            checkUnsafe(pFieldType); // added to the binder so we don't bind to pointer ops

            EXPRFIELD pResult;
            {
                bool isLValue = false;
                if ((pOptionalObject != null && pOptionalObject.type.IsPointerType()) || objectIsLvalue(pOptionalObject))
                {
                    isLValue = true;
                }
                // Exception: a readonly field is not an lvalue unless we're in the constructor/static constructor appropriate
                // for the field.
                if (RespectReadonly() && fwt.Field().isReadOnly)
                {
                    if (ContainingAgg() == null ||
                        !InMethod() || !InConstructor() ||
                        fwt.Field().getClass() != ContainingAgg() ||
                        InStaticMethod() != fwt.Field().isStatic ||
                        (pOptionalObject != null && !isThisPointer(pOptionalObject)) ||
                        InAnonymousMethod())
                    {
                        isLValue = false;
                    }
                }

                pResult = GetExprFactory().CreateField(isLValue ? EXPRFLAG.EXF_LVALUE : 0, pFieldType, pOptionalObject, 0, fwt, pOptionalLHS);
                if (!bIsMatchingStatic)
                {
                    pResult.SetMismatchedStaticBit();
                }

                if (pFieldType.IsErrorType())
                {
                    pResult.SetError();
                }
                Debug.Assert(BindingFlag.BIND_MEMBERSET == (BindingFlag)EXPRFLAG.EXF_MEMBERSET);
                pResult.flags |= (EXPRFLAG)(bindFlags & BindingFlag.BIND_MEMBERSET);
            }

            // If this field is the backing field of a WindowsRuntime event then we need to bind to its
            // invocationlist property which is a delegate containing all the handlers.
            if (pResult.isFIELD() &&
                fwt.Field().isEvent &&
                fwt.Field().getEvent(GetSymbolLoader()) != null &&
                fwt.Field().getEvent(GetSymbolLoader()).IsWindowsRuntimeEvent)
            {
                CType fieldType = fwt.Field().GetType();
                if (fieldType.IsAggregateType())
                {
                    // Access event backing field (EventRegistrationTokenTable<T>) using
                    // EventRegistrationTokenTable<T>.GetOrCreateEventRegistrationTokenTable()
                    // to ensure non-null
                    pResult.setType(GetTypes().GetParameterModifier(pResult.type, false));

                    Name getOrCreateMethodName = GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_GETORCREATEEVENTREGISTRATIONTOKENTABLE);
                    GetSymbolLoader().RuntimeBinderSymbolTable.PopulateSymbolTableWithName(getOrCreateMethodName.Text, null, fieldType.AssociatedSystemType);
                    MethodSymbol getOrCreateMethod = GetSymbolLoader().LookupAggMember(getOrCreateMethodName, fieldType.getAggregate(), symbmask_t.MASK_MethodSymbol).AsMethodSymbol();

                    MethPropWithInst getOrCreatempwi = new MethPropWithInst(getOrCreateMethod, fieldType.AsAggregateType());
                    EXPRMEMGRP getOrCreateGrp = GetExprFactory().CreateMemGroup(null, getOrCreatempwi);

                    EXPR getOrCreateCall = BindToMethod(new MethWithInst(getOrCreatempwi),
                                                        pResult,
                                                        getOrCreateGrp,
                                                        (MemLookFlags)MemLookFlags.None);

                    AggregateSymbol fieldTypeSymbol = fieldType.AsAggregateType().GetOwningAggregate();
                    Name invocationListName = GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_INVOCATIONLIST);

                    // InvocationList might not be populated in the symbol table as no one would have called it.
                    GetSymbolLoader().RuntimeBinderSymbolTable.PopulateSymbolTableWithName(invocationListName.Text, null, fieldType.AssociatedSystemType);
                    PropertySymbol invocationList = GetSymbolLoader().LookupAggMember(
                                                        invocationListName,
                                                        fieldTypeSymbol,
                                                        symbmask_t.MASK_PropertySymbol).AsPropertySymbol();

                    MethPropWithInst mpwi = new MethPropWithInst(invocationList, fieldType.AsAggregateType());
                    EXPRMEMGRP memGroup = GetExprFactory().CreateMemGroup(getOrCreateCall, mpwi);

                    PropWithType pwt = new PropWithType(invocationList, fieldType.AsAggregateType());
                    EXPR propertyExpr = BindToProperty(getOrCreateCall, pwt, bindFlags, null, null, memGroup);
                    return propertyExpr;
                }
            }

            return pResult;
        }
예제 #36
0
 public EXPRUNARYOP CreateUserDefinedUnaryOperator(ExpressionKind exprKind, CType pType, EXPR pOperand, EXPR call, MethPropWithInst pmpwi)
 {
     Debug.Assert(pType != null);
     Debug.Assert(pOperand != null);
     Debug.Assert(call != null);
     Debug.Assert(pmpwi != null);
     EXPRUNARYOP rval = new EXPRUNARYOP();
     rval.kind = exprKind;
     rval.type = pType;
     rval.flags = 0;
     rval.Child = pOperand;
     // The call may be lifted, but we do not mark the outer binop as lifted.
     rval.OptionalUserDefinedCall = call;
     rval.UserDefinedCallMethod = pmpwi;
     if (call.HasError())
     {
         rval.SetError();
     }
     Debug.Assert(rval != null);
     return (rval);
 }
예제 #37
0
파일: ErrorFmt.cs 프로젝트: noahfalk/corefx
 public ErrArg(MethPropWithInst mpwi)
 {
     this.eak = ErrArgKind.MethWithInst;
     this.eaf = ErrArgFlags.None;
     this.mpwiMemo = new MethPropWithInstMemo();
     this.mpwiMemo.sym = mpwi.Sym;
     this.mpwiMemo.ats = mpwi.Ats;
     this.mpwiMemo.typeArgs = mpwi.TypeArgs;
 }
예제 #38
0
 public EXPRMETHODINFO CreateMethodInfo(MethPropWithInst mwi)
 {
     return CreateMethodInfo(mwi.Meth(), mwi.GetType(), mwi.TypeArgs);
 }
예제 #39
0
파일: ErrorFmt.cs 프로젝트: noahfalk/corefx
 public ErrArgRef(MethPropWithInst mpwi)
     : base(mpwi)
 {
     this.eaf = ErrArgFlags.Ref;
 }
        public EXPRBINOP CreateUserDefinedBinop(ExpressionKind exprKind, CType pType, EXPR p1, EXPR p2, EXPR call, MethPropWithInst pmpwi)
        {
            Debug.Assert(p1 != null);
            Debug.Assert(p2 != null);
            Debug.Assert(call != null);
            EXPRBINOP rval = new EXPRBINOP();

            rval.kind  = exprKind;
            rval.type  = pType;
            rval.flags = EXPRFLAG.EXF_BINOP;
            rval.SetOptionalLeftChild(p1);
            rval.SetOptionalRightChild(p2);
            // The call may be lifted, but we do not mark the outer binop as lifted.
            rval.isLifted = false;
            rval.SetOptionalUserDefinedCall(call);
            rval.SetUserDefinedCallMethod(pmpwi);
            if (call.HasError())
            {
                rval.SetError();
            }
            Debug.Assert(rval != null);
            return(rval);
        }
예제 #41
0
        private EXPR BindWinRTEventAccessor(EventWithType ewt, EXPR callingObject, ArgumentObject[] arguments, Dictionary<int, LocalVariableSymbol> dictionary, bool isAddAccessor)
        {
            // We want to generate either:
            // WindowsRuntimeMarshal.AddEventHandler<delegType>(new Func<delegType, EventRegistrationToken>(x.add_foo), new Action<EventRegistrationToken>(x.remove_foo), value)
            // or
            // WindowsRuntimeMarshal.RemoveEventHandler<delegType>(new Action<EventRegistrationToken>(x.remove_foo), value)

            Type evtType = ewt.Event().type.AssociatedSystemType;

            // Get new Action<EventRegistrationToken>(x.remove_foo)
            MethPropWithInst removemwi = new MethPropWithInst(ewt.Event().methRemove, ewt.Ats);
            EXPRMEMGRP removeMethGrp = _exprFactory.CreateMemGroup(callingObject, removemwi);
            removeMethGrp.flags &= ~EXPRFLAG.EXF_USERCALLABLE;
            Type eventRegistrationTokenType = SymbolTable.EventRegistrationTokenType;
            Type actionType = Expression.GetActionType(eventRegistrationTokenType);
            EXPR removeMethArg = _binder.mustConvert(removeMethGrp, _symbolTable.GetCTypeFromType(actionType));

            // The value
            EXPR delegateVal = CreateArgumentEXPR(arguments[1], dictionary[1]);
            EXPRLIST args;
            string methodName;

            if (isAddAccessor)
            {
                // Get new Func<delegType, EventRegistrationToken>(x.add_foo)
                MethPropWithInst addmwi = new MethPropWithInst(ewt.Event().methAdd, ewt.Ats);
                EXPRMEMGRP addMethGrp = _exprFactory.CreateMemGroup(callingObject, addmwi);
                addMethGrp.flags &= ~EXPRFLAG.EXF_USERCALLABLE;
                Type funcType = Expression.GetFuncType(evtType, eventRegistrationTokenType);
                EXPR addMethArg = _binder.mustConvert(addMethGrp, _symbolTable.GetCTypeFromType(funcType));

                args = _exprFactory.CreateList(addMethArg, removeMethArg, delegateVal);
                methodName = SymbolLoader.GetNameManager().GetPredefName(PredefinedName.PN_ADDEVENTHANDLER).Text;
            }
            else
            {
                args = _exprFactory.CreateList(removeMethArg, delegateVal);
                methodName = SymbolLoader.GetNameManager().GetPredefName(PredefinedName.PN_REMOVEEVENTHANDLER).Text;
            }

            // WindowsRuntimeMarshal.Add\RemoveEventHandler(...)
            Type windowsRuntimeMarshalType = SymbolTable.WindowsRuntimeMarshalType;
            _symbolTable.PopulateSymbolTableWithName(methodName, new List<Type> { evtType }, windowsRuntimeMarshalType);
            EXPRCLASS marshalClass = _exprFactory.CreateClass(_symbolTable.GetCTypeFromType(windowsRuntimeMarshalType), null, null);
            EXPRMEMGRP addEventGrp = CreateMemberGroupEXPR(methodName, new List<Type> { evtType }, marshalClass, SYMKIND.SK_MethodSymbol);
            EXPR expr = _binder.BindMethodGroupToArguments(
                BindingFlag.BIND_RVALUEREQUIRED | BindingFlag.BIND_STMTEXPRONLY,
                addEventGrp,
                args);

            return expr;
        }
예제 #42
0
 public static ExprBinOp CreateUserDefinedBinop(ExpressionKind exprKind, CType type, Expr left, Expr right, Expr call, MethPropWithInst userMethod) =>
 new ExprBinOp(exprKind, type, left, right, call, userMethod);
예제 #43
0
            public GroupToArgsBinder(ExpressionBinder exprBinder, BindingFlag bindFlags, EXPRMEMGRP grp, ArgInfos args, ArgInfos originalArgs, bool bHasNamedArguments, AggregateType atsDelegate)
            {
                Debug.Assert(grp != null);
                Debug.Assert(exprBinder != null);
                Debug.Assert(args != null);

                _pExprBinder = exprBinder;
                _fCandidatesUnsupported = false;
                _fBindFlags = bindFlags;
                _pGroup = grp;
                _pArguments = args;
                _pOriginalArguments = originalArgs;
                _bHasNamedArguments = bHasNamedArguments;
                _pDelegate = atsDelegate;
                _pCurrentType = null;
                _pCurrentSym = null;
                _pCurrentTypeArgs = null;
                _pCurrentParameters = null;
                _pBestParameters = null;
                _nArgBest = -1;
                _nWrongCount = 0;
                _bIterateToEndOfNsList = false;
                _bBindingCollectionAddArgs = false;
                _results = new GroupToArgsBinderResult();
                _methList = new List<CandidateFunctionMember>();
                _mpwiParamTypeConstraints = new MethPropWithInst();
                _mpwiBogus = new MethPropWithInst();
                _mpwiCantInferInstArg = new MethPropWithInst();
                _mwtBadArity = new MethWithType();
                _HiddenTypes = new List<CType>();
            }
예제 #44
0
        public EXPRMEMGRP CreateMemGroup(
                EXPR pObject,
                MethPropWithInst mwi)
        {
            Name pName = mwi.Sym != null ? mwi.Sym.name : null;
            MethodOrPropertySymbol methProp = mwi.MethProp();

            CType pType = mwi.GetType();
            if (pType == null)
            {
                pType = GetTypes().GetErrorSym();
            }

            return CreateMemGroup(0, pName, mwi.TypeArgs, methProp != null ? methProp.getKind() : SYMKIND.SK_MethodSymbol, mwi.GetType(), methProp, pObject, new CMemberLookupResults(GetGlobalSymbols().AllocParams(1, new CType[] { pType }), pName));
        }
예제 #45
0
        ////////////////////////////////////////////////////////////////////////////////
        // Determine which method is better for the purposes of overload resolution.
        // Better means: as least as good in all params, and better in at least one param.
        // Better w/r to a param means is an ordering, from best down:
        // 1) same type as argument
        // 2) implicit conversion from argument to formal type
        // Because of user defined conversion opers this relation is not transitive.
        //
        // If there is a tie because of identical signatures, the tie may be broken by the
        // following rules:
        // 1) If one is generic and the other isn't, the non-generic wins.
        // 2) Otherwise if one is expanded (params) and the other isn't, the non-expanded wins.
        // 3) Otherwise if one has more specific parameter types (at the declaration) it wins:
        //    This occurs if at least on parameter type is more specific and no parameter type is
        //    less specific.
        //* A type parameter is less specific than a non-type parameter.
        //* A constructed type is more specific than another constructed type if at least
        //      one type argument is more specific and no type argument is less specific than
        //      the corresponding type args in the other.
        // 4) Otherwise if one has more modopts than the other does, the smaller number of modopts wins.
        //
        // Returns Left if m1 is better, Right if m2 is better, or Neither/Same

        private BetterType WhichMethodIsBetter(
            CandidateFunctionMember node1,
            CandidateFunctionMember node2,
            CType pTypeThrough,
            ArgInfos args)
        {
            MethPropWithInst mpwi1 = node1.mpwi;
            MethPropWithInst mpwi2 = node2.mpwi;

            // Substitutions should have already been done on these!
            TypeArray pta1 = RearrangeNamedArguments(node1.@params, mpwi1, pTypeThrough, args);
            TypeArray pta2 = RearrangeNamedArguments(node2.@params, mpwi2, pTypeThrough, args);

            // If the parameter types for both candidate methods are identical,
            // use the tie breaking rules.

            if (pta1 == pta2)
            {
                return(WhichMethodIsBetterTieBreaker(node1, node2, pTypeThrough, args));
            }

            //  Otherwise, do a parameter-by-parameter comparison:
            //
            // Given an argument list A with a set of argument expressions {E1, ... En} and
            // two applicable function members Mp and Mq with parameter types {P1,... Pn} and
            // {Q1, ... Qn}, Mp is defined to be a better function member than Mq if:
            //* for each argument the implicit conversion from Ex to Qx is not better than
            //   the implicit conversion from Ex to Px.
            //* for at least one argument, the conversion from Ex to Px is better than the
            //   conversion from Ex to Qx.

            BetterType betterMethod = BetterType.Neither;
            int        carg         = args.carg;

            for (int i = 0; i < carg; i++)
            {
                Expr  arg = args.fHasExprs ? args.prgexpr[i] : null;
                CType p1  = pta1[i];
                CType p2  = pta2[i];

                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // RUNTIME BINDER ONLY CHANGE
                // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //
                // We need to consider conversions from the actual runtime type
                // since we could have private interfaces that we are converting

                CType argType = arg?.RuntimeObjectActualType ?? args.types[i];

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

                BetterType betterConversion = WhichConversionIsBetter(argType, p1, p2);

                if (betterMethod == BetterType.Right)
                {
                    if (betterConversion == BetterType.Left)
                    {
                        betterMethod = BetterType.Neither;
                        break;
                    }
                }
                else if (betterMethod == BetterType.Left)
                {
                    if (betterConversion == BetterType.Right)
                    {
                        betterMethod = BetterType.Neither;
                        break;
                    }
                }
                else
                {
                    Debug.Assert(betterMethod == BetterType.Neither);
                    if (betterConversion == BetterType.Right || betterConversion == BetterType.Left)
                    {
                        betterMethod = betterConversion;
                    }
                }
            }

            // We may have different sizes if we had optional parameters. If thats the case,
            // the one with fewer parameters wins (ie less optional parameters) unless it is
            // expanded. If so, the one with more parameters wins (ie option beats expanded).
            if (pta1.Count != pta2.Count && betterMethod == BetterType.Neither)
            {
                if (node1.fExpanded)
                {
                    if (!node2.fExpanded)
                    {
                        return(BetterType.Right);
                    }
                }
                else if (node2.fExpanded)
                {
                    return(BetterType.Left);
                }

                // Here, if both methods needed to use optionals to fill in the signatures,
                // then we are ambiguous. Otherwise, take the one that didn't need any
                // optionals.

                if (pta1.Count == carg)
                {
                    return(BetterType.Left);
                }

                if (pta2.Count == carg)
                {
                    return(BetterType.Right);
                }

                return(BetterType.Neither);
            }

            return(betterMethod);
        }
예제 #46
0
 private EXPRCALL BindUDUnopCall(EXPR arg, CType typeArg, MethPropWithInst mpwi)
 {
     CType typeRet = GetTypes().SubstType(mpwi.Meth().RetType, mpwi.GetType());
     checkUnsafe(typeRet); // added to the binder so we don't bind to pointer ops
     EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mpwi);
     EXPRCALL call = GetExprFactory().CreateCall(0, typeRet, mustConvert(arg, typeArg), pMemGroup, null);
     call.mwi = new MethWithInst(mpwi);
     verifyMethodArgs(call, mpwi.GetType());
     return call;
 }
예제 #47
0
 public ExprBinOp(ExpressionKind kind, CType type, Expr left, Expr right, Expr call, MethPropWithInst userMethod)
     : base(kind, type, call, userMethod)
 {
     Debug.Assert(kind > ExpressionKind.TypeLimit);
     Debug.Assert(left != null);
     Debug.Assert(right != null);
     Debug.Assert(call != null);
     Flags              = EXPRFLAG.EXF_BINOP;
     OptionalLeftChild  = left;
     OptionalRightChild = right;
 }
예제 #48
0
 public MethWithInst(MethPropWithInst mpwi)
 {
     Set(mpwi.Sym.AsMethodSymbol(), mpwi.Ats, mpwi.TypeArgs);
 }
예제 #49
0
        ////////////////////////////////////////////////////////////////////////////////
        // This finds a method  and binds it to the args provided.

        internal EXPRCALL BindPredefMethToArgs(PREDEFMETH predefMethod, EXPR obj, EXPR args, TypeArray clsTypeArgs, TypeArray methTypeArgs)
        {
            MethodSymbol methSym = GetSymbolLoader().getPredefinedMembers().GetMethod(predefMethod);
            if (methSym == null)
            {
                MethWithInst mwi = new MethWithInst(null, null);
                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(obj, mwi);
                EXPRCALL rval = GetExprFactory().CreateCall(0, null, args, pMemGroup, null);
                rval.SetError();
                return rval;
            }

            AggregateSymbol agg = methSym.getClass();
            if (clsTypeArgs == null)
            {
                clsTypeArgs = BSYMMGR.EmptyTypeArray();
            }
            AggregateType aggType = GetTypes().GetAggregate(agg, clsTypeArgs);

            MethPropWithInst mpwiBest = new MethPropWithInst(methSym, aggType, methTypeArgs);
            EXPRMEMGRP memgroup = GetExprFactory().CreateMemGroup(obj, mpwiBest);

            EXPRCALL exprRes = BindToMethod(new MethWithInst(mpwiBest), args, memgroup, (MemLookFlags)MemLookFlags.None);

            return exprRes;
        }