LookupNextSym() 공개 메소드

public LookupNextSym ( Symbol sym, Microsoft.CSharp.RuntimeBinder.Semantics.ParentSymbol parent, symbmask_t kindmask ) : Symbol
sym Symbol
parent Microsoft.CSharp.RuntimeBinder.Semantics.ParentSymbol
kindmask symbmask_t
리턴 Symbol
            private bool FindNextMethod()
            {
                for (;;)
                {
                    CurrentSymbol = (CurrentSymbol == null
                        ? _symbolLoader.LookupAggMember(_name, CurrentType.OwningAggregate, _mask)
                        : SymbolLoader.LookupNextSym(CurrentSymbol, CurrentType.OwningAggregate, _mask)) as MethodOrPropertySymbol;

                    // If we couldn't find a sym, we look up the type chain and get the next type.
                    if (CurrentSymbol == null)
                    {
                        if (!FindNextTypeForInstanceMethods())
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        // Note that we do not filter the current symbol for the user. They must do that themselves.
                        // This is because for instance, BindGrpToArgs wants to filter on arguments before filtering
                        // on bogosity.

                        // If we're here, we're good to go.

                        return(true);
                    }
                }
            }
예제 #2
0
            private bool FindNextMethod()
            {
                while (true)
                {
                    if (_pCurrentSym == null)
                    {
                        _pCurrentSym = GetSymbolLoader().LookupAggMember(
                            _pName, _pCurrentType.getAggregate(), _mask) as MethodOrPropertySymbol;
                    }
                    else
                    {
                        _pCurrentSym = SymbolLoader.LookupNextSym(
                            _pCurrentSym, _pCurrentType.getAggregate(), _mask) as MethodOrPropertySymbol;
                    }

                    // If we couldn't find a sym, we look up the type chain and get the next type.
                    if (_pCurrentSym == null)
                    {
                        if (_bIsCheckingInstanceMethods)
                        {
                            if (!FindNextTypeForInstanceMethods() && _bcanIncludeExtensionsInResults)
                            {
                                // We didn't find any more instance methods, set us into extension mode.

                                _bIsCheckingInstanceMethods = false;
                            }
                            else if (_pCurrentType == null && !_bcanIncludeExtensionsInResults)
                            {
                                return(false);
                            }
                            else
                            {
                                // Found an instance method.
                                continue;
                            }
                        }
                        continue;
                    }

                    // Note that we do not filter the current symbol for the user. They must do that themselves.
                    // This is because for instance, BindGrpToArgs wants to filter on arguments before filtering
                    // on bogosity.

                    // If we're here, we're good to go.

                    break;
                }
                return(true);
            }
 private MethodSymbol LookupMethodWhileLoading(AggregateSymbol type, int cMethodTyVars, Name methodName, ACCESS methodAccess, bool isStatic, bool isVirtual, CType returnType, TypeArray argumentTypes)
 {
     for (Symbol sym = GetSymbolLoader().LookupAggMember(methodName, type, symbmask_t.MASK_ALL);
          sym != null;
          sym = SymbolLoader.LookupNextSym(sym, type, symbmask_t.MASK_ALL))
     {
         if (sym is MethodSymbol methsym)
         {
             if ((methsym.GetAccess() == methodAccess || methodAccess == ACCESS.ACC_UNKNOWN) &&
                 methsym.isStatic == isStatic &&
                 methsym.isVirtual == isVirtual &&
                 methsym.typeVars.Count == cMethodTyVars &&
                 GetTypeManager().SubstEqualTypes(methsym.RetType, returnType, null, methsym.typeVars, true) &&
                 GetTypeManager().SubstEqualTypeArrays(methsym.Params, argumentTypes, null, methsym.typeVars))
             {
                 return(methsym);
             }
         }
     }
     return(null);
 }
예제 #4
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;

            for (symCur = GetSymbolLoader().LookupAggMember(_name, typeCur.OwningAggregate, symbmask_t.MASK_ALL);
                 symCur != null;
                 symCur = SymbolLoader.LookupNextSym(symCur, typeCur.OwningAggregate, 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 && ((MethodSymbol)symCur).typeVars.Count != _arity)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;

                case SYMKIND.SK_AggregateSymbol:
                    // For types, always filter on arity.
                    if (((AggregateSymbol)symCur).GetTypeVars().Count != _arity)
                    {
                        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())
                {
                    continue;
                }

                MethodOrPropertySymbol methProp = symCur as MethodOrPropertySymbol;
                MethodSymbol           meth     = symCur as MethodSymbol;
                if (methProp != null && (_flags & MemLookFlags.UserCallable) != 0 && !methProp.isUserCallable())
                {
                    // If its an indexed property method symbol, let it through.
                    if (meth != null &&
                        meth.isPropertyAccessor() &&
                        ((symCur.name.Text.StartsWith("set_", StringComparison.Ordinal) && meth.Params.Count > 1) ||
                         (symCur.name.Text.StartsWith("get_", StringComparison.Ordinal) && meth.Params.Count > 0)))
                    {
                        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;
                }

                PropertySymbol prop = symCur as PropertySymbol;

                // Make sure that whether we're seeing a ctor, operator, or indexer is consistent with the flags.
                if (((_flags & MemLookFlags.Ctor) == 0) != (meth == null || !meth.IsConstructor()) ||
                    ((_flags & MemLookFlags.Operator) == 0) != (meth == null || !meth.isOperator) ||
                    ((_flags & MemLookFlags.Indexer) == 0) != !(prop is IndexerSymbol))
                {
                    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 is MethodSymbol) && (_flags & MemLookFlags.Indexer) == 0 && CSemanticChecker.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 is FieldSymbol field && !IsDelegateType(field.GetType(), typeCur) && !IsDynamicMember(symCur)) ||
                        (prop != null && !IsDelegateType(prop.RetType, typeCur) && !IsDynamicMember(symCur)))
                    {
                        if (!_swtBad)
                        {
                            _swtBad.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

                if (methProp != null)
                {
                    MethPropWithType mwpInsert = new MethPropWithType(methProp, 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 is FieldSymbol && symCur is EventSymbol
                                // 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
                                )
                            {
                                // m_swtFirst is just the field behind the event symCur so ignore symCur.
                                continue;
                            }
                            else if (_swtFirst.Sym is FieldSymbol && symCur is EventSymbol)
                            {
                                // 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 (!(symCur is MethodSymbol))
                        {
                            goto LAmbig;
                        }
                        // 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.DiffHidden)
                        {
                            // Give method groups priority.
                            if (!(_swtFirst.Sym is MethodSymbol))
                            {
                                goto LAmbig;
                            }
                        }
                        // This one is hidden by another. This one also hides any more in base types.
                        pfHideByName = true;
                        continue;
                    }
                }

                RecordType(typeCur, symCur);

                if (methProp != null && methProp.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);
        }
예제 #5
0
            /////////////////////////////////////////////////////////////////////////////////

            public static MethodOrPropertySymbol FindMostDerivedMethod(
                    SymbolLoader symbolLoader,
                    MethodOrPropertySymbol pMethProp,
                    CType pType)
            {
                MethodSymbol method;
                bool bIsIndexer = false;

                if (pMethProp.IsMethodSymbol())
                {
                    method = pMethProp.AsMethodSymbol();
                }
                else
                {
                    PropertySymbol prop = pMethProp.AsPropertySymbol();
                    method = prop.methGet != null ? prop.methGet : prop.methSet;
                    if (method == null)
                    {
                        return null;
                    }
                    bIsIndexer = prop.isIndexer();
                }

                if (!method.isVirtual)
                {
                    return method;
                }

                if (pType == null)
                {
                    // This must be a static call.
                    return method;
                }

                // Now get the slot method.
                if (method.swtSlot != null && method.swtSlot.Meth() != null)
                {
                    method = method.swtSlot.Meth();
                }

                if (!pType.IsAggregateType())
                {
                    // Not something that can have overrides anyway.
                    return method;
                }

                for (AggregateSymbol pAggregate = pType.AsAggregateType().GetOwningAggregate();
                        pAggregate != null && pAggregate.GetBaseAgg() != null;
                        pAggregate = pAggregate.GetBaseAgg())
                {
                    for (MethodOrPropertySymbol meth = symbolLoader.LookupAggMember(method.name, pAggregate, symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol).AsMethodOrPropertySymbol();
                            meth != null;
                            meth = symbolLoader.LookupNextSym(meth, pAggregate, symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol).AsMethodOrPropertySymbol())
                    {
                        if (!meth.isOverride)
                        {
                            continue;
                        }
                        if (meth.swtSlot.Sym != null && meth.swtSlot.Sym == method)
                        {
                            if (bIsIndexer)
                            {
                                Debug.Assert(meth.IsMethodSymbol());
                                return meth.AsMethodSymbol().getProperty();
                            }
                            else
                            {
                                return meth;
                            }
                        }
                    }
                }

                // If we get here, it means we can have two cases: one is that we have 
                // a delegate. This is because the delegate invoke method is virtual and is 
                // an override, but we wont have the slots set up correctly, and will 
                // not find the base type in the inheritance hierarchy. The second is that
                // we're calling off of the base itself.
                Debug.Assert(method.parent.IsAggregateSymbol());
                return method;
            }
예제 #6
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();
            }
        }