Пример #1
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>();
            }
Пример #2
0
 /***************************************************************************************************
     Set the values of the UnaOpFullSig from the given UnaOpSig. The ExpressionBinder is needed to get
     the predefined type. Returns true iff the predef type is found.
 ***************************************************************************************************/
 public UnaOpFullSig(ExpressionBinder fnc, UnaOpSig uos)
 {
     this.pt = uos.pt;
     this.grfuom = uos.grfuom;
     this.cuosSkip = uos.cuosSkip;
     this.pfn = uos.pfn;
     this.fnkind = uos.fnkind;
     _type = pt != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetOptPDT(pt) : null;
     _grflt = LiftFlags.None;
 }
Пример #3
0
 public ImplicitConversion(ExpressionBinder binder, EXPR exprSrc, CType typeSrc, EXPRTYPEORNAMESPACE typeDest, bool needsExprDest, CONVERTTYPE flags)
 {
     _binder = binder;
     _exprSrc = exprSrc;
     _typeSrc = typeSrc;
     _typeDest = typeDest.TypeOrNamespace.AsType();
     _exprTypeDest = typeDest;
     _needsExprDest = needsExprDest;
     _flags = flags;
     _exprDest = null;
 }
Пример #4
0
            // ----------------------------------------------------------------------------
            // BindExplicitConversion
            // ----------------------------------------------------------------------------

            public ExplicitConversion(ExpressionBinder binder, EXPR exprSrc, CType typeSrc, EXPRTYPEORNAMESPACE typeDest, CType pDestinationTypeForLambdaErrorReporting, bool needsExprDest, CONVERTTYPE flags)
            {
                _binder = binder;
                _exprSrc = exprSrc;
                _typeSrc = typeSrc;
                _typeDest = typeDest.TypeOrNamespace.AsType();
                _pDestinationTypeForLambdaErrorReporting = pDestinationTypeForLambdaErrorReporting;
                _exprTypeDest = typeDest;
                _needsExprDest = needsExprDest;
                _flags = flags;
                _exprDest = null;
            }
Пример #5
0
            /***************************************************************************************************
                Set the values of the BinOpFullSig from the given BinOpSig. The ExpressionBinder is needed to get
                the predefined types. Returns true iff the predef types are found.
            ***************************************************************************************************/
            public BinOpFullSig(ExpressionBinder fnc, BinOpSig bos)
            {
                this.pt1 = bos.pt1;
                this.pt2 = bos.pt2;
                this.mask = bos.mask;
                this.cbosSkip = bos.cbosSkip;
                this.pfn = bos.pfn;
                this.grfos = bos.grfos;
                this.fnkind = bos.fnkind;

                _type1 = pt1 != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetOptPDT(pt1) : null;
                _type2 = pt2 != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetOptPDT(pt2) : null;
                _grflt = LiftFlags.None;
            }
Пример #6
0
        /*
        SPEC:

        CType inference occurs as part of the compile-time processing of a method invocation
        and takes place before the overload resolution step of the invocation. When a
        particular method group is specified in a method invocation, and no CType arguments
        are specified as part of the method invocation, CType inference is applied to each
        generic method in the method group. If CType inference succeeds, then the inferred
        CType arguments are used to determine the types of formal parameters for subsequent 
        overload resolution. If overload resolution chooses a generic method as the one to
        invoke then the inferred CType arguments are used as the actual CType arguments for the
        invocation. If CType inference for a particular method fails, that method does not
        participate in overload resolution. The failure of CType inference, in and of itself,
        does not cause a compile-time error. However, it often leads to a compile-time error
        when overload resolution then fails to find any applicable methods.

        If the supplied number of arguments is different than the number of parameters in
        the method, then inference immediately fails. Otherwise, assume that the generic
        method has the following signature:

        Tr M<X1...Xn>(T1 x1 ... Tm xm)

        With a method call of the form M(E1...Em) the task of CType inference is to find
        unique CType arguments S1...Sn for each of the CType parameters X1...Xn so that the
        call M<S1...Sn>(E1...Em)becomes valid.

        During the process of inference each CType parameter Xi is either fixed to a particular
        CType Si or unfixed with an associated set of bounds. Each of the bounds is some CType T.
        Each bound is classified as an upper bound, lower bound or exact bound.
        Initially each CType variable Xi is unfixed with an empty set of bounds.


        */

        // This file contains the implementation for method CType inference on calls (with
        // arguments, and method CType inference on conversion of method groups to delegate
        // types (which will not have arguments.)

        ////////////////////////////////////////////////////////////////////////////////

        public static bool Infer(
            ExpressionBinder binder,
            SymbolLoader symbolLoader,
            MethodSymbol pMethod,
            TypeArray pClassTypeArguments,
            TypeArray pMethodFormalParameterTypes,
            ArgInfos pMethodArguments,
            out TypeArray ppInferredTypeArguments)
        {
            Debug.Assert(pMethod != null);
            Debug.Assert(pMethod.typeVars.size > 0);
            Debug.Assert(pMethod.isParamArray || pMethod.Params == pMethodFormalParameterTypes);
            ppInferredTypeArguments = null;
            if (pMethodFormalParameterTypes.size == 0 || pMethod.InferenceMustFail())
            {
                return false;
            }
            Debug.Assert(pMethodArguments != null);
            Debug.Assert(pMethodFormalParameterTypes != null);
            Debug.Assert(pMethodArguments.carg <= pMethodFormalParameterTypes.size);

            var inferrer = new MethodTypeInferrer(binder, symbolLoader,
                pMethodFormalParameterTypes, pMethodArguments,
                pMethod.typeVars, pClassTypeArguments);
            bool success;
            if (pMethodArguments.fHasExprs)
            {
                success = inferrer.InferTypeArgs();
            }
            else
            {
                success = inferrer.InferForMethodGroupConversion();
            }

            ppInferredTypeArguments = inferrer.GetResults();
            return success;
        }
Пример #7
0
        ////////////////////////////////////////////////////////////////////////////////
        //
        // In error recovery and reporting scenarios we sometimes end up in a situation
        // like this:
        //
        // x.Foo( y=>
        //
        // and the question is, "is Foo a valid extension method of x?"  If Foo is
        // generic, then Foo will be something like:
        //
        // static Blah Foo<T>(this Bar<T> bar, Func<T, T> f){ ... }
        //
        // What we would like to know is: given _only_ the expression x, can we infer
        // what T is in Bar<T> ?  If we can, then for error recovery and reporting
        // we can provisionally consider Foo to be an extension method of x. If we 
        // cannot deduce this just from x then we should consider Foo to not be an
        // extension method of x, at least until we have more information.
        //
        // Clearly it is pointless to run multiple phases

        public static bool CanObjectOfExtensionBeInferred(
            ExpressionBinder binder,
            SymbolLoader symbolLoader,
            MethodSymbol pMethod,
            TypeArray pClassTypeArguments,
            TypeArray pMethodFormalParameterTypes,
            ArgInfos pMethodArguments)
        {
            Debug.Assert(pMethod != null);
            Debug.Assert(pMethod.typeVars.size > 0);
            Debug.Assert(pMethodFormalParameterTypes != null);
            Debug.Assert(pMethod.isParamArray || pMethod.Params == pMethodFormalParameterTypes);
            // We need at least one formal parameter type and at least one argument.
            if (pMethodFormalParameterTypes.size < 1 || pMethod.InferenceMustFail())
            {
                return false;
            }
            Debug.Assert(pMethodArguments != null);
            Debug.Assert(pMethodArguments.carg <= pMethodFormalParameterTypes.size);
            if (pMethodArguments.carg < 1)
            {
                return false;
            }
            var inferrer = new MethodTypeInferrer(binder, symbolLoader,
            pMethodFormalParameterTypes, pMethodArguments, pMethod.typeVars, pClassTypeArguments);
            return inferrer.CanInferExtensionObject();
        }
Пример #8
0
        ////////////////////////////////////////////////////////////////////////////////
        //
        // Fixed, unfixed and bounded CType parameters
        //
        // SPEC: During the process of inference each CType parameter is either fixed to
        // SPEC: a particular CType or unfixed with an associated set of bounds. Each of
        // SPEC: the bounds is of some CType T. Initially each CType parameter is unfixed
        // SPEC: with an empty set of bounds.

        private MethodTypeInferrer(
            ExpressionBinder exprBinder, SymbolLoader symLoader,
            TypeArray pMethodFormalParameterTypes, ArgInfos pMethodArguments,
            TypeArray pMethodTypeParameters, TypeArray pClassTypeArguments)
        {
            _binder = exprBinder;
            _symbolLoader = symLoader;
            _pMethodFormalParameterTypes = pMethodFormalParameterTypes;
            _pMethodArguments = pMethodArguments;
            _pMethodTypeParameters = pMethodTypeParameters;
            _pClassTypeArguments = pClassTypeArguments;
            _pFixedResults = new CType[pMethodTypeParameters.size];
            _pLowerBounds = new List<CType>[pMethodTypeParameters.size];
            _pUpperBounds = new List<CType>[pMethodTypeParameters.size];
            _pExactBounds = new List<CType>[pMethodTypeParameters.size];
            for (int iBound = 0; iBound < pMethodTypeParameters.size; ++iBound)
            {
                _pLowerBounds[iBound] = new List<CType>();
                _pUpperBounds[iBound] = new List<CType>();
                _pExactBounds[iBound] = new List<CType>();
            }
            _ppDependencies = null;
        }
Пример #9
0
        private void Reset()
        {
            _controller = new RuntimeBinderController();
            _semanticChecker = new LangCompiler(_controller, new NameManager());

            BSYMMGR bsymmgr = _semanticChecker.getBSymmgr();
            NameManager nameManager = _semanticChecker.GetNameManager();

            InputFile infile = bsymmgr.GetMiscSymFactory().CreateMDInfile(nameManager.Lookup(""), (mdToken)0);
            infile.SetAssemblyID(bsymmgr.AidAlloc(infile));
            infile.AddToAlias(KAID.kaidThisAssembly);
            infile.AddToAlias(KAID.kaidGlobal);

            _symbolTable = new SymbolTable(
                bsymmgr.GetSymbolTable(),
                bsymmgr.GetSymFactory(),
                nameManager,
                _semanticChecker.GetTypeManager(),
                bsymmgr,
                _semanticChecker,
                infile);
            _semanticChecker.getPredefTypes().Init(_semanticChecker.GetErrorContext(), _symbolTable);
            _semanticChecker.GetTypeManager().InitTypeFactory(_symbolTable);
            SymbolLoader.getPredefinedMembers().RuntimeBinderSymbolTable = _symbolTable;
            SymbolLoader.SetSymbolTable(_symbolTable);

            _exprFactory = new ExprFactory(_semanticChecker.GetSymbolLoader().GetGlobalSymbolContext());
            _outputContext = new OutputContext();
            _nameGenerator = new NameGenerator();
            _bindingContext = BindingContext.CreateInstance(
                _semanticChecker,
                _exprFactory,
                _outputContext,
                _nameGenerator,
                false,
                true,
                false,
                false,
                false,
                false,
                0);
            _binder = new ExpressionBinder(_bindingContext);
        }
Пример #10
0
        /******************************************************************************
        *   Reports errors. Only call this if FError() is true.
        ******************************************************************************/
        public void ReportErrors()
        {
            Debug.Assert(FError());

            // Report error.
            // NOTE: If the definition of FError changes, this code will need to change.
            Debug.Assert(!m_swtFirst || m_swtAmbig);

            if (m_swtFirst)
            {
                // Ambiguous lookup.
                GetErrorContext().ErrorRef(ErrorCode.ERR_AmbigMember, m_swtFirst, m_swtAmbig);
            }
            else if (m_swtInaccess)
            {
                if (!m_swtInaccess.Sym.isUserCallable() && ((m_flags & MemLookFlags.UserCallable) != 0))
                {
                    GetErrorContext().Error(ErrorCode.ERR_CantCallSpecialMethod, m_swtInaccess);
                }
                else
                {
                    GetSemanticChecker().ReportAccessError(m_swtInaccess, m_symWhere, m_typeQual);
                }
            }
            else if ((m_flags & MemLookFlags.Ctor) != 0)
            {
                if (m_arity > 0)
                {
                    GetErrorContext().Error(ErrorCode.ERR_BadCtorArgCount, m_typeSrc.getAggregate(), m_arity);
                }
                else
                {
                    GetErrorContext().Error(ErrorCode.ERR_NoConstructors, m_typeSrc.getAggregate());
                }
            }
            else if ((m_flags & MemLookFlags.Operator) != 0)
            {
                // REVIEW : Will we ever get here? Normally UD op errors are reported elsewhere....
                // This is a bogus message in any event.
                GetErrorContext().Error(ErrorCode.ERR_NoSuchMember, m_typeSrc, m_name);
            }
            else if ((m_flags & MemLookFlags.Indexer) != 0)
            {
                GetErrorContext().Error(ErrorCode.ERR_BadIndexLHS, m_typeSrc);
            }
            else if (m_swtBad)
            {
                GetErrorContext().Error((m_flags & MemLookFlags.MustBeInvocable) != 0 ? ErrorCode.ERR_NonInvocableMemberCalled : ErrorCode.ERR_CantCallSpecialMethod, m_swtBad);
            }
            else if (m_swtBogus)
            {
                ReportBogus(m_swtBogus);
            }
            else if (m_swtBadArity)
            {
                int cvar;

                switch (m_swtBadArity.Sym.getKind())
                {
                case SYMKIND.SK_MethodSymbol:
                    Debug.Assert(m_arity != 0);
                    cvar = m_swtBadArity.Sym.AsMethodSymbol().typeVars.size;
                    GetErrorContext().ErrorRef(cvar > 0 ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, m_swtBadArity, new ErrArgSymKind(m_swtBadArity.Sym), cvar);
                    break;

                case SYMKIND.SK_AggregateSymbol:
                    cvar = m_swtBadArity.Sym.AsAggregateSymbol().GetTypeVars().size;
                    GetErrorContext().ErrorRef(cvar > 0 ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, m_swtBadArity, new ErrArgSymKind(m_swtBadArity.Sym), cvar);
                    break;

                default:
                    Debug.Assert(m_arity != 0);
                    ExpressionBinder.ReportTypeArgsNotAllowedError(GetSymbolLoader(), m_arity, m_swtBadArity, new ErrArgSymKind(m_swtBadArity.Sym));
                    break;
                }
            }
            else
            {
                if ((m_flags & MemLookFlags.ExtensionCall) != 0)
                {
                    GetErrorContext().Error(ErrorCode.ERR_NoSuchMemberOrExtension, m_typeSrc, m_name);
                }
                else
                {
                    GetErrorContext().Error(ErrorCode.ERR_NoSuchMember, m_typeSrc, m_name);
                }
            }
        }
Пример #11
0
            public bool CanUseCurrentSymbol()
            {
                _bCurrentSymIsInaccessible = false;
                _bCurrentSymIsBogus        = false;

                // Make sure that whether we're seeing a ctor is consistent with the flag.
                // The only properties we handle are indexers.
                if (_mask == symbmask_t.MASK_MethodSymbol && (
                        0 == (_flags & EXPRFLAG.EXF_CTOR) != !_pCurrentSym.AsMethodSymbol().IsConstructor() ||
                        0 == (_flags & EXPRFLAG.EXF_OPERATOR) != !_pCurrentSym.AsMethodSymbol().isOperator) ||
                    _mask == symbmask_t.MASK_PropertySymbol && !_pCurrentSym.AsPropertySymbol().isIndexer())
                {
                    // Get the next symbol.
                    return(false);
                }

                // If our arity is non-0, we must match arity with this symbol.
                if (_nArity > 0)
                {
                    if (_mask == symbmask_t.MASK_MethodSymbol && _pCurrentSym.AsMethodSymbol().typeVars.Count != _nArity)
                    {
                        return(false);
                    }
                }

                // If this guy's not callable, no good.
                if (!ExpressionBinder.IsMethPropCallable(_pCurrentSym, (_flags & EXPRFLAG.EXF_USERCALLABLE) != 0))
                {
                    return(false);
                }

                // Check access.
                if (!GetSemanticChecker().CheckAccess(_pCurrentSym, _pCurrentType, _pContext, _pQualifyingType))
                {
                    // Sym is not accessible. However, if we're allowing inaccessible, then let it through and mark it.
                    if (_bAllowBogusAndInaccessible)
                    {
                        _bCurrentSymIsInaccessible = true;
                    }
                    else
                    {
                        return(false);
                    }
                }

                // Check bogus.
                if (GetSemanticChecker().CheckBogus(_pCurrentSym))
                {
                    // Sym is bogus, but if we're allow it, then let it through and mark it.
                    if (_bAllowBogusAndInaccessible)
                    {
                        _bCurrentSymIsBogus = true;
                    }
                    else
                    {
                        return(false);
                    }
                }

                // if we are done checking all the instance types ensure that currentsym is an
                // extension method and not a simple static method
                if (!_bIsCheckingInstanceMethods)
                {
                    if (!_pCurrentSym.AsMethodSymbol().IsExtension())
                    {
                        return(false);
                    }
                }

                return(true);
            }