Ejemplo n.º 1
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;
}
bool CLSComplianceChecker::IsTypeCLSCompliant(
    BCSYM * RawType,
    BCSYM_NamedRoot * NamedContext)
{
    BCSYM *ActualType = RawType->ChaseToType();

    if (!ActualType ||
        (ActualType->IsNamedRoot() &&
         ActualType->PNamedRoot()->IsBadNamedRoot()))
    {
        return true;
    }

    // Return true for generic params because its constraints are anyway verified separately
    //
    if (ActualType->IsGenericParam())
    {
        return true;
    }

    VSASSERT( ActualType->IsContainer(),
                    "What else can a chased type be ?");

    if (ActualType->IsGenericBinding())
    {
        NameTypeArguments **RawTypeArgumentsSets =
            RawType->IsNamedType() ? RawType->PNamedType()->GetArgumentsArray() : NULL;

        unsigned CountOfRawTypeArgumentsSets =
            RawType->IsNamedType() ? RawType->PNamedType()->GetNameCount() : 0;

        NameTypeArguments *CurrentRawTypeArgumentsSet = NULL;
        unsigned CurrentRawTypeArgumentsSetIndex = CountOfRawTypeArgumentsSets;

        for(BCSYM_GenericTypeBinding *GenericBinding = ActualType->PGenericTypeBinding();
            GenericBinding;
            GenericBinding = GenericBinding->GetParentBinding())
        {
            if (RawTypeArgumentsSets && CurrentRawTypeArgumentsSetIndex > 0)
            {
                CurrentRawTypeArgumentsSet = RawTypeArgumentsSets[--CurrentRawTypeArgumentsSetIndex];

                if (CurrentRawTypeArgumentsSet &&
                    CurrentRawTypeArgumentsSet->m_BoundGenericBinding != GenericBinding)
                {
                    // Lost the one to one mapping between actual type and raw type, so
                    // invalidate and do not use the raw type argument locations.

                    CurrentRawTypeArgumentsSet = NULL;
                }
            }

            unsigned GenericArgumentCount = GenericBinding->GetArgumentCount();
            for(unsigned Index = 0; Index < GenericArgumentCount; Index++)
            {
                BCSYM *ArgumentType = GenericBinding->GetArgument(Index);

                if (!IsTypeCLSCompliant(ArgumentType, NamedContext))
                {
                    Location *ErrorLocation = NULL;

                    if (CurrentRawTypeArgumentsSet &&
                        CurrentRawTypeArgumentsSet->m_ArgumentCount > 0)
                    {
                        ErrorLocation = CurrentRawTypeArgumentsSet->GetArgumentLocation(Index);
                    }

                    if (!ErrorLocation)
                    {
                        ErrorLocation =
                            RawType->IsNamedType() ?
                                RawType->GetLocation() :
                                NamedContext->GetLocation();
                    }

                    ReportErrorAtLocation(
                        WRNID_TypeNotCLSCompliant1,
                        ErrorLocation,
                        NamedContext,
                        ArgumentType->ChaseToType()->GetErrorName(m_Compiler));
                }
            }
        }

        return IsTypeCLSCompliant(ActualType->PGenericTypeBinding()->GetGeneric(), NamedContext);
    }

    return ActualType->PContainer()->IsCLSCompliant();
}