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>();
            }
Exemple #2
0
        /////////////////////////////////////////////////////////////////////////////////

        private EXPR CreateProperty(
            SymWithType swt,
            EXPR callingObject,
            BindingFlag flags)
        {
            // For a property, we simply create the EXPRPROP for the thing, call the
            // expression tree rewriter, rewrite it, and send it on its way.

            PropertySymbol property = swt.Prop();
            AggregateType propertyType = swt.GetType();
            PropWithType pwt = new PropWithType(property, propertyType);
            EXPRMEMGRP pMemGroup = CreateMemberGroupEXPR(property.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol);

            return _binder.BindToProperty(// For a static property instance, don't set the object.
                    callingObject.isCLASS() ? null : callingObject, pwt, flags, null, null, pMemGroup);
        }
Exemple #3
0
        /////////////////////////////////////////////////////////////////////////////////

        private EXPR CreateIndexer(SymWithType swt, EXPR callingObject, EXPR arguments, BindingFlag bindFlags)
        {
            IndexerSymbol index = swt.Sym as IndexerSymbol;
            AggregateType ctype = swt.GetType();
            EXPRMEMGRP memgroup = CreateMemberGroupEXPR(index.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol);

            EXPR result = _binder.BindMethodGroupToArguments(bindFlags, memgroup, arguments);
            return ReorderArgumentsForNamedAndOptional(callingObject, result);
        }
Exemple #4
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;
        }
Exemple #5
0
        ////////////////////////////////////////////////////////////////////////////////

        internal EXPR BindToProperty(EXPR pObject, PropWithType pwt, BindingFlag bindFlags, EXPR args, AggregateType pOtherType, EXPRMEMGRP pMemGroup)
        {
            Debug.Assert(pwt.Sym != null &&
                    pwt.Sym.IsPropertySymbol() &&
                    pwt.GetType() != null &&
                    pwt.Prop().getClass() == pwt.GetType().getAggregate());
            Debug.Assert(pwt.Prop().Params.size == 0 || pwt.Prop().isIndexer());
            Debug.Assert(pOtherType == null ||
                    !pwt.Prop().isIndexer() &&
                    pOtherType.getAggregate() == pwt.Prop().RetType.getAggregate());

            bool fConstrained;
            MethWithType mwtGet;
            MethWithType mwtSet;
            EXPR pObjectThrough = null;

            // We keep track of the type of the pObject which we're doing the call through so that we can report 
            // protection access errors later, either below when binding the get, or later when checking that
            // the setter is actually an lvalue.  If we're actually doing a base.prop call then we do not
            // need to ensure that the left side of the dot is an instance of the derived class, otherwise
            // we save it away for later.
            if (0 == (bindFlags & BindingFlag.BIND_BASECALL))
            {
                pObjectThrough = pObject;
            }

            bool bIsMatchingStatic;
            PostBindProperty((bindFlags & BindingFlag.BIND_BASECALL) != 0, pwt, pObject, out mwtGet, out mwtSet);

            if (mwtGet &&
                    (!mwtSet ||
                     mwtSet.GetType() == mwtGet.GetType() ||
                     GetSymbolLoader().HasBaseConversion(mwtGet.GetType(), mwtSet.GetType())
                     )
                )
            {
                pObject = AdjustMemberObject(mwtGet, pObject, out fConstrained, out bIsMatchingStatic);
            }
            else if (mwtSet)
            {
                pObject = AdjustMemberObject(mwtSet, pObject, out fConstrained, out bIsMatchingStatic);
            }
            else
            {
                pObject = AdjustMemberObject(pwt, pObject, out fConstrained, out bIsMatchingStatic);
            }
            pMemGroup.SetOptionalObject(pObject);

            CType pReturnType = GetTypes().SubstType(pwt.Prop().RetType, pwt.GetType());
            Debug.Assert(pOtherType == pReturnType || pOtherType == null);

            if (pObject != null && !pObject.isOK())
            {
                EXPRPROP pResult = GetExprFactory().CreateProperty(pReturnType, pObjectThrough, args, pMemGroup, pwt, null, null);
                if (!bIsMatchingStatic)
                {
                    pResult.SetMismatchedStaticBit();
                }
                pResult.SetError();
                return pResult;
            }

            // if we are doing a get on this thing, and there is no get, and
            // most importantly, we are not leaving the arguments to be bound by the array index
            // then error...
            if ((bindFlags & BindingFlag.BIND_RVALUEREQUIRED) != 0)
            {
                if (!mwtGet)
                {
                    if (pOtherType != null)
                    {
                        return GetExprFactory().MakeClass(pOtherType);
                    }
                    ErrorContext.ErrorRef(ErrorCode.ERR_PropertyLacksGet, pwt);
                }
                else if (((bindFlags & BindingFlag.BIND_BASECALL) != 0) && mwtGet.Meth().isAbstract)
                {
                    // if the get exists, but is abstract, forbid the call as well...
                    if (pOtherType != null)
                    {
                        return GetExprFactory().MakeClass(pOtherType);
                    }
                    ErrorContext.Error(ErrorCode.ERR_AbstractBaseCall, pwt);
                }
                else
                {
                    CType type = null;
                    if (pObjectThrough != null)
                    {
                        type = pObjectThrough.type;
                    }

                    ACCESSERROR error = SemanticChecker.CheckAccess2(mwtGet.Meth(), mwtGet.GetType(), ContextForMemberLookup(), type);
                    if (error != ACCESSERROR.ACCESSERROR_NOERROR)
                    {
                        // if the get exists, but is not accessible, give an error.
                        if (pOtherType != null)
                        {
                            return GetExprFactory().MakeClass(pOtherType);
                        }

                        if (error == ACCESSERROR.ACCESSERROR_NOACCESSTHRU)
                        {
                            ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, pwt, type, ContextForMemberLookup());
                        }
                        else
                        {
                            ErrorContext.ErrorRef(ErrorCode.ERR_InaccessibleGetter, pwt);
                        }
                    }
                }
            }

            EXPRPROP result = GetExprFactory().CreateProperty(pReturnType, pObjectThrough, args, pMemGroup, pwt, mwtGet, mwtSet);
            if (!bIsMatchingStatic)
            {
                result.SetMismatchedStaticBit();
            }

            Debug.Assert(EXPRFLAG.EXF_BASECALL == (EXPRFLAG)BindingFlag.BIND_BASECALL);
            if ((EXPRFLAG.EXF_BASECALL & (EXPRFLAG)bindFlags) != 0)
            {
                result.flags |= EXPRFLAG.EXF_BASECALL;
            }
            else if (fConstrained && pObject != null)
            {
                // Use the constrained prefix.
                result.flags |= EXPRFLAG.EXF_CONSTRAINED;
            }

            if (result.GetOptionalArguments() != null)
            {
                verifyMethodArgs(result, pObjectThrough != null ? pObjectThrough.type : null);
            }

            if (mwtSet && objectIsLvalue(result.GetMemberGroup().GetOptionalObject()))
            {
                result.flags |= EXPRFLAG.EXF_LVALUE;
            }
            if (pOtherType != null)
            {
                result.flags |= EXPRFLAG.EXF_SAMENAMETYPE;
            }

            return result;
        }
Exemple #6
0
        ////////////////////////////////////////////////////////////////////////////////
        // Construct the EXPR node which corresponds to a field expression
        // for a given field and pObject pointer.

        internal EXPR BindToField(EXPR pObject, FieldWithType fwt, BindingFlag bindFlags)
        {
            return BindToField(pObject, fwt, bindFlags, null/*OptionalLHS*/);
        }
Exemple #7
0
        protected EXPR bindIndexer(EXPR pObject, EXPR args, BindingFlag bindFlags)
        {
            CType type = pObject.type;

            if (!type.IsAggregateType() && !type.IsTypeParameterType())
            {
                ErrorContext.Error(ErrorCode.ERR_BadIndexLHS, type);
                MethWithInst mwi = new MethWithInst(null, null);
                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(pObject, mwi);
                EXPRCALL rval = GetExprFactory().CreateCall(0, type, args, pMemGroup, null);
                rval.SetError();
                return rval;
            }

            Name pName = GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_INDEXERINTERNAL);

            MemberLookup mem = new MemberLookup();
            if (!mem.Lookup(GetSemanticChecker(), type, pObject, ContextForMemberLookup(), pName, 0,
                            (bindFlags & BindingFlag.BIND_BASECALL) != 0 ? (MemLookFlags.BaseCall | MemLookFlags.Indexer) : MemLookFlags.Indexer))
            {
                mem.ReportErrors();
                type = GetTypes().GetErrorSym();
                Symbol pSymbol = null;

                if (mem.SwtInaccessible().Sym != null)
                {
                    Debug.Assert(mem.SwtInaccessible().Sym.IsMethodOrPropertySymbol());
                    type = mem.SwtInaccessible().MethProp().RetType;
                    pSymbol = mem.SwtInaccessible().Sym;
                }

                EXPRMEMGRP memgrp = null;

                if (pSymbol != null)
                {
                    memgrp = GetExprFactory().CreateMemGroup((EXPRFLAG)mem.GetFlags(),
                        pName, BSYMMGR.EmptyTypeArray(), pSymbol.getKind(), mem.GetSourceType(), null/*pMPS*/, mem.GetObject(), mem.GetResults());
                    memgrp.SetInaccessibleBit();
                }
                else
                {
                    MethWithInst mwi = new MethWithInst(null, null);
                    memgrp = GetExprFactory().CreateMemGroup(mem.GetObject(), mwi);
                }

                EXPRCALL rval = GetExprFactory().CreateCall(0, type, args, memgrp, null);
                rval.SetError();
                return rval;
            }

            Debug.Assert(mem.SymFirst().IsPropertySymbol() && mem.SymFirst().AsPropertySymbol().isIndexer());

            EXPRMEMGRP grp = GetExprFactory().CreateMemGroup((EXPRFLAG)mem.GetFlags(),
                pName, BSYMMGR.EmptyTypeArray(), mem.SymFirst().getKind(), mem.GetSourceType(), null/*pMPS*/, mem.GetObject(), mem.GetResults());

            EXPR pResult = BindMethodGroupToArguments(bindFlags, grp, args);
            Debug.Assert(pResult.HasObject());
            if (pResult.getObject() == null)
            {
                // We must be in an error scenario where the object was not allowed. 
                // This can happen if the user tries to access the indexer off the
                // type and not an instance or if the incorrect type/number of arguments 
                // were passed for binding.
                pResult.SetObject(pObject);
                pResult.SetError();
            }
            return pResult;
        }
Exemple #8
0
        internal EXPR BindArrayIndexCore(BindingFlag bindFlags, EXPR pOp1, EXPR pOp2)
        {
            EXPR pExpr;
            bool bIsError = false;
            if (!pOp1.isOK() || !pOp2.isOK())
            {
                bIsError = true;
            }

            CType pIntType = GetReqPDT(PredefinedType.PT_INT);

            // Array indexing must occur on an array type.
            if (!pOp1.type.IsArrayType())
            {
                Debug.Assert(!pOp1.type.IsPointerType());
                pExpr = bindIndexer(pOp1, pOp2, bindFlags);
                if (bIsError)
                {
                    pExpr.SetError();
                }
                return pExpr;
            }
            ArrayType pArrayType = pOp1.type.AsArrayType();
            checkUnsafe(pArrayType.GetElementType()); // added to the binder so we don't bind to pointer ops
            // Check the rank of the array against the number of indices provided, and
            // convert the indexes to ints

            CType pDestType = chooseArrayIndexType(pOp2);

            if (null == pDestType)
            {
                // using int as the type will allow us to give a better error...
                pDestType = pIntType;
            }

            int rank = pArrayType.rank;
            int cIndices = 0;

            EXPR transformedIndices = pOp2.Map(GetExprFactory(),
                (EXPR x) =>
                {
                    cIndices++;
                    EXPR pTemp = mustConvert(x, pDestType);
                    if (pDestType == pIntType)
                        return pTemp;
#if CSEE
                    EXPRFLAG flag = 0;
#else
                    EXPRFLAG flag = EXPRFLAG.EXF_INDEXEXPR;
#endif
                    EXPRCLASS exprType = GetExprFactory().MakeClass(pDestType);
                    return GetExprFactory().CreateCast(flag, exprType, pTemp);
                });

            if (cIndices != rank)
            {
                ErrorContext.Error(ErrorCode.ERR_BadIndexCount, rank);
                pExpr = GetExprFactory().CreateArrayIndex(pOp1, transformedIndices);
                pExpr.SetError();
                return pExpr;
            }

            // Allocate a new expression, the type is the element type of the array.
            // Array index operations are always lvalues.
            pExpr = GetExprFactory().CreateArrayIndex(pOp1, transformedIndices);
            pExpr.flags |= EXPRFLAG.EXF_LVALUE | EXPRFLAG.EXF_ASSGOP;

            if (bIsError)
            {
                pExpr.SetError();
            }

            return pExpr;
        }
Exemple #9
0
        ////////////////////////////////////////////////////////////////////////////////
        // Given a method group or indexer group, bind it to the arguments for an 
        // invocation.
        internal EXPR BindMethodGroupToArguments(BindingFlag bindFlags, EXPRMEMGRP grp, EXPR args)
        {
            Debug.Assert(grp.sk == SYMKIND.SK_MethodSymbol || grp.sk == SYMKIND.SK_PropertySymbol && ((grp.flags & EXPRFLAG.EXF_INDEXER) != 0));

            // Count the args.
            bool argTypeErrors;
            int carg = CountArguments(args, out argTypeErrors);
            // We need to store the object because BindMethodGroupToArgumentsCore will 
            // null it out in the case of an extension method, which is then consumed
            // by BindToMethod. After that, we want to set the object back.
            EXPR pObject = grp.GetOptionalObject();

            // If we weren't given a pName, then we couldn't bind the method pName, so we should
            // just bail out of here.

            if (grp.name == null)
            {
                EXPRCALL rval = GetExprFactory().CreateCall(0, GetTypes().GetErrorSym(), args, grp, null);
                rval.SetError();
                return rval;
            }

            // If we have named arguments specified, make sure we have them all appearing after 
            // fixed arguments.
            bool bSeenNamed = false;
            if (!VerifyNamedArgumentsAfterFixed(args, out bSeenNamed))
            {
                EXPRCALL rval = GetExprFactory().CreateCall(0, GetTypes().GetErrorSym(), args, grp, null);
                rval.SetError();
                return rval;
            }

            GroupToArgsBinderResult result;
            if (!BindMethodGroupToArgumentsCore(out result, bindFlags, grp, ref args, carg, false, bSeenNamed))
            {
                Debug.Assert(false, "Why didn't BindMethodGroupToArgumentsCore throw an error?");
                return null;
            }

            EXPR exprRes;
            MethPropWithInst mpwiBest = result.GetBestResult();

            if (grp.sk == SYMKIND.SK_PropertySymbol)
            {
                Debug.Assert((grp.flags & EXPRFLAG.EXF_INDEXER) != 0);
                //PropWithType pwt = new PropWithType(mpwiBest.Prop(), mpwiBest.GetType());

                exprRes = BindToProperty(grp.GetOptionalObject(), new PropWithType(mpwiBest), (bindFlags | (BindingFlag)(grp.flags & EXPRFLAG.EXF_BASECALL)), args, null/*typeOther*/, grp);
            }
            else
            {
                exprRes = BindToMethod(new MethWithInst(mpwiBest), args, grp, (MemLookFlags)grp.flags);
            }
            return exprRes;
        }
Exemple #10
0
        ////////////////////////////////////////////////////////////////////////////////
        // Given a method group or indexer group, bind it to the arguments for an 
        // invocation. This method can change the arguments to bind with Extension 
        // Methods
        private bool BindMethodGroupToArgumentsCore(out GroupToArgsBinderResult pResults, BindingFlag bindFlags, EXPRMEMGRP grp, ref EXPR args, int carg, bool bindingCollectionAdd, bool bHasNamedArgumentSpecifiers)
        {
            ArgInfos pargInfo = new ArgInfos {carg = carg};
            FillInArgInfoFromArgList(pargInfo, args);

            ArgInfos pOriginalArgInfo = new ArgInfos {carg = carg};
            FillInArgInfoFromArgList(pOriginalArgInfo, args);

            GroupToArgsBinder binder = new GroupToArgsBinder(this, bindFlags, grp, pargInfo, pOriginalArgInfo, bHasNamedArgumentSpecifiers, null/*atsDelegate*/);
            bool retval = bindingCollectionAdd ? binder.BindCollectionAddArgs() : binder.Bind(true /*ReportErrors*/);

            pResults = binder.GetResultsOfBind();
            return retval;
        }