BCSYM_Property* Bindable::GetWithEventsPropertyForWithEventsVariable ( BCSYM_Variable *WithEventsVar ) { BCSYM_NamedRoot *PossibleWithEventsProperty = CurrentContainer()->SimpleBind( NULL, WithEventsVar->GetName()); while (PossibleWithEventsProperty && !(PossibleWithEventsProperty->IsProperty() && PossibleWithEventsProperty->CreatedByWithEventsDecl() == WithEventsVar)) { PossibleWithEventsProperty = PossibleWithEventsProperty->GetNextOfSameName(); } return PossibleWithEventsProperty->PProperty(); }
BCSYM_Variable* Bindable::BindWithEventsVariable ( _In_z_ STRING *WithEventVarName, bool &InAccessible, bool &WithEventsVarFoundInBase ) { InAccessible = false; WithEventsVarFoundInBase = false; VSASSERT( CurrentContainer()->IsClass(), "How can a non-class have handles clauses ?"); BCSYM_Class *Class = CurrentContainer()->PClass(); bool IsShadowed = false; BCSYM_NamedRoot *Member; for(Member = Class->SimpleBind(NULL, WithEventVarName); Member; Member = Member->GetNextOfSameName()) { if (Member->IsVariable() && Member->PVariable()->GetVarkind() == VAR_WithEvents) { return Member->PVariable(); } // Ignore synthesized properties in checking for shadowing. if (!Member->CreatedByWithEventsDecl() || !Member->IsProperty()) { IsShadowed = true; } } for(BCSYM_Class *Base = Class->GetCompilerBaseClass(); !IsShadowed && Base; Base = Base->GetCompilerBaseClass()) { for(Member = Base->SimpleBind(NULL, WithEventVarName); Member; Member = Member->GetNextOfSameName()) { if (Member->IsVariable() && Member->PVariable()->GetVarkind() == VAR_WithEvents) { if (IsAccessible(Member)) { WithEventsVarFoundInBase = true; return Member->PVariable(); } InAccessible = true; } else { if (IsAccessible(Member) && // Ignore synthesized properties in checking for shadowing. (!Member->CreatedByWithEventsDecl() || !Member->IsProperty())) { IsShadowed = true; } } } } return NULL; }
BCSYM_Property* Bindable::GetEventSourceProperty ( BCSYM *TypeOfWithEventsVar, _In_z_ STRING *PropertyName ) { // Need to find a property that sources an event // To handle events on subobjects, (internal use only), you must supply a Class // type for the WithEvents variable. But for completeness with respect to generics, // adding support type parameters with class constraints too. BCSYM *TypeToFindEventSourcePropertyIn; if (TypeOfWithEventsVar->IsGenericParam()) { // TypeToFindEventSourcePropertyIn = GetClassConstraint( TypeOfWithEventsVar->PGenericParam(), CurrentCompilerHost(), CurrentAllocator(), false, // don't ReturnArraysAs"System.Array" true // ReturnValuesAs"System.ValueType"or"System.Enum" ); } else { TypeToFindEventSourcePropertyIn = TypeOfWithEventsVar; } if (!TypeToFindEventSourcePropertyIn || !TypeToFindEventSourcePropertyIn->IsClass()) { return NULL; } // ---- attributes on all symbols in the TypeOfWithEventsVar container. This is needed // in order to verify if a property is an EventSource which is determined by // an attribute on the property. // ----AttributesOnAllSymbolsInContainer(TypeToFindEventSourcePropertyIn->PClass(), m_CompilationCaches); BCSYM_NamedRoot *Property = TypeToFindEventSourcePropertyIn->PClass()->SimpleBind(NULL, PropertyName); while (Property && Property->IsProperty()) { if (ValidEventSourceProperty(Property->PProperty()) && IsAccessible( Property->PProperty()->GetProperty(), TypeToFindEventSourcePropertyIn->IsGenericBinding() ? TypeToFindEventSourcePropertyIn->PGenericBinding() : NULL, CurrentContainer(), TypeOfWithEventsVar)) { return Property->PProperty(); // found it } Property = Property->GetNextOfSameName(); // Note: // - we don't support finding the Property if it is overloaded // across classes. // - Also note that we don't support digging into bases. This was // how the previous impl. was. // Given that this is not a user feature, we don't bother doing // this extra work. } return NULL; }