Example #1
0
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;
}
Example #2
0
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);

}