BCSYM* Bindable::BasesIter::GetFirst() { BCSYM *Base = NULL; m_LinkToCurrentBase = NULL; if (m_ClassOrInterface->IsClass()) { Base = m_ClassOrInterface->PClass()->GetBaseClass(); if (Base && (Base->IsBad() || !Base->IsClass())) { Base = NULL; } } else if (m_ClassOrInterface->IsInterface()) { m_LinkToCurrentBase = m_ClassOrInterface->PInterface()->GetFirstImplements(); Base = GetBaseInterface(m_LinkToCurrentBase); } return Base; }
BCSYM* Bindable::BasesIter::GetBaseInterface ( BCSYM_Implements *&LinkToBase ) { BCSYM *Base = NULL; do { do { if (!LinkToBase) { return NULL; } if (!LinkToBase->IsBad()) { break; } LinkToBase = LinkToBase->GetNext(); } while(true); Base = LinkToBase->GetInterfaceIfExists(); if (Base && !Base->IsBad()) { break; } LinkToBase = LinkToBase->GetNext(); } while(true); return Base; }
bool // true - there are events defined on the WithEvents variable AND they are visible to ContainerOfWithEventsVar Bindable::CheckForAccessibleEvents ( BCSYM *TypeOfWithEventsVar, bool ConsiderEventSourcePropertiesToo, bool &AnyEventDefined ) { // Note: the calling function is expected to initialize AnyEventDefine to false. // We don't do this here because the function is recursive. if (TypeOfWithEventsVar->IsBad()) { // This has the effect of sometimes missing an event def we could have found had we not punted. // But does it make sense to dig into an interface that is junk? return false; } BCSYM *TypePossiblyContainingEvents; if (TypeOfWithEventsVar->IsGenericParam()) { TypePossiblyContainingEvents = GetClassConstraint( TypeOfWithEventsVar->PGenericParam(), CurrentCompilerHost(), CurrentAllocator(), true, // ReturnArraysAs"System.Array" true // ReturnValuesAs"System.ValueType"or"System.Enum" ); // See if there are any events in the class constraint // // Note that the class constraint needs to be checked separately to // preserve the shadowing semantics for the events found. // if (TypePossiblyContainingEvents && !TypePossiblyContainingEvents->IsBad() && CheckForAccessibleEventsInContainer( TypePossiblyContainingEvents, TypeOfWithEventsVar, ConsiderEventSourcePropertiesToo, AnyEventDefined)) { return true; } VSASSERT(TypePossiblyContainingEvents || TypeOfWithEventsVar->PGenericParam()->IsReferenceType(), "Unexpected withevents type!!!"); // See if there are any events in the Interface constraints BCITER_Constraints ConstraintsIter(TypeOfWithEventsVar->PGenericParam(), true, CurrentCompilerInstance()); while (BCSYM_GenericConstraint *Constraint = ConstraintsIter.Next()) { VSASSERT(!Constraint->IsBadConstraint(), "Bad constraint unexpected!!!"); if (!Constraint->IsGenericTypeConstraint()) { continue; } TypePossiblyContainingEvents = Constraint->PGenericTypeConstraint()->GetType(); if (!TypePossiblyContainingEvents || TypePossiblyContainingEvents->IsBad() || !TypePossiblyContainingEvents->IsInterface()) { continue; } if (CheckForAccessibleEventsInContainer( TypePossiblyContainingEvents, TypeOfWithEventsVar, ConsiderEventSourcePropertiesToo, AnyEventDefined)) { return true; } } return false; } else { TypePossiblyContainingEvents = TypeOfWithEventsVar; return CheckForAccessibleEventsInContainer( TypePossiblyContainingEvents, TypeOfWithEventsVar, ConsiderEventSourcePropertiesToo, AnyEventDefined); } return false; }