Beispiel #1
0
        private void ReportBogus(SymWithType swt)
        {
            Debug.Assert(swt.Sym.hasBogus() && swt.Sym.checkBogus());

            switch (swt.Sym.getKind())
            {
            case SYMKIND.SK_EventSymbol:
                break;

            case SYMKIND.SK_PropertySymbol:
                if (swt.Prop().useMethInstead)
                {
                    MethodSymbol meth1 = swt.Prop().methGet;
                    MethodSymbol meth2 = swt.Prop().methSet;
                    ReportBogusForEventsAndProperties(swt, meth1, meth2);
                    return;
                }
                break;

            case SYMKIND.SK_MethodSymbol:
                if (swt.Meth().name == NameManager.GetPredefinedName(PredefinedName.PN_INVOKE) && swt.Meth().getClass().IsDelegate())
                {
                    swt.Set(swt.Meth().getClass(), swt.GetType());
                }
                break;

            default:
                break;
            }

            // Generic bogus error.
            GetErrorContext().ErrorRef(ErrorCode.ERR_BindToBogus, swt);
        }
        public static RuntimeBinderException ReportAccessError(SymWithType swtBad, Symbol symWhere, CType typeQual)
        {
            Debug.Assert(!CheckAccess(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) ||
                         !CheckTypeAccess(swtBad.GetType(), symWhere));

            return(CheckAccess2(swtBad.Sym, swtBad.GetType(), symWhere, typeQual)
                   == ACCESSERROR.ACCESSERROR_NOACCESSTHRU
                ? ErrorHandling.Error(ErrorCode.ERR_BadProtectedAccess, swtBad, typeQual, symWhere)
                : ErrorHandling.Error(ErrorCode.ERR_BadAccess, swtBad));
        }
Beispiel #3
0
        public override bool Equals(object obj)
        {
            SymWithType other = obj as SymWithType;

            if (other == null)
            {
                return(false);
            }
            return(this.Sym == other.Sym && this.Ats == other.Ats);
        }
Beispiel #4
0
        [ExcludeFromCodeCoverage] // == overload should always be the method called.
        public override bool Equals(object obj)
        {
            Debug.Fail("Sub-optimal equality called. Check if this is correct.");
            SymWithType other = obj as SymWithType;

            if (other == null)
            {
                return(false);
            }
            return(Sym == other.Sym && Ats == other.Ats);
        }
Beispiel #5
0
        /////////////////////////////////////////////////////////////////////////////////
        // Public methods.

        public MemberLookup()
        {
            _methPropWithTypeList = new List <MethPropWithType>();
            _rgtypeStart          = new List <AggregateType>();
            _swtFirst             = new SymWithType();
            _swtAmbig             = new SymWithType();
            _swtInaccess          = new SymWithType();
            _swtBad      = new SymWithType();
            _swtBogus    = new SymWithType();
            _swtBadArity = new SymWithType();
        }
Beispiel #6
0
 private void ReportBogusForEventsAndProperties(SymWithType swt, MethodSymbol meth1, MethodSymbol meth2)
 {
     if (meth1 != null && meth2 != null)
     {
         GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp2, swt.Sym.name, new SymWithType(meth1, swt.GetType()), new SymWithType(meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym));
         return;
     }
     if (meth1 != null || meth2 != null)
     {
         GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp1, swt.Sym.name, new SymWithType(meth1 != null ? meth1 : meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym));
         return;
     }
     throw Error.InternalCompilerError();
 }
Beispiel #7
0
        public void ReportAccessError(SymWithType swtBad, Symbol symWhere, CType typeQual)
        {
            Debug.Assert(!CheckAccess(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) ||
                         !CheckTypeAccess(swtBad.GetType(), symWhere));

            if (CheckAccess2(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) == ACCESSERROR.ACCESSERROR_NOACCESSTHRU)
            {
                ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, swtBad, typeQual, symWhere);
            }
            else
            {
                ErrorContext.ErrorRef(ErrorCode.ERR_BadAccess, swtBad);
            }
        }
Beispiel #8
0
        private static RuntimeBinderException ReportBogus(SymWithType swt)
        {
            Debug.Assert(CSemanticChecker.CheckBogus(swt.Sym));
            MethodSymbol meth1 = swt.Prop().GetterMethod;
            MethodSymbol meth2 = swt.Prop().SetterMethod;

            Debug.Assert((meth1 ?? meth2) != null);
            return(meth1 == null | meth2 == null
                ? ErrorHandling.Error(
                       ErrorCode.ERR_BindToBogusProp1, swt.Sym.name, new SymWithType(meth1 ?? meth2, swt.GetType()),
                       new ErrArgRefOnly(swt.Sym))
                : ErrorHandling.Error(
                       ErrorCode.ERR_BindToBogusProp2, swt.Sym.name, new SymWithType(meth1, swt.GetType()),
                       new SymWithType(meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym)));
        }
Beispiel #9
0
        private void ReportBogus(SymWithType swt)
        {
            Debug.Assert(CSemanticChecker.CheckBogus(swt.Sym));
            MethodSymbol meth1 = swt.Prop().GetterMethod;
            MethodSymbol meth2 = swt.Prop().SetterMethod;

            Debug.Assert((meth1 ?? meth2) != null);
            if (meth1 == null | meth2 == null)
            {
                GetErrorContext().Error(
                    ErrorCode.ERR_BindToBogusProp1, swt.Sym.name, new SymWithType(meth1 ?? meth2, swt.GetType()),
                    new ErrArgRefOnly(swt.Sym));
            }
            else
            {
                GetErrorContext().Error(
                    ErrorCode.ERR_BindToBogusProp2, swt.Sym.name, new SymWithType(meth1, swt.GetType()),
                    new SymWithType(meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym));
            }
        }
Beispiel #10
0
        public void ReportAccessError(SymWithType swtBad, Symbol symWhere, CType typeQual)
        {
            Debug.Assert(!CheckAccess(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) ||
                   !CheckTypeAccess(swtBad.GetType(), symWhere));

            if (CheckAccess2(swtBad.Sym, swtBad.GetType(), symWhere, typeQual) == ACCESSERROR.ACCESSERROR_NOACCESSTHRU)
            {
                ErrorContext.Error(ErrorCode.ERR_BadProtectedAccess, swtBad, typeQual, symWhere);
            }
            else
            {
                ErrorContext.ErrorRef(ErrorCode.ERR_BadAccess, swtBad);
            }
        }
Beispiel #11
0
 private void ReportBogusForEventsAndProperties(SymWithType swt, MethodSymbol meth1, MethodSymbol meth2)
 {
     if (meth1 != null && meth2 != null)
     {
         GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp2, swt.Sym.name, new SymWithType(meth1, swt.GetType()), new SymWithType(meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym));
         return;
     }
     if (meth1 != null || meth2 != null)
     {
         GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp1, swt.Sym.name, new SymWithType(meth1 != null ? meth1 : meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym));
         return;
     }
     throw Error.InternalCompilerError();
 }
Beispiel #12
0
        /////////////////////////////////////////////////////////////////////////////////
        // Public methods.

        public MemberLookup()
        {
            _methPropWithTypeList = new List<MethPropWithType>();
            _rgtypeStart = new List<AggregateType>();
            _swtFirst = new SymWithType();
            _swtAmbig = new SymWithType();
            _swtInaccess = new SymWithType();
            _swtBad = new SymWithType();
            _swtBogus = new SymWithType();
            _swtBadArity = new SymWithType();
            _swtAmbigWarn = new SymWithType();
            _swtOverride = new SymWithType();
        }
Beispiel #13
0
            private void LookForCandidates()
            {
                bool fExpanded = false;
                bool bSearchForExpanded = true;
                int cswtMaxWrongCount = _swtWrongCount.Length;
                bool allCandidatesUnsupported = true;
                bool lookedAtCandidates = false;

                // Calculate the mask based on the type of the sym we've found so far.  This
                // is to ensure that if we found a propsym (or methsym, or whatever) the 
                // iterator will only return propsyms (or methsyms, or whatever)
                symbmask_t mask = (symbmask_t)(1 << (int)_pGroup.sk);

                CType pTypeThrough = _pGroup.GetOptionalObject() != null ? _pGroup.GetOptionalObject().type : null;
                CMemberLookupResults.CMethodIterator iterator = _pGroup.GetMemberLookupResults().GetMethodIterator(GetSemanticChecker(), GetSymbolLoader(), pTypeThrough, GetTypeQualifier(_pGroup), _pExprBinder.ContextForMemberLookup(), true, // AllowBogusAndInaccessible
                    false, _pGroup.typeArgs.size, _pGroup.flags, mask);
                while (true)
                {
                    bool bFoundExpanded;
                    Result currentTypeArgsResult;

                    bFoundExpanded = false;
                    if (bSearchForExpanded && !fExpanded)
                    {
                        bFoundExpanded = fExpanded = ConstructExpandedParameters();
                    }

                    // Get the next sym to search for.
                    if (!bFoundExpanded)
                    {
                        fExpanded = false;

                        if (!GetNextSym(iterator))
                        {
                            break;
                        }

                        // Get the parameters.
                        _pCurrentParameters = _pCurrentSym.Params;
                        bSearchForExpanded = true;
                    }

                    if (_bArgumentsChangedForNamedOrOptionalArguments)
                    {
                        // If we changed them last time, then we need to reset them.
                        _bArgumentsChangedForNamedOrOptionalArguments = false;
                        CopyArgInfos(_pOriginalArguments, _pArguments);
                    }

                    // If we have named arguments, reorder them for this method.
                    if (_pArguments.fHasExprs)
                    {
                        // If we dont have EXPRs, its because we're doing a method group conversion.
                        // In those scenarios, we never want to add named arguments or optional arguments.
                        if (_bHasNamedArguments)
                        {
                            if (!ReOrderArgsForNamedArguments())
                            {
                                continue;
                            }
                        }
                        else if (HasOptionalParameters())
                        {
                            if (!AddArgumentsForOptionalParameters())
                            {
                                continue;
                            }
                        }
                    }

                    if (!bFoundExpanded)
                    {
                        lookedAtCandidates = true;
                        allCandidatesUnsupported &= _pCurrentSym.getBogus();

                        // If we have the wrong number of arguments and still have room in our cache of 20,
                        // then store it in our cache and go to the next sym.
                        if (_pCurrentParameters.size != _pArguments.carg)
                        {
                            if (_nWrongCount < cswtMaxWrongCount &&
                                    (!_pCurrentSym.isParamArray || _pArguments.carg < _pCurrentParameters.size - 1))
                            {
                                _swtWrongCount[_nWrongCount++] = new SymWithType(_pCurrentSym, _pCurrentType);
                            }
                            bSearchForExpanded = true;
                            continue;
                        }
                    }

                    // If we cant use the current symbol, then we've filtered it, so get the next one.

                    if (!iterator.CanUseCurrentSymbol())
                    {
                        continue;
                    }

                    // Get the current type args.
                    currentTypeArgsResult = DetermineCurrentTypeArgs();
                    if (currentTypeArgsResult != Result.Success)
                    {
                        bSearchForExpanded = (currentTypeArgsResult == Result.Failure_SearchForExpanded);
                        continue;
                    }

                    // Check access.
                    bool fCanAccess = !iterator.IsCurrentSymbolInaccessible();
                    if (!fCanAccess && (!_methList.IsEmpty() || _results.GetInaccessibleResult()))
                    {
                        // We'll never use this one for error reporting anyway, so just skip it.
                        bSearchForExpanded = false;
                        continue;
                    }

                    // Check bogus.
                    bool fBogus = fCanAccess && iterator.IsCurrentSymbolBogus();
                    if (fBogus && (!_methList.IsEmpty() || _results.GetInaccessibleResult() || _mpwiBogus))
                    {
                        // We'll never use this one for error reporting anyway, so just skip it.
                        bSearchForExpanded = false;
                        continue;
                    }

                    // Check convertibility of arguments.
                    if (!ArgumentsAreConvertible())
                    {
                        bSearchForExpanded = true;
                        continue;
                    }

                    // We know we have the right number of arguments and they are all convertible.
                    if (!fCanAccess)
                    {
                        // In case we never get an accessible method, this will allow us to give
                        // a better error...
                        Debug.Assert(!_results.GetInaccessibleResult());
                        _results.GetInaccessibleResult().Set(_pCurrentSym, _pCurrentType, _pCurrentTypeArgs);
                    }
                    else if (fBogus)
                    {
                        // In case we never get a good method, this will allow us to give
                        // a better error...
                        Debug.Assert(!_mpwiBogus);
                        _mpwiBogus.Set(_pCurrentSym, _pCurrentType, _pCurrentTypeArgs);
                    }
                    else
                    {
                        // This is a plausible method / property to call.
                        // Link it in at the end of the list.
                        _methList.Add(new CandidateFunctionMember(
                                    new MethPropWithInst(_pCurrentSym, _pCurrentType, _pCurrentTypeArgs),
                                    _pCurrentParameters,
                                    0,
                                    fExpanded));

                        // When we find a method, we check if the type has interfaces. If so, mark the other interfaces
                        // as hidden, and object as well.

                        if (_pCurrentType.isInterfaceType())
                        {
                            TypeArray ifaces = _pCurrentType.GetIfacesAll();
                            for (int i = 0; i < ifaces.size; i++)
                            {
                                AggregateType type = ifaces.Item(i).AsAggregateType();

                                Debug.Assert(type.isInterfaceType());
                                _HiddenTypes.Add(type);
                            }

                            // Mark object.
                            AggregateType typeObject = GetSymbolLoader().GetReqPredefType(PredefinedType.PT_OBJECT, true);
                            _HiddenTypes.Add(typeObject);
                        }
                    }

                    // Don't look at the expanded form.
                    bSearchForExpanded = false;
                }
                _fCandidatesUnsupported = allCandidatesUnsupported && lookedAtCandidates;

                // Restore the arguments to their original state if we changed them for named/optional arguments.
                // ILGen will take care of putting the real arguments in there.
                if (_bArgumentsChangedForNamedOrOptionalArguments)
                {
                    // If we changed them last time, then we need to reset them.
                    CopyArgInfos(_pOriginalArguments, _pArguments);
                }
            }
Beispiel #14
0
        /////////////////////////////////////////////////////////////////////////////////

        private EXPREVENT CreateEvent(
            SymWithType swt,
            EXPR callingObject)
        {
            EventSymbol eventSymbol = swt.Event();
            EXPREVENT e = _exprFactory.CreateEvent(eventSymbol.type, callingObject, new EventWithType(eventSymbol, swt.GetType()));
            return e;
        }
Beispiel #15
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);
        }
Beispiel #16
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);
        }
Beispiel #17
0
 public PropWithType(SymWithType swt)
 {
     Set(swt.Sym as PropertySymbol, swt.Ats);
 }
Beispiel #18
0
        private void ReportBogus(SymWithType swt)
        {
            Debug.Assert(swt.Sym.hasBogus() && swt.Sym.checkBogus());

            switch (swt.Sym.getKind())
            {
                case SYMKIND.SK_EventSymbol:
                    break;

                case SYMKIND.SK_PropertySymbol:
                    if (swt.Prop().useMethInstead)
                    {
                        MethodSymbol meth1 = swt.Prop().methGet;
                        MethodSymbol meth2 = swt.Prop().methSet;
                        ReportBogusForEventsAndProperties(swt, meth1, meth2);
                        return;
                    }
                    break;

                case SYMKIND.SK_MethodSymbol:
                    if (swt.Meth().name == GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_INVOKE) && swt.Meth().getClass().IsDelegate())
                    {
                        swt.Set(swt.Meth().getClass(), swt.GetType());
                    }
                    break;

                default:
                    break;
            }

            // Generic bogus error.
            GetErrorContext().ErrorRef(ErrorCode.ERR_BindToBogus, swt);
        }
Beispiel #19
0
        ////////////////////////////////////////////////////////////////////////////////
        // For a base call we need to remap from the virtual to the specific override 
        // to invoke.  This is also used to map a virtual on pObject (like ToString) to 
        // the specific override when the pObject is a simple type (int, bool, char, 
        // etc). In these cases it is safe to assume that any override won't later be 
        // removed.... We start searching from "typeObj" up the superclass hierarchy 
        // until we find a method with an exact signature match.

        public static void RemapToOverride(SymbolLoader symbolLoader, SymWithType pswt, CType typeObj)
        {
            // For a property/indexer we remap the accessors, not the property/indexer.
            // Since every event has both accessors we remap the event instead of the accessors.
            Debug.Assert(pswt && (pswt.Sym.IsMethodSymbol() || pswt.Sym.IsEventSymbol() || pswt.Sym.IsMethodOrPropertySymbol()));
            Debug.Assert(typeObj != null);

            // Don't remap static or interface methods.
            if (typeObj.IsNullableType())
            {
                typeObj = typeObj.AsNullableType().GetAts(symbolLoader.GetErrorContext());
                if (typeObj == null)
                {
                    VSFAIL("Why did GetAts return null?");
                    return;
                }
            }

            // Don't remap non-virtual members
            if (!typeObj.IsAggregateType() || typeObj.isInterfaceType() || !pswt.Sym.IsVirtual())
            {
                return;
            }

            symbmask_t mask = pswt.Sym.mask();

            AggregateType atsObj = typeObj.AsAggregateType();

            // Search for an override version of the method.
            while (atsObj != null && atsObj.getAggregate() != pswt.Sym.parent)
            {
                for (Symbol symT = symbolLoader.LookupAggMember(pswt.Sym.name, atsObj.getAggregate(), mask);
                     symT != null;
                     symT = symbolLoader.LookupNextSym(symT, atsObj.getAggregate(), mask))
                {
                    if (symT.IsOverride() && (symT.SymBaseVirtual() == pswt.Sym || symT.SymBaseVirtual() == pswt.Sym.SymBaseVirtual()))
                    {
                        pswt.Set(symT, atsObj);
                        return;
                    }
                }
                atsObj = atsObj.GetBaseClass();
            }
        }
Beispiel #20
0
        /////////////////////////////////////////////////////////////////////////////////

        private bool IsMatchingStatic(SymWithType swt, EXPR pObject)
        {
            Symbol pSym = swt.Sym;

            // Instance constructors are always ok, static constructors are never ok.
            if (pSym.IsMethodSymbol() && pSym.AsMethodSymbol().IsConstructor())
            {
                return !pSym.AsMethodSymbol().isStatic;
            }

            bool isStatic = swt.Sym.isStatic;

            if (isStatic)
            {
                // If we're static and we don't have an object, or we have an implicit this, 
                // then we're ok. The reason implicit this is ok is because if the user is
                // just typing something like:
                //
                //      Equals(
                //
                // then the implicit this can bind to statics.

                if (pObject == null || ((pObject.flags & EXPRFLAG.EXF_IMPLICITTHIS) != 0))
                {
                    return true;
                }

                if ((pObject.flags & EXPRFLAG.EXF_SAMENAMETYPE) == 0)
                {
                    return false;
                }
            }
            else if (pObject == null)
            {
                // We're not static, and we don't have an object. This is ok in certain scenarios:
                bool bNonStaticField = InFieldInitializer() && !InStaticMethod() && ContainingAgg() == swt.Sym.parent;
                bool bAnonymousMethod = InAnonymousMethod() && !InStaticMethod() && ContainingAgg() == swt.Sym.parent && ContainingAgg().IsStruct();

                if (!bNonStaticField && !bAnonymousMethod)
                {
                    return false;
                }
            }
            return true;
        }
Beispiel #21
0
        private EXPR AdjustMemberObject(SymWithType swt, EXPR pObject, out bool pfConstrained, out bool pIsMatchingStatic)
        {
            // Assert that the type is present and is an instantiation of the member's parent.
            Debug.Assert(swt.GetType() != null && swt.GetType().getAggregate() == swt.Sym.parent.AsAggregateSymbol());
            bool bIsMatchingStatic = IsMatchingStatic(swt, pObject);
            pIsMatchingStatic = bIsMatchingStatic;
            pfConstrained = false;

            bool isStatic = swt.Sym.isStatic;

            // If our static doesn't match, bail out of here.
            if (!bIsMatchingStatic)
            {
                if (isStatic)
                {
                    // If we have a mismatched static, a static method, and the binding flag
                    // that tells us we're binding simple names, then insert a type here instead.
                    if ((pObject.flags & EXPRFLAG.EXF_SIMPLENAME) != 0)
                    {
                        // We've made the static match now.
                        pIsMatchingStatic = true;
                        return null;
                    }
                    else
                    {
                        ErrorContext.ErrorRef(ErrorCode.ERR_ObjectProhibited, swt);
                        return null;
                    }
                }
                else
                {
                    ErrorContext.ErrorRef(ErrorCode.ERR_ObjectRequired, swt);
                    return pObject;
                }
            }

            // At this point, all errors for static invocations have been reported, and
            // the object has been nulled out. So return out of here.
            if (isStatic)
            {
                return null;
            }

            // If we're in a constructor, then bail.
            if (swt.Sym.IsMethodSymbol() && swt.Meth().IsConstructor())
            {
                return pObject;
            }

            if (pObject == null)
            {
                if (InFieldInitializer() && !InStaticMethod() && ContainingAgg() == swt.Sym.parent)
                {
                    ErrorContext.ErrorRef(ErrorCode.ERR_FieldInitRefNonstatic, swt); // give better error message for common mistake <BUGNUM>See VS7:119218</BUGNUM>
                }
                else if (InAnonymousMethod() && !InStaticMethod() && ContainingAgg() == swt.Sym.parent && ContainingAgg().IsStruct())
                {
                    ErrorContext.Error(ErrorCode.ERR_ThisStructNotInAnonMeth);
                }
                else
                {
                    return null;
                }

                // For fields or structs, make a this pointer for us to use.

                EXPRTHISPOINTER thisExpr = GetExprFactory().CreateThis(Context.GetThisPointer(), true);
                thisExpr.SetMismatchedStaticBit();
                if (thisExpr.type == null)
                {
                    thisExpr.setType(GetTypes().GetErrorSym());
                }
                return thisExpr;
            }

            CType typeObj = pObject.type;
            CType typeTmp;

            if (typeObj.IsNullableType() && (typeTmp = typeObj.AsNullableType().GetAts(GetErrorContext())) != null && typeTmp != swt.GetType())
            {
                typeObj = typeTmp;
            }

            if (typeObj.IsTypeParameterType() || typeObj.IsAggregateType())
            {
                AggregateSymbol aggCalled = null;
                aggCalled = swt.Sym.parent.AsAggregateSymbol();
                Debug.Assert(swt.GetType().getAggregate() == aggCalled);

                // If we're invoking code on a struct-valued field, mark the struct as assigned (to
                // avoid warning CS0649).
                if (pObject.isFIELD() && !pObject.asFIELD().fwt.Field().isAssigned && !swt.Sym.IsFieldSymbol() &&
                    typeObj.isStructType() && !typeObj.isPredefined())
                {
                    pObject.asFIELD().fwt.Field().isAssigned = true;
                }

                if (pfConstrained &&
                    (typeObj.IsTypeParameterType() ||
                     typeObj.isStructType() && swt.GetType().IsRefType() && swt.Sym.IsVirtual()))
                {
                    // For calls on type parameters or virtual calls on struct types (not enums),
                    // use the constrained prefix.
                    pfConstrained = true;
                }

                EXPR objNew = tryConvert(pObject, swt.GetType(), CONVERTTYPE.NOUDC);

                // This check ensures that we do not bind to methods in an outer class
                // which are visible, but whose this pointer is of an incorrect type...
                // ... also handles case of calling an pObject method on a RefAny value.
                // WE don't give a great message for this, but it'll do.
                if (objNew == null)
                {
                    if (!pObject.type.isSpecialByRefType())
                    {
                        ErrorContext.Error(ErrorCode.ERR_WrongNestedThis, swt.GetType(), pObject.type);
                    }
                    else
                    {
                        ErrorContext.Error(ErrorCode.ERR_NoImplicitConv, pObject.type, swt.GetType());
                    }
                }
                pObject = objNew;
            }

            return pObject;
        }
Beispiel #22
0
        /******************************************************************************
        *   Search just the given type (not any bases). Returns true iff it finds
        *   something (which will have been recorded by RecordType).
        *
        *   pfHideByName is set to true iff something was found that hides all
        *   members of base types (eg, a hidebyname method).
        ******************************************************************************/
        private bool SearchSingleType(AggregateType typeCur, out bool pfHideByName)
        {
            bool             fFoundSome = false;
            MethPropWithType mwpInsert;

            pfHideByName = false;

            // Make sure this type is accessible. It may not be due to private inheritance
            // or friend assemblies.
            bool fInaccess = !GetSemanticChecker().CheckTypeAccess(typeCur, _symWhere);

            if (fInaccess && (_csym != 0 || _swtInaccess != null))
            {
                return(false);
            }

            // Loop through symbols.
            Symbol symCur = null;

            for (symCur = GetSymbolLoader().LookupAggMember(_name, typeCur.getAggregate(), symbmask_t.MASK_ALL);
                 symCur != null;
                 symCur = GetSymbolLoader().LookupNextSym(symCur, typeCur.getAggregate(), symbmask_t.MASK_ALL))
            {
                // Check for arity.
                switch (symCur.getKind())
                {
                case SYMKIND.SK_MethodSymbol:
                    // For non-zero arity, only methods of the correct arity are considered.
                    // For zero arity, don't filter out any methods since we do type argument
                    // inferencing.
                    if (_arity > 0 && symCur.AsMethodSymbol().typeVars.size != _arity)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;

                case SYMKIND.SK_AggregateSymbol:
                    // For types, always filter on arity.
                    if (symCur.AsAggregateSymbol().GetTypeVars().size != _arity)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;

                case SYMKIND.SK_TypeParameterSymbol:
                    if ((_flags & MemLookFlags.TypeVarsAllowed) == 0)
                    {
                        continue;
                    }
                    if (_arity > 0)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;

                default:
                    // All others are only considered when arity is zero.
                    if (_arity > 0)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;
                }

                // Check for user callability.
                if (symCur.IsOverride() && !symCur.IsHideByName())
                {
                    if (!_swtOverride)
                    {
                        _swtOverride.Set(symCur, typeCur);
                    }
                    continue;
                }
                if ((_flags & MemLookFlags.UserCallable) != 0 && symCur.IsMethodOrPropertySymbol() && !symCur.AsMethodOrPropertySymbol().isUserCallable())
                {
                    bool bIsIndexedProperty = false;
                    // If its an indexed property method symbol, let it through.
                    if (symCur.IsMethodSymbol() &&
                        symCur.AsMethodSymbol().isPropertyAccessor() &&
                        ((symCur.name.Text.StartsWith("set_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 1) ||
                         (symCur.name.Text.StartsWith("get_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 0)))
                    {
                        bIsIndexedProperty = true;
                    }

                    if (!bIsIndexedProperty)
                    {
                        if (!_swtInaccess)
                        {
                            _swtInaccess.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

                if (fInaccess || !GetSemanticChecker().CheckAccess(symCur, typeCur, _symWhere, _typeQual))
                {
                    // Not accessible so get the next sym.
                    if (!_swtInaccess)
                    {
                        _swtInaccess.Set(symCur, typeCur);
                    }
                    if (fInaccess)
                    {
                        return(false);
                    }
                    continue;
                }

                // Make sure that whether we're seeing a ctor, operator, or indexer is consistent with the flags.
                if (((_flags & MemLookFlags.Ctor) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().IsConstructor()) ||
                    ((_flags & MemLookFlags.Operator) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().isOperator) ||
                    ((_flags & MemLookFlags.Indexer) == 0) != (!symCur.IsPropertySymbol() || !symCur.AsPropertySymbol().isIndexer()))
                {
                    if (!_swtBad)
                    {
                        _swtBad.Set(symCur, typeCur);
                    }
                    continue;
                }

                // We can't call CheckBogus on methods or indexers because if the method has the wrong
                // number of parameters people don't think they should have to /r the assemblies containing
                // the parameter types and they complain about the resulting CS0012 errors.
                if (!symCur.IsMethodSymbol() && (_flags & MemLookFlags.Indexer) == 0 && GetSemanticChecker().CheckBogus(symCur))
                {
                    // A bogus member - we can't use these, so only record them for error reporting.
                    if (!_swtBogus)
                    {
                        _swtBogus.Set(symCur, typeCur);
                    }
                    continue;
                }

                // if we are in a calling context then we should only find a property if it is delegate valued
                if ((_flags & MemLookFlags.MustBeInvocable) != 0)
                {
                    if ((symCur.IsFieldSymbol() && !IsDelegateType(symCur.AsFieldSymbol().GetType(), typeCur) && !IsDynamicMember(symCur)) ||
                        (symCur.IsPropertySymbol() && !IsDelegateType(symCur.AsPropertySymbol().RetType, typeCur) && !IsDynamicMember(symCur)))
                    {
                        if (!_swtBad)
                        {
                            _swtBad.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

                if (symCur.IsMethodOrPropertySymbol())
                {
                    mwpInsert = new MethPropWithType(symCur.AsMethodOrPropertySymbol(), typeCur);
                    _methPropWithTypeList.Add(mwpInsert);
                }

                // We have a visible symbol.
                fFoundSome = true;

                if (_swtFirst)
                {
                    if (!typeCur.isInterfaceType())
                    {
                        // Non-interface case.
                        Debug.Assert(_fMulti || typeCur == _prgtype[0]);
                        if (!_fMulti)
                        {
                            if (_swtFirst.Sym.IsFieldSymbol() && symCur.IsEventSymbol()
#if !CSEE                       // The isEvent bit is only set on symbols which come from source...
                                // This is not a problem for the compiler because the field is only
                                // accessible in the scope in which it is declared,
                                // but in the EE we ignore accessibility...
                                && _swtFirst.Field().isEvent
#endif
                                )
                            {
                                // m_swtFirst is just the field behind the event symCur so ignore symCur.
                                continue;
                            }
                            else if (_swtFirst.Sym.IsFieldSymbol() && symCur.IsEventSymbol())
                            {
                                // symCur is the matching event.
                                continue;
                            }
                            goto LAmbig;
                        }
                        if (_swtFirst.Sym.getKind() != symCur.getKind())
                        {
                            if (typeCur == _prgtype[0])
                            {
                                goto LAmbig;
                            }
                            // This one is hidden by the first one. This one also hides any more in base types.
                            pfHideByName = true;
                            continue;
                        }
                    }
                    // Interface case.
                    // m_fMulti   : n n n y y y y y
                    // same-kind  : * * * y n n n n
                    // fDiffHidden: * * * * y n n n
                    // meth       : * * * * * y n *  can n happen? just in case, we better handle it....
                    // hack       : n * y * * y * n
                    // meth-2     : * n y * * * * *
                    // res        : A A S R H H A A
                    else if (!_fMulti)
                    {
                        // Give method groups priority.
                        if (/* !GetSymbolLoader().options.fLookupHack ||*/ !symCur.IsMethodSymbol())
                        {
                            goto LAmbig;
                        }
                        _swtAmbigWarn = _swtFirst;
                        // Erase previous results so we'll record this method as the first.
                        _prgtype = new List <AggregateType>();
                        _csym    = 0;
                        _swtFirst.Clear();
                        _swtAmbig.Clear();
                    }
                    else if (_swtFirst.Sym.getKind() != symCur.getKind())
                    {
                        if (!typeCur.fDiffHidden)
                        {
                            // Give method groups priority.
                            if (/*!GetSymbolLoader().options.fLookupHack ||*/ !_swtFirst.Sym.IsMethodSymbol())
                            {
                                goto LAmbig;
                            }
                            if (!_swtAmbigWarn)
                            {
                                _swtAmbigWarn.Set(symCur, typeCur);
                            }
                        }
                        // This one is hidden by another. This one also hides any more in base types.
                        pfHideByName = true;
                        continue;
                    }
                }

                RecordType(typeCur, symCur);

                if (symCur.IsMethodOrPropertySymbol() && symCur.AsMethodOrPropertySymbol().isHideByName)
                {
                    pfHideByName = true;
                }
                // We've found a symbol in this type but need to make sure there aren't any conflicting
                // syms here, so keep searching the type.
            }

            Debug.Assert(!fInaccess || !fFoundSome);

            return(fFoundSome);

LAmbig:
            // Ambiguous!
            if (!_swtAmbig)
            {
                _swtAmbig.Set(symCur, typeCur);
            }
            pfHideByName = true;
            return(true);
        }
Beispiel #23
0
        /////////////////////////////////////////////////////////////////////////////////

        private EXPR CreateField(
            SymWithType swt,
            EXPR callingObject)
        {
            // For a field, simply create the EXPRFIELD and our caller takes care of the rest.

            FieldSymbol fieldSymbol = swt.Field();
            CType returnType = fieldSymbol.GetType();
            AggregateType fieldType = swt.GetType();
            FieldWithType fwt = new FieldWithType(fieldSymbol, fieldType);

            EXPR field = _binder.BindToField(callingObject.isCLASS() ? null : callingObject, fwt, 0);
            return field;
        }
Beispiel #24
0
 public ErrArg(SymWithType swt)
 {
     this.eak = ErrArgKind.SymWithType;
     this.eaf = ErrArgFlags.None;
     this.swtMemo = new SymWithTypeMemo();
     this.swtMemo.sym = swt.Sym;
     this.swtMemo.ats = swt.Ats;
 }
Beispiel #25
0
 public PropWithType(SymWithType swt)
 {
     Set(swt.Sym as PropertySymbol, swt.Ats);
 }
Beispiel #26
0
 public ErrArgRef(SymWithType swt)
     : base(swt)
 {
     this.eaf = ErrArgFlags.Ref;
 }
Beispiel #27
0
        /******************************************************************************
            Search just the given type (not any bases). Returns true iff it finds
            something (which will have been recorded by RecordType).
         
            pfHideByName is set to true iff something was found that hides all
            members of base types (eg, a hidebyname method).
        ******************************************************************************/
        private bool SearchSingleType(AggregateType typeCur, out bool pfHideByName)
        {
            bool fFoundSome = false;

            pfHideByName = false;

            // Make sure this type is accessible. It may not be due to private inheritance
            // or friend assemblies.
            bool fInaccess = !GetSemanticChecker().CheckTypeAccess(typeCur, _symWhere);
            if (fInaccess && (_csym != 0 || _swtInaccess != null))
                return false;

            // Loop through symbols.
            Symbol symCur = null;
            for (symCur = GetSymbolLoader().LookupAggMember(_name, typeCur.getAggregate(), symbmask_t.MASK_ALL);
                 symCur != null;
                 symCur = GetSymbolLoader().LookupNextSym(symCur, typeCur.getAggregate(), symbmask_t.MASK_ALL))
            {
                // Check for arity.
                switch (symCur.getKind())
                {
                    case SYMKIND.SK_MethodSymbol:
                        // For non-zero arity, only methods of the correct arity are considered.
                        // For zero arity, don't filter out any methods since we do type argument
                        // inferencing.
                        if (_arity > 0 && symCur.AsMethodSymbol().typeVars.size != _arity)
                        {
                            if (!_swtBadArity)
                                _swtBadArity.Set(symCur, typeCur);
                            continue;
                        }
                        break;

                    case SYMKIND.SK_AggregateSymbol:
                        // For types, always filter on arity.
                        if (symCur.AsAggregateSymbol().GetTypeVars().size != _arity)
                        {
                            if (!_swtBadArity)
                                _swtBadArity.Set(symCur, typeCur);
                            continue;
                        }
                        break;

                    case SYMKIND.SK_TypeParameterSymbol:
                        if ((_flags & MemLookFlags.TypeVarsAllowed) == 0)
                            continue;
                        if (_arity > 0)
                        {
                            if (!_swtBadArity)
                                _swtBadArity.Set(symCur, typeCur);
                            continue;
                        }
                        break;

                    default:
                        // All others are only considered when arity is zero.
                        if (_arity > 0)
                        {
                            if (!_swtBadArity)
                                _swtBadArity.Set(symCur, typeCur);
                            continue;
                        }
                        break;
                }

                // Check for user callability.
                if (symCur.IsOverride() && !symCur.IsHideByName())
                {
                    if (!_swtOverride)
                    {
                        _swtOverride.Set(symCur, typeCur);
                    }
                    continue;
                }
                if ((_flags & MemLookFlags.UserCallable) != 0 && symCur.IsMethodOrPropertySymbol() && !symCur.AsMethodOrPropertySymbol().isUserCallable())
                {
                    bool bIsIndexedProperty = false;
                    // If its an indexed property method symbol, let it through.
                    if (symCur.IsMethodSymbol() &&
                        symCur.AsMethodSymbol().isPropertyAccessor() &&
                        ((symCur.name.Text.StartsWith("set_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 1) ||
                        (symCur.name.Text.StartsWith("get_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 0)))
                    {
                        bIsIndexedProperty = true;
                    }

                    if (!bIsIndexedProperty)
                    {
                        if (!_swtInaccess)
                        {
                            _swtInaccess.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

                if (fInaccess || !GetSemanticChecker().CheckAccess(symCur, typeCur, _symWhere, _typeQual))
                {
                    // Not accessible so get the next sym.
                    if (!_swtInaccess)
                    {
                        _swtInaccess.Set(symCur, typeCur);
                    }
                    if (fInaccess)
                    {
                        return false;
                    }
                    continue;
                }

                // Make sure that whether we're seeing a ctor, operator, or indexer is consistent with the flags.
                if (((_flags & MemLookFlags.Ctor) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().IsConstructor()) ||
                    ((_flags & MemLookFlags.Operator) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().isOperator) ||
                    ((_flags & MemLookFlags.Indexer) == 0) != (!symCur.IsPropertySymbol() || !symCur.AsPropertySymbol().isIndexer()))
                {
                    if (!_swtBad)
                    {
                        _swtBad.Set(symCur, typeCur);
                    }
                    continue;
                }

                // We can't call CheckBogus on methods or indexers because if the method has the wrong
                // number of parameters people don't think they should have to /r the assemblies containing
                // the parameter types and they complain about the resulting CS0012 errors.
                if (!symCur.IsMethodSymbol() && (_flags & MemLookFlags.Indexer) == 0 && GetSemanticChecker().CheckBogus(symCur))
                {
                    // A bogus member - we can't use these, so only record them for error reporting.
                    if (!_swtBogus)
                    {
                        _swtBogus.Set(symCur, typeCur);
                    }
                    continue;
                }

                // if we are in a calling context then we should only find a property if it is delegate valued
                if ((_flags & MemLookFlags.MustBeInvocable) != 0)
                {
                    if ((symCur.IsFieldSymbol() && !IsDelegateType(symCur.AsFieldSymbol().GetType(), typeCur) && !IsDynamicMember(symCur)) ||
                        (symCur.IsPropertySymbol() && !IsDelegateType(symCur.AsPropertySymbol().RetType, typeCur) && !IsDynamicMember(symCur)))
                    {
                        if (!_swtBad)
                        {
                            _swtBad.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

                if (symCur.IsMethodOrPropertySymbol())
                {
                    MethPropWithType mwpInsert = new MethPropWithType(symCur.AsMethodOrPropertySymbol(), typeCur);
                    _methPropWithTypeList.Add(mwpInsert);
                }

                // We have a visible symbol.
                fFoundSome = true;

                if (_swtFirst)
                {
                    if (!typeCur.isInterfaceType())
                    {
                        // Non-interface case.
                        Debug.Assert(_fMulti || typeCur == _prgtype[0]);
                        if (!_fMulti)
                        {
                            if (_swtFirst.Sym.IsFieldSymbol() && symCur.IsEventSymbol()
#if !CSEE                       // The isEvent bit is only set on symbols which come from source...
                                // This is not a problem for the compiler because the field is only
                                // accessible in the scope in which it is declared,
                                // but in the EE we ignore accessibility...
                                && _swtFirst.Field().isEvent
#endif
)
                            {
                                // m_swtFirst is just the field behind the event symCur so ignore symCur.
                                continue;
                            }
                            else if (_swtFirst.Sym.IsFieldSymbol() && symCur.IsEventSymbol())
                            {
                                // symCur is the matching event.
                                continue;
                            }
                            goto LAmbig;
                        }
                        if (_swtFirst.Sym.getKind() != symCur.getKind())
                        {
                            if (typeCur == _prgtype[0])
                                goto LAmbig;
                            // This one is hidden by the first one. This one also hides any more in base types.
                            pfHideByName = true;
                            continue;
                        }
                    }
                    // Interface case.
                    // m_fMulti   : n n n y y y y y
                    // same-kind  : * * * y n n n n
                    // fDiffHidden: * * * * y n n n
                    // meth       : * * * * * y n *  can n happen? just in case, we better handle it....
                    // hack       : n * y * * y * n
                    // meth-2     : * n y * * * * *
                    // res        : A A S R H H A A
                    else if (!_fMulti)
                    {
                        // Give method groups priority.
                        if ( /* !GetSymbolLoader().options.fLookupHack ||*/ !symCur.IsMethodSymbol())
                            goto LAmbig;
                        _swtAmbigWarn = _swtFirst;
                        // Erase previous results so we'll record this method as the first.
                        _prgtype = new List<AggregateType>();
                        _csym = 0;
                        _swtFirst.Clear();
                        _swtAmbig.Clear();
                    }
                    else if (_swtFirst.Sym.getKind() != symCur.getKind())
                    {
                        if (!typeCur.fDiffHidden)
                        {
                            // Give method groups priority.
                            if ( /*!GetSymbolLoader().options.fLookupHack ||*/ !_swtFirst.Sym.IsMethodSymbol())
                                goto LAmbig;
                            if (!_swtAmbigWarn)
                                _swtAmbigWarn.Set(symCur, typeCur);
                        }
                        // This one is hidden by another. This one also hides any more in base types.
                        pfHideByName = true;
                        continue;
                    }
                }

                RecordType(typeCur, symCur);

                if (symCur.IsMethodOrPropertySymbol() && symCur.AsMethodOrPropertySymbol().isHideByName)
                    pfHideByName = true;
                // We've found a symbol in this type but need to make sure there aren't any conflicting
                // syms here, so keep searching the type.
            }

            Debug.Assert(!fInaccess || !fFoundSome);

            return fFoundSome;

        LAmbig:
            // Ambiguous!
            if (!_swtAmbig)
                _swtAmbig.Set(symCur, typeCur);
            pfHideByName = true;
            return true;
        }