bool TypeExtensionIterator::MoveNext() { BCSYM_NamedRoot * pNamed = NULL; do { pNamed = m_childIterator.GetNext(); if (pNamed && pNamed->IsContainer()) { BCSYM_Container *pContainer = pNamed->PContainer(); // Perf: We are only interested in looking at types marked as containing extension methods. So only load the // type's children if the type says it contains extension methods. BCSYM *pContainerAfterDiggingThroughAlias = pContainer->DigThroughAlias(); if (pContainerAfterDiggingThroughAlias->IsClass()) { if (pContainerAfterDiggingThroughAlias->PClass()->ContainsExtensionMethods()) { pContainer->EnsureChildrenLoaded(); } } else if (!pContainer->GetCompilerFile() || (pContainer->GetCompilerFile()->IsMetaDataFile() && pContainer->GetCompilerFile()->ContainsExtensionMethods())) { pContainer->EnsureChildrenLoaded(); } } } while (pNamed && ! pNamed->IsTypeExtension()); if (pNamed) { m_pCurrent = pNamed->PClass(); } else { m_pCurrent = NULL; } return m_pCurrent; }
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; }
void CLSComplianceChecker::VerifyProcForCLSCompliance( BCSYM_Proc * Proc, BCSYM_Container * ParentOfProc) { // We won't do CLS Compliance checking on BeginInvoke or EndInvoke (only Invoke) to avoid // duplicating our efforts. // if (ParentOfProc->IsDelegate() && (ParentOfProc->SimpleBind(NULL, STRING_CONST(m_Compiler, DelegateBeginInvoke)) == Proc || ParentOfProc->SimpleBind(NULL, STRING_CONST(m_Compiler, DelegateEndInvoke)) == Proc)) { return; } // Event specific validation // if (Proc->IsEventDecl()) { BCSYM_EventDecl *Event = Proc->PEventDecl(); BCSYM *RawDelegate = Event->GetRawDelegate(); BCSYM *Delegate = Event->GetDelegate(); VSASSERT(!(Event->AreParametersObtainedFromDelegate() && Event->IsDelegateFromImplements()), "Event parameters obtained from the implemented event's delegate - unexpected!!!"); // The event's delegate also needs to be validated, but only when it is not the implicitly // generated delegate of this event. // if (Delegate && Delegate->IsDelegate() && Delegate->PClass()->CreatedByEventDecl() != Event) { // If this asserts fails, this can possibly cause duplicate errors for type arguments // of the delegate and also for errors to be reported at the wrong locations. // VSASSERT(RawDelegate->IsNamedType() || Event->IsDelegateFromImplements(), "Event delegate should not be the raw delegate type of the implemented event!!!"); if (!IsTypeCLSCompliant(RawDelegate, Event)) { ReportErrorOnSymbol( WRNID_EventDelegateTypeNotCLSCompliant2, RawDelegate->IsNamedType() ? RawDelegate : Event, Event, Delegate->PClass()->GetQualifiedName(true, ParentOfProc), Event->GetName()); } } // If the event's parameters are obtained from its delegate, then its parameters should not // be checked here because they will be validated when the delegate itself is checked. // if (Event->AreParametersObtainedFromDelegate()) { return; } } // Check the return type. // if (!IsTypeCLSCompliant(Proc->GetRawType(), Proc)) { ReportErrorOnSymbol( WRNID_ProcTypeNotCLSCompliant1, Proc, Proc->GetName()); } // Check the parameters. // for(BCSYM_Param *Param = Proc->GetFirstParam(); Param; Param = Param->GetNext()) { if (!IsTypeCLSCompliant(Param->GetRawType(), Proc)) { ReportErrorOnSymbol( WRNID_ParamNotCLSCompliant1, Param, Proc, Param->GetName()); } else if (Param->IsOptional() && Param->IsParamWithValue()) { BCSYM_Expression *OptionalValue = Param->PParamWithValue()->GetExpression(); if (OptionalValue && // SByte, UInt16, Uint32, Uint64 constants are not CLS compliant // (OptionalValue->GetValue().TypeCode == t_i1 || OptionalValue->GetValue().TypeCode == t_ui2 || OptionalValue->GetValue().TypeCode == t_ui4 || OptionalValue->GetValue().TypeCode == t_ui8)) { ReportErrorOnSymbol( WRNID_OptionalValueNotCLSCompliant1, Param->PParamWithValue()->GetExpression()->HasLocation() ? (BCSYM *)Param->PParamWithValue()->GetExpression() : Param, Proc, Param->GetName()); } } } VerifyOverloadsForCLSCompliance(Proc); VerifyConstraintsAreCLSCompliant(Proc); }