コード例 #1
0
void CompileableMethodsInAContainer::Init
(
    BCSYM_Container *pContainer,
    bool fLookOnlyInCurrentPartialType
)
{
    // Free the memory.
    m_nra.FreeHeap();

    if (pContainer != NULL)
    {
        // Look in only this container and ignore its other partial containers
        //
        BCITER_CHILD_ALL bichild(pContainer, fLookOnlyInCurrentPartialType);

        unsigned cMethods = 0;
        BCSYM_NamedRoot *pRoot;
        BCSYM_Proc **ppProc;

        while (pRoot = bichild.GetNext())
        {
            if (pRoot->IsMethodImpl() ||
                    pRoot->IsSyntheticMethod() ||
                    pRoot->IsProperty() ||
                    pRoot->IsEventDecl())
            {
                cMethods++;
            }
        }

        IfFalseThrow(cMethods + 1 > cMethods);
        ppProc = m_ppNext = (BCSYM_Proc **)m_nra.Alloc(VBMath::Multiply(
            (cMethods + 1), 
            sizeof(BCSYM_Proc *)));

        bichild.Reset();

        while (pRoot = bichild.GetNext())
        {
            if (pRoot->IsMethodImpl() ||
                    pRoot->IsSyntheticMethod() ||
                    pRoot->IsProperty() ||
                    pRoot->IsEventDecl())
            {
                *ppProc = pRoot->PProc();
                ppProc++;
            }
        }

        // Sort the list in file definition order.
        extern int _cdecl SortSymbolsByLocation(const void *arg1, const void *arg2);

        qsort(m_ppNext, ppProc - m_ppNext, sizeof(BCSYM_Proc *), SortSymbolsByLocation);
    }
    else
    {
        m_ppNext = NULL;
    }
}
コード例 #2
0
void CLSComplianceChecker::VerifyOverloadsForCLSCompliance(BCSYM_Proc * PossiblyOverloadedProc)
{
    // Check the Overloads for overloading by Array Rank or
    // overloading on Array of Arrays

    // we don't allow bad members because they could have
    // been bad during overloads verification in bindable.
    //
    VSASSERT( !PossiblyOverloadedProc->IsBad(),
                    "Bad members unexpected!!!");

    if (!Bindable::IsMethod(PossiblyOverloadedProc) &&
        !Bindable::IsProperty(PossiblyOverloadedProc))
    {
        return;
    }

    for(BCSYM_NamedRoot *NextPossibleOverload = PossiblyOverloadedProc->GetNextOverload();
        NextPossibleOverload;
        NextPossibleOverload = NextPossibleOverload->GetNextOverload())
    {
        VSASSERT( NextPossibleOverload->IsProc(),
                    "How can a non-proc be involved in overloads ?");

        BCSYM_Proc *NextOverload = NextPossibleOverload->PProc();

        if (!IsAccessibleOutsideAssembly(NextOverload))
        {
            continue;
        }

        VerifyOverloadsForCLSCompliance(
            PossiblyOverloadedProc,
            NextOverload);
    }

    // 














}
コード例 #3
0
BCSYM_Property * PublicReadablePropertiesIterator::Next()
{
    BCSYM_NamedRoot * pNamedRoot = NULL;
    while
    (
        (pNamedRoot = m_childIterator.GetNext()) &&
        (
            ! pNamedRoot->IsProperty() ||
            pNamedRoot->GetAccess() != ACCESS_Public ||
            pNamedRoot->PProperty()->IsWriteOnly()
        )
    )
    {
    }

    return pNamedRoot ? pNamedRoot->PProperty() : NULL;
}
コード例 #4
0
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();
}
コード例 #5
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;
}
コード例 #6
0
DLRExpressionTree*
ETSemanticsForLambdas::ConvertLambda
(
    ILTree::Expression* Input,
    ExpressionFlags Flags,
    Type* TargetType
)
{
    ThrowIfNull(Input);
    ThrowIfFalse(Input->bilop == SX_LAMBDA);

    // Don't allow Sub lambdas to be converted to expression trees.
    if (Input->ResultType->IsDelegate())
    {
        BCSYM_NamedRoot* proc = GetInvokeFromDelegate(Input->ResultType, m_Compiler);
        if(proc && proc->PProc() && (!proc->PProc()->GetType() || TypeHelpers::IsVoidType(proc->PProc()->GetType())))
        {
            ReportErrorForExpressionTree( ERRID_StatementLambdaInExpressionTree, Input->Loc );
            return NULL;
        }
    }

    return ExpressionTreeSemantics<DLRExpressionTree>::ConvertLambda(Input, Flags, TargetType);
}
コード例 #7
0
BCSYM_Container *AllContainersInFileIterator::Next()
{
    BCSYM_NamedRoot *pDug;

    while(m_pNext)
    {
        pDug = m_pNext->DigThroughAlias()->PNamedRoot();

        m_pNext = m_pNext->GetNextInSymbolList();

        if (!m_fIncludeTransientSymbols && pDug->IsTransient())
        {
            continue;
        }

        if (pDug->IsContainer() &&
            (m_fIncludePartialContainers || !pDug->PContainer()->IsPartialTypeAndHasMainType()))
        {
            return pDug->PContainer();
        }
    }

    return NULL;
}
コード例 #8
0
/*****************************************************************************
;ValidateHandlesLists

Given Method() Handles X1.SomeEvent

    1. verify that X1 is a valid WithEvents variable
    2. verify that X1 sources SomeEvent()
*****************************************************************************/
void
Bindable::ValidateAndHookUpHandles
(
    BCSYM_HandlesList *HandlesEntry,
    BCSYM_MethodImpl *HandlingMethod
)
{
    VSASSERT( !HandlesEntry->IsBad(), "Bad handles unexpected here!!");
    VSASSERT( CurrentContainer()->IsClass(),
                    "Non-classes/non-structures/non-modules cannot have handles clauses!!");

    // Dev10#489103: if the handling method is bad, then we can't really tell whether it handles the event:
    if (HandlingMethod->IsBadParamTypeOrReturnType())
    {
        HandlesEntry->SetIsBad();
        return;
    }

    Symbols
        SymbolFactory(
            CurrentCompilerInstance(),
            CurrentAllocator(),
            NULL,
            CurrentGenericBindingCache());

    BCSYM_Class *ContainerOfHandlingMethod = CurrentContainer()->PClass();

    BCSYM *TypeToFindEventIn;
    BCSYM_Property *EventSourceProperty = NULL;
    BCSYM_Property *WithEventsProperty;
    BCSYM *InstanceTypeThroughWhichEventIsAccessed;

    if (HandlesEntry->IsMyBase())
    {
        TypeToFindEventIn = TypeHelpers::GetBaseClass(ContainerOfHandlingMethod, SymbolFactory);

        // A bad base is no base
        if (!TypeToFindEventIn)
        {
            HandlesEntry->SetIsBad();
            return;
        }

        InstanceTypeThroughWhichEventIsAccessed = ContainerOfHandlingMethod;
    }
    else if (HandlesEntry->IsEventFromMeOrMyClass())
    {
        if (ContainerOfHandlingMethod->IsGeneric())
        {
            TypeToFindEventIn =
                SynthesizeOpenGenericBinding(
                    ContainerOfHandlingMethod,
                    SymbolFactory);
        }
        else
        {
            TypeToFindEventIn = ContainerOfHandlingMethod;
        }

        InstanceTypeThroughWhichEventIsAccessed = ContainerOfHandlingMethod;
    }
    else
    {
        WithEventsProperty = HandlesEntry->GetWithEventsProperty();

        VSASSERT( WithEventsProperty,
                        "How can a non-bad handles entry not have a withevents property ?");

        BCSYM_Variable *WithEventsVar = WithEventsProperty->CreatedByWithEventsDecl();

        VSASSERT( WithEventsVar,
                        "How can a non-bad handles entry not refer to a withevents var ?");

        if (WithEventsVar->IsBad() ||
            WithEventsVar->IsBadVariableType())
        {
            HandlesEntry->SetIsBad();
            return;
        }

        BCSYM *TypeOfWithEventsVar = WithEventsProperty->GetType();

        VSASSERT( TypeOfWithEventsVar->IsContainer() ||
                  (TypeOfWithEventsVar->IsGenericParam() &&
                        TypeOfWithEventsVar->PGenericParam()->IsReferenceType()),
                            "What else can the type of a withevents variable be ?");

        if (HandlesEntry->GetEventSourcePropertyName())
        {
            // If withevents variable type is type parameter, then search in its class constraint,
            // else search in the withevents variable type itself.
            //
            EventSourceProperty =
                GetEventSourceProperty(
                    TypeOfWithEventsVar,
                    HandlesEntry->GetEventSourcePropertyName());

            if (!EventSourceProperty)
            {
                // "'Handles' must specify a 'WithEvents' variable or 'MyBase' qualified with a single identifier."

                ReportErrorOnSymbol(
                    IsStdModule(CurrentContainer()) ?
                        ERRID_HandlesSyntaxInModule :
                        ERRID_HandlesSyntaxInClass,
                    CurrentErrorLog(HandlingMethod),
                    HandlesEntry);

                HandlesEntry->SetIsBad();
                return;
            }

            // 






            HandlesEntry->SetEventSourceProperty(EventSourceProperty);

            // 


            VSASSERT( EventSourceProperty->GetType()->IsContainer(),
                            "Referring Property - What else can a type that is not a named type be ?");

            TypeToFindEventIn = EventSourceProperty->GetType();
        }
        else
        {
            TypeToFindEventIn = TypeOfWithEventsVar;
        }

        InstanceTypeThroughWhichEventIsAccessed = TypeToFindEventIn;
    }

    VSASSERT( TypeToFindEventIn, "No type to find the event in ?");

    bool IsBadName;
    BCSYM_NamedRoot *EventDecl =
        Semantics::EnsureNamedRoot
        (
            Semantics::InterpretName
            (
                HandlesEntry->GetEventName(),
                *(HandlesEntry->GetLocationOfEvent()),
                TypeToFindEventIn->IsContainer() ?
                    TypeToFindEventIn->PContainer()->GetHash() :
                    NULL,
                TypeToFindEventIn->IsGenericParam() ?
                    TypeToFindEventIn->PGenericParam() :
                    NULL,
                NameSearchIgnoreParent | NameSearchEventReference | NameSearchIgnoreExtensionMethods,
                InstanceTypeThroughWhichEventIsAccessed,
                ContainerOfHandlingMethod->GetHash(),     // Current Context
                CurrentErrorLog(HandlingMethod),
                CurrentCompilerInstance(),
                CurrentCompilerHost(),
                m_CompilationCaches,
                CurrentSourceFile(HandlingMethod),
                false,                                    // don't perform obsolete checks
                IsBadName,
                NULL,   // the binding context is not required here since the synthesized
                        // code has the withevents variable from which the type binding
                        // information is obtained
                NULL,
                -1
            )
        );


    if (IsBadName)
    {
        HandlesEntry->SetIsBad();
        return;
    }

    if (!EventDecl || !EventDecl->IsEventDecl())
    {
        ReportErrorAtLocation(
            ERRID_EventNotFound1,
            CurrentErrorLog(HandlingMethod),
            HandlesEntry->GetLocationOfEvent(),
            HandlesEntry->GetEventName());

        HandlesEntry->SetIsBad();
        return;
    }

    if (EventDecl->IsBad())
    {
        HandlesEntry->SetIsBad();
        return;
    }


    BCSYM_EventDecl *Event = EventDecl->PEventDecl();
    HandlesEntry->SetEvent(Event);

    // [....] - 11/17/2005
    // See Bug # 544269
    // The call to ResolveAllNamedTypesForContainer needed to be replaced with a call
    // to ResolveShadowingOverloadingAndOverridingForContainer because event signatures
    // are not necessarily setup untill after ResolveShadowingOverloadingAndOverriding
    // has been called.

    // Go and bind the event we are comparing against up to the state we need for
    // validating handles.
    ResolveShadowingOverloadingOverridingAndCheckGenericsForContainer(Event->GetContainer(), m_CompilationCaches);


    // Check for bad param types here (VSW#172753).
    if (Event->GetDelegate() &&
        Event->GetDelegate()->IsContainer() &&
        DefinedInMetaData(Event->GetDelegate()->PContainer()))
    {
        for (BCSYM_Param *Param = Event->GetFirstParam();
             Param;
             Param = Param->GetNext())
        {
            if (Param->GetType()->IsBad())
            {
                Param->GetType()->PNamedRoot()->ReportError(
                    CurrentCompilerInstance(),
                    CurrentErrorLog(HandlingMethod),
                    HandlesEntry->GetLocationOfEvent());

                HandlesEntry->SetIsBad();
                return;
            }
        }
    }

    BCSYM_GenericBinding *EventGenericBindingContext =
        DeriveGenericBindingForMemberReference(TypeToFindEventIn, Event, SymbolFactory, CurrentCompilerHost());

   MethodConversionClass MethodConversion = Semantics::ClassifyMethodConversion(
            HandlingMethod,
            GenericBindingInfo(),
            Event,
            EventGenericBindingContext,
            false, //IgnoreReturnValueErrorsForInference
            &SymbolFactory,
            CurrentCompilerHost());

    SourceFile * SourceFile = HandlingMethod->GetSourceFile();

    if (!Semantics::IsSupportedMethodConversion(
            SourceFile->GetOptionFlags() & OPTION_OptionStrict,
            MethodConversion))
    {
        // "Method '|1' cannot handle Event '|2' because they do not have the same signature."

        StringBuffer HandlingMethodRepresentation;
        HandlingMethod->GetBasicRep(CurrentCompilerInstance(), NULL, &HandlingMethodRepresentation);

        StringBuffer EventRepresentation;
        Event->GetBasicRep(CurrentCompilerInstance(), NULL, &EventRepresentation, EventGenericBindingContext);

        ReportErrorAtLocation(
            ERRID_EventHandlerSignatureIncompatible2,
            CurrentErrorLog(HandlingMethod),
            HandlesEntry->GetLocationOfEvent(),
            HandlingMethodRepresentation.GetString(),
            EventRepresentation.GetString());

        HandlesEntry->SetIsBad();
        return;
    }

    // Hook up handlers to the events they specify in their handles clauses

    if (HandlesEntry->IsMyBase() ||
        HandlesEntry->IsEventFromMeOrMyClass())
    {
        // For these cases, we search for valid MyBase, Me, MyClass handles clauses and set up the
        // addhandlers in all constructors that directly call a base constructor. This is done in
        // semantics in initializefields because that is when the information whether it directly
        // calls the base constructor is known.
        //

        const bool BuildSharedConstructor = true;

        if (HandlesEntry->GetEvent()->IsShared() &&
            HandlingMethod->IsShared())
        {
            // Make sure a shared constructor is present, else synthesize one

            if (!ContainerOfHandlingMethod->GetSharedConstructor(CurrentCompilerInstance()))
            {
                // Synthesize one
                SynthesizeConstructor(BuildSharedConstructor);
            }
        }
        else
        {
            // Make sure an Instance constructor is present, else synthesize one

            if (!ContainerOfHandlingMethod->GetFirstInstanceConstructor(CurrentCompilerInstance()))
            {
                // Synthesize one
                SynthesizeConstructor(!BuildSharedConstructor);
            }
        }
    }
    else
    {
        VSASSERT( WithEventsProperty->SetProperty(),
                        "How can there be no set accessor for a withevents property ?");


        if (WithEventsProperty->IsShared() &&
            !HandlingMethod->IsShared())
        {
            // "Events of shared WithEvents variables cannot be handled by non-shared methods."

            ReportErrorAtLocation(
                ERRID_SharedEventNeedsSharedHandler,
                CurrentErrorLog(HandlingMethod),
                HandlesEntry->GetLocationOfWithEventsVar());

            HandlesEntry->SetIsBad();
            return;
        }

        // 

        // hookup the handler list info for the above handles entry on to the WithEvents_Set.
        // GenWithEventsSetCode() will write synthetic code for these later
        //
        WithEventsProperty->SetProperty()->AddToHandlerList(
            HandlingMethod,
            Event,
            EventGenericBindingContext,
            EventSourceProperty,
            CurrentAllocator());

    }
}
コード例 #9
0
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;
}
コード例 #10
0
bool
Bindable::CheckForAccessibleEventsWorker
(
    BCSYM *TypePossiblyContainingEvents,
    BCSYM *TypeOfWithEventsVar,
    MembersHashTable *ShadowingMembers,
    bool ConsiderEventSourcePropertiesToo,
    bool &AnyEventDefined
)
{
    VSASSERT( TypePossiblyContainingEvents->IsContainer(),
                    "Looking for events in non-container unexpected!!!");

    // 


    // ---- attributes on all symbols in the EventDecl container. This is needed
    // in order to verify if a property is an EventSource which is determined by
    // an attribute on the property.
    //
    if (ConsiderEventSourcePropertiesToo)
    {
        ----AttributesOnAllSymbolsInContainer(TypePossiblyContainingEvents->PContainer(), m_CompilationCaches);
    }

    BCITER_CHILD ContainerIterator;
    ContainerIterator.Init(TypePossiblyContainingEvents->PContainer());

    for(BCSYM_NamedRoot *EventDecl = ContainerIterator.GetNext();
        EventDecl != NULL;
        EventDecl = ContainerIterator.GetNext())
    {
        // Was the event decl we just found shadowed out by somebody on a nearer base class/interface?
        //
        if (IsMemberShadowed(EventDecl, ShadowingMembers))
            continue;

        bool IsMemberAccessible =
            IsAccessible(
                EventDecl,
                TypePossiblyContainingEvents->IsGenericBinding() ?
                    TypePossiblyContainingEvents->PGenericBinding() :
                    NULL,
                CurrentContainer(),
                TypeOfWithEventsVar);

        // Keep track of who is shadowing in this container - we'll need the info if the event we find is on a derived container
        if (IsMemberAccessible && EventDecl->IsShadowing())
        {
            ShadowingMembers->Add(EventDecl);
        }

        if (ConsiderEventSourcePropertiesToo &&
            EventDecl->IsProperty() &&
            ValidEventSourceProperty(EventDecl->PProperty()))
        {
            IsMemberAccessible =
                IsMemberAccessible &&
                IsAccessible(
                    EventDecl->PProperty()->GetProperty(),
                    TypePossiblyContainingEvents->IsGenericBinding() ?
                        TypePossiblyContainingEvents->PGenericBinding() :
                        NULL,
                    CurrentContainer(),
                    TypeOfWithEventsVar);

            BCSYM *PropertyReturnType = EventDecl->PProperty()->GetType();

            // 


            // We only care about properties returning classes or interfaces
            // because only classes and interfaces can be specified in a
            // handles clause.
            //

            VSASSERT(IsClassOrInterface(PropertyReturnType),
                        "Invalid event source property found. Should have been disallowed earlier!!!");

            // We've come across a Property that returns an Event source.  Dig through it.
            //
            if (CheckForAccessibleEvents(
                    PropertyReturnType,                // Property return type
                    false,                             // i.e. don't consider EventSource properties, because
                                                       //    we only allow at most 3 names i.e. x.y.z in the
                                                       //    handles clause and and only y is allowed to be the
                                                       //    referring event source property.
                    AnyEventDefined))
            {
                // there are events on this WithEvents variable - and they are accessible
            }
            else
            {
                continue;
            }
        }
        else if (EventDecl->IsEventDecl())
        {
            // there are events on this WithEvents variable - whether they are accessible is another matter
            //
            AnyEventDefined = true;
        }
        else
        {
            // Screen out everthing that isn't an Event declaration or possible Event Source
            //
            continue;
        }

        // This assert will guard against any bad changes to the conditions checks above
        VSASSERT( AnyEventDefined,
                        "How can we get here when we have not found any event or event source ?");

        // Determine if the event is accessible
        // It must be visible to the WithEvents container that references the event
        //
        if (IsMemberAccessible)
        {
            return true;
        }

    } // trawl container members looking for events/properties that may return events


    // Look recursively in bases too
    BasesIter Bases(TypePossiblyContainingEvents->PContainer());

    BCSYM_GenericTypeBinding *BaseGenericBinding;
    while (BCSYM_Container *Base = Bases.GetNextBase(&BaseGenericBinding))
    {
        if (Base->IsBad()) continue;

        if (CheckForAccessibleEventsWorker(
                BaseGenericBinding ?
                    (BCSYM *)BaseGenericBinding :
                    Base,
                TypeOfWithEventsVar,
                ShadowingMembers,
                false,  // Don't consider event source properties in based as available
                        // because we don't allow binding to them in the handles clause
                        // (for no other better reason than leaving this implementation
                        //  as it was without complicating things, since this is not a
                        //  user feature anyway.)
                AnyEventDefined))
        {
            return true;
        }
    }

    return false; // no visible events found
}
コード例 #11
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;
}
コード例 #12
0
ファイル: linemarkertable.cpp プロジェクト: JianwenSun/cc
void LineMarkerTable::UpdateTrackedLocation(
    VBTextBuffer * pVBTextBuffer,
    TrackedLocation * ploc)
{
    VSASSERT(pVBTextBuffer && ploc, L"Bad input");
    VSASSERT(ploc->fIsChanged, L"LineMarkerTable::UpdateTrackedLocation() only takes locations that have been changed!");

    TrackedLocation locCache = *ploc;

    // Here is a list of bugs that we've had in previous code, we should regress against these
    // bugs when changes are made here.
    // VS#302006, VS#305056, VS#305847, VS#243392, VS#180674, VS#186022, VS#238616, VS#192462, VS#262018, VS#544586, VS#543103, VS#545446, VS#545457

    VSASSERT(ploc->m_oBegin >= 0, L"Invalid Begin offset");
    VSASSERT(ploc->m_oEnd >= ploc->m_oBegin, L"Invalid End offset");

    if (ploc->m_oBegin == 0)
    {
        ploc->m_lBegLine   = 0;
        ploc->m_lBegColumn = 0;
    }
    else
    {
        ploc->UpdateStartLineAndColumn(pVBTextBuffer);
    }

    if (ploc->m_oEnd == 0)
    {
        ploc->m_lEndLine   = 0;
        ploc->m_lEndColumn = 0;
    }
    else
    {
        ploc->UpdateEndLineAndColumn(pVBTextBuffer);
    }

    // And Update the symbols hash table as needed too.
#if DEBUG
    ploc->DebCheck();   // Make sure that the lines and columns are all good.

    if (VBFTESTSWITCH(fDebugLineMark))
    {
        DebPrintf("Location was moved From ((%3d, %3d),(%3d, %3d)) ", locCache.m_lBegLine, locCache.m_lBegColumn, locCache.m_lEndLine, locCache.m_lEndColumn);
        DebPrintf("To ((%3d, %3d),(%3d, %3d))", ploc->m_lBegLine, ploc->m_lBegColumn, ploc->m_lEndLine, ploc->m_lEndColumn);
    }
#endif DEBUG

    if (ploc->fIsInSourceFileHashTable == true)
    {
        // The sourcefile has a hash table of symbols that are hashed based on their
        // location. We need to update the hash table accroding to the new location
        // info for the symbols.

        // Remove the symbol from the hash table and hold on to the symbol
        BCSYM_NamedRoot *SymbolToUpdate = m_pSourceFile->RemoveSymbolFromHashTable(&locCache);
        VSASSERT(ploc->m_pSymbolForLocation == SymbolToUpdate, L"Two different symbols?");

        // Re-add the symbol back to the hash table with the new location.
        // This should add the symbol to the tail of the list of symbols
        // in one hash bucket. See VS213488
        if (SymbolToUpdate && ploc->IsValid())
        {
            m_pSourceFile->AddSymbolToHashTable((Location *) ploc, SymbolToUpdate);
        }

#if DEBUG
        if (VBFTESTSWITCH(fDebugLineMark))
        {
            if (ploc->m_locType == CodeBlockLoc)
            {
                DebPrintf(" (%S) ", ((TrackedCodeBlock *)ploc)->fProcBlock == true ? L"pTrackedProcBlock" : L"pTrackedCodeBlock");
            }

            DebPrintf(" \"%S\" (In HashTable)\n", (SymbolToUpdate && SymbolToUpdate->IsNamedRoot())? SymbolToUpdate->PNamedRoot()->GetName() : L"");
        }
#endif DEBUG
    }
    else
    {
#if DEBUG
        if (VBFTESTSWITCH(fDebugLineMark))
        {
            if (ploc->m_locType == CodeBlockLoc)
            {
                DebPrintf(" (%S) ", ((TrackedCodeBlock *)ploc)->fProcBlock == true ? L"pTrackedProcBlock" : L"pTrackedCodeBlock");
            }

            DebPrintf(" \"%S\" (Not In HashTable)\n", (ploc->m_pSymbolForLocation && ploc->m_pSymbolForLocation->IsNamedRoot())?  ploc->m_pSymbolForLocation->PNamedRoot()->GetName() : L"");
        }
#endif DEBUG
    }
}
コード例 #13
0
void ComClassMembersInAContainer::Init
(
    BCSYM_Container *pContainer
)
{
    // Free the memory.
    m_nra.FreeHeap();

    if (pContainer != NULL)
    {
        BCITER_CHILD bichild(pContainer);
        unsigned cMembers = 0;
        BCSYM_NamedRoot *pRoot;
        BCSYM_NamedRoot **ppRoot;

        while (pRoot = bichild.GetNext())
        {
            if (!Filter(pRoot))
                continue;

            cMembers++;

            if (pRoot->IsProperty())
            {
                BCSYM_Property *pProperty = pRoot->PProperty();

                if (pProperty->GetProperty() && Filter(pProperty->GetProperty()))
                {
                    cMembers++;
                }
                if (pProperty->SetProperty() && Filter(pProperty->SetProperty()))
                {
                    cMembers++;
                }
            }
        }

        IfFalseThrow(cMembers + 1 > cMembers);
        ppRoot = m_ppRoot = m_ppNext = (BCSYM_NamedRoot **)m_nra.Alloc(VBMath::Multiply(
            (cMembers + 1), 
            sizeof(BCSYM_NamedRoot *)));
        m_count = cMembers;

        bichild.Init(pContainer);

        while (pRoot = bichild.GetNext())
        {
            if (!Filter(pRoot))
                continue;

            *ppRoot = pRoot;
            ppRoot++;

            if (pRoot->IsProperty())
            {
                BCSYM_Property *pProperty = pRoot->PProperty();

                if (pProperty->GetProperty() && Filter(pProperty->GetProperty()))
                {
                    *ppRoot = pProperty->GetProperty();
                    ppRoot++;
                }
                if (pProperty->SetProperty() && Filter(pProperty->SetProperty()))
                {
                    *ppRoot = pProperty->SetProperty();
                    ppRoot++;
                }
            }
        }

        // Sort the list in slot number then file definition order.
        extern int _cdecl SortSymbolsByLocation(const void *arg1, const void *arg2);

        qsort(m_ppNext, ppRoot - m_ppNext, sizeof(BCSYM_NamedRoot *), SortSymbolsByLocation);
    }
    else
    {
        m_count = 0;
        m_ppNext = NULL;
        m_ppRoot = NULL;
    }
}