///////////////////////////////////////////////////////////////////////////////// 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; }
public bool CanUseCurrentSymbol() { m_bCurrentSymIsInaccessible = false; m_bCurrentSymIsBogus = false; // Make sure that whether we're seeing a ctor is consistent with the flag. // The only properties we handle are indexers. if (m_mask == symbmask_t.MASK_MethodSymbol && ( 0 == (m_flags & EXPRFLAG.EXF_CTOR) != !m_pCurrentSym.AsMethodSymbol().IsConstructor() || 0 == (m_flags & EXPRFLAG.EXF_OPERATOR) != !m_pCurrentSym.AsMethodSymbol().isOperator) || m_mask == symbmask_t.MASK_PropertySymbol && !m_pCurrentSym.AsPropertySymbol().isIndexer()) { // Get the next symbol. return(false); } // If our arity is non-0, we must match arity with this symbol. if (m_nArity > 0) { if (m_mask == symbmask_t.MASK_MethodSymbol && m_pCurrentSym.AsMethodSymbol().typeVars.size != m_nArity) { return(false); } } // If this guy's not callable, no good. if (!ExpressionBinder.IsMethPropCallable(m_pCurrentSym, (m_flags & EXPRFLAG.EXF_USERCALLABLE) != 0)) { return(false); } // Check access. if (!GetSemanticChecker().CheckAccess(m_pCurrentSym, m_pCurrentType, m_pContext, m_pQualifyingType)) { // Sym is not accessible. However, if we're allowing inaccessible, then let it through and mark it. if (m_bAllowBogusAndInaccessible) { m_bCurrentSymIsInaccessible = true; } else { return(false); } } // Check bogus. if (GetSemanticChecker().CheckBogus(m_pCurrentSym)) { // Sym is bogus, but if we're allow it, then let it through and mark it. if (m_bAllowBogusAndInaccessible) { m_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 (!m_bIsCheckingInstanceMethods) { if (!m_pCurrentSym.AsMethodSymbol().IsExtension()) { return(false); } } return(true); }