/// <summary>
        ///     A method that gets called for each event definition in analyzed assembly.
        /// </summary>
        /// <param name="member">
        ///     An object that represents an event.
        /// </param>
        public override void VisitEvent(Event member)
        {
            this.visitedMembers.Push(member);

            base.VisitEvent(member);

            this.visitedMembers.Pop();
        }
Example #2
0
        public static Event[] GetImplementedEvents(Event trigger) {
            List < Event > list = new List < Event >();

            // get the adder
            Method adder = trigger.HandlerAdder;

            // get interface methods corresponding to this adder
            Method[] implementedAdders = GetImplementedMethods(adder);

            // get the events corresponding to the implemented adders
            foreach (Method implementedAdder in implementedAdders) {
                Event implementedTrigger = GetEventFromAdder(implementedAdder);
                if (implementedTrigger != null) list.Add(implementedTrigger);
            }

            return (list.ToArray());

        }
Example #3
0
        /// <summary>
        /// Write out an event name
        /// </summary>
        /// <param name="trigger">The event for which to write out the name</param>
        /// <param name="sb">The string builder to which the name is written</param>
        private static void WriteEvent(Event trigger, StringBuilder sb)
        {
            WriteType(trigger.DeclaringType, sb);

            Event eiiTrigger = null;

            if(trigger.IsPrivate && trigger.IsVirtual)
                eiiTrigger = trigger.GetImplementedEvents().FirstOrDefault();

            if(eiiTrigger != null)
            {
                TypeNode eiiType = eiiTrigger.DeclaringType;

                if(eiiType != null)
                    if(eiiType.Template != null)
                    {
                        sb.Append(".");
                        WriteTemplate(eiiType, sb);
                    }
                    else
                    {
                        StringBuilder eiiName = new StringBuilder();

                        WriteType(eiiType, eiiName);
                        sb.Append(".");
                        sb.Append(eiiName.ToString().Replace('.', '#'));
                    }

                sb.Append("#");
                sb.Append(eiiTrigger.Name.Name);
            }
            else
            {
                sb.Append('.');
                sb.Append(trigger.Name.Name);
            }
        }
Example #4
0
 public virtual Event VisitEvent(Event evnt)
 {
     if (evnt == null) return null;
     evnt.Attributes = this.VisitAttributeList(evnt.Attributes);
     evnt.HandlerType = this.VisitTypeReference(evnt.HandlerType);
     return evnt;
 }
Example #5
0
        private void WriteEventData(Event trigger) {

            Method adder = trigger.HandlerAdder;
            Method remover = trigger.HandlerRemover;
            Method caller = trigger.HandlerCaller;

            WriteProcedureData(adder, trigger.OverriddenMember);

            writer.WriteStartElement("eventdata");
            if (adder != null) WriteBooleanAttribute("add", true);
            if (remover != null) WriteBooleanAttribute("remove", true);
            if (caller != null) WriteBooleanAttribute("call", true);
            writer.WriteEndElement();

            if (adder != null)
            {
                writer.WriteStartElement("adder");
                WriteStringAttribute("name", string.Format("add_{0}", trigger.Name.Name));

                WriteAttributes(adder.Attributes, adder.SecurityAttributes);
                writer.WriteEndElement();
            }
            if (remover != null)
            {
                writer.WriteStartElement("remover");
                WriteStringAttribute("name", string.Format("remove_{0}", trigger.Name.Name));

                WriteAttributes(remover.Attributes, remover.SecurityAttributes);
                writer.WriteEndElement();
            }

            writer.WriteStartElement("eventhandler");
            WriteTypeReference(trigger.HandlerType);
            writer.WriteEndElement();

            // handlers should always be elegates, but I have seen a case where one is not, so check for this
            DelegateNode handler = trigger.HandlerType as DelegateNode;
            if (handler != null) {
                ParameterList parameters = handler.Parameters;

                if ((parameters != null) && (parameters.Count == 2) && (parameters[0].Type.FullName == "System.Object")) {
                    writer.WriteStartElement("eventargs");
                    WriteTypeReference(parameters[1].Type);
                    writer.WriteEndElement();
                }
            }

        }
        //=====================================================================

        /// <summary>
        /// This finds all attached properties and events, adds information about them to the types, and tracks
        /// them for adding to the reflection data later in the other callbacks.
        /// </summary>
        /// <param name="writer">The reflection data XML writer</param>
        /// <param name="info">For this callback, the information object is a namespace list</param>
        private void AddAttachedMembers(XmlWriter writer, object info)
        {
            NamespaceList spaces = (NamespaceList)info;

            foreach(Namespace space in spaces)
            {
                TypeNodeList types = space.Types;

                foreach(TypeNode type in types)
                {
                    MemberList members = new MemberList(type.Members);

                    // Go through the members looking for fields signaling attached properties
                    foreach(Member member in members)
                    {
                        // We need a visible, static, field...
                        if(!member.IsStatic || !member.IsVisibleOutsideAssembly || member.NodeType != NodeType.Field)
                            continue;

                        Field field = (Field)member;

                        // ... of type dependency property ...
                        if(field.Type.FullName != "System.Windows.DependencyProperty")
                            continue;

                        // ... with a name ending in "Property".
                        string name = field.Name.Name;

                        if(!name.EndsWith("Property", StringComparison.Ordinal))
                            continue;

                        name = name.Substring(0, name.Length - 8);

                        // Look for a getter and/or a setter
                        Method getter = null;

                        MemberList candidateGetters = type.GetMembersNamed(new Identifier("Get" + name));

                        foreach(var candidateGetter in candidateGetters)
                            if(candidateGetter.NodeType == NodeType.Method && candidateGetter.IsStatic &&
                              candidateGetter.IsVisibleOutsideAssembly)
                                getter = (Method)candidateGetter;

                        Method setter = null;

                        MemberList candidateSetters = type.GetMembersNamed(new Identifier("Set" + name));

                        foreach(var candidateSetter in candidateSetters)
                            if(candidateSetter.NodeType == NodeType.Method && candidateSetter.IsStatic &&
                              candidateSetter.IsVisibleOutsideAssembly)
                                setter = (Method)candidateSetter;

                        if(getter == null && setter == null)
                            continue;

                        // Make sure there isn't already such a property
                        Property existingProperty = type.GetProperty(new Identifier(name), new TypeNode[0]);

                        if(existingProperty != null && existingProperty.IsVisibleOutsideAssembly)
                            continue;

                        // Okay, this really is an indication of an attached property, so create one
                        Property attachedProperty = new Property(type, null, PropertyFlags.None, new Identifier(name), getter, setter);

                        // Attached properties have no parameters
                        attachedProperty.Parameters = ParameterList.Empty;

                        // Attached properties are instance properties
                        type.Members.Add(attachedProperty);

                        attachedMembers.Add(attachedProperty, field);
                    }

                    // Go through the members, looking for fields signaling attached events
                    foreach(Member member in members)
                    {
                        // Follow a similar approach as above but for an event
                        if(!member.IsStatic || !member.IsVisibleOutsideAssembly)
                            continue;

                        if(member.NodeType != NodeType.Field)
                            continue;

                        Field field = (Field)member;

                        if(field.Type.FullName != "System.Windows.RoutedEvent")
                            continue;

                        string name = field.Name.Name;

                        if(!name.EndsWith("Event", StringComparison.Ordinal))
                            continue;

                        name = name.Substring(0, name.Length - 5);

                        Method adder = null;

                        MemberList candidateAdders = type.GetMembersNamed(new Identifier("Add" + name + "Handler"));

                        foreach(var candidateAdder in candidateAdders)
                            if(candidateAdder.NodeType == NodeType.Method && candidateAdder.IsStatic)
                                adder = (Method)candidateAdder;

                        Method remover = null;

                        MemberList candidateRemovers = type.GetMembersNamed(new Identifier("Remove" + name + "Handler"));

                        foreach(var candidateRemover in candidateRemovers)
                            if(candidateRemover.NodeType == NodeType.Method && candidateRemover.IsStatic)
                                remover = (Method)candidateRemover;

                        if(adder == null || remover == null)
                            continue;

                        // Make sure there isn't already such an event
                        Event existingEvent = type.GetEvent(new Identifier(name));

                        if(existingEvent != null && existingEvent.IsVisibleOutsideAssembly)
                            continue;

                        // Okay, this really is an indication of an attached event, so create one
                        TypeNode handler = adder.Parameters[1].Type;

                        Event attachedEvent = new Event(type, null, EventFlags.None, new Identifier(name), adder, null, remover, handler);
                        attachedEvent.HandlerFlags = adder.Flags;

                        type.Members.Add(attachedEvent);

                        attachedMembers.Add(attachedEvent, field);
                    }
                }
            }
        }
Example #7
0
        public override Event VisitEvent(Event evnt)
        {
            if (evnt == null) return null;
            Event dup = (Event)this.DuplicateFor[evnt.UniqueKey];
            if (dup != null) return dup;
            this.DuplicateFor[evnt.UniqueKey] = dup = (Event)evnt.Clone();

            if (this.CopyDocumentation) dup.Documentation = evnt.Documentation;

            dup.HandlerAdder = this.VisitMethod(evnt.HandlerAdder);
            dup.HandlerCaller = this.VisitMethod(evnt.HandlerCaller);
            dup.HandlerRemover = this.VisitMethod(evnt.HandlerRemover);
            dup.OtherMethods = this.VisitMethodList(evnt.OtherMethods);
            dup.DeclaringType = this.TargetType;
            return base.VisitEvent(dup);
        }
Example #8
0
 private void ParseEvent(TypeNode parentType, AttributeList attributes, TokenList modifierTokens,
   SourceContextList modifierContexts, object sctx, TokenSet followers){
   Debug.Assert(this.currentToken == Token.Event);
   this.GetNextToken();
   Event e = new Event(parentType, attributes, EventFlags.None, null, null, null, null, null);
   e.DeclaringType = parentType;
   e.Documentation = this.LastDocComment;
   TypeNode t = this.ParseTypeExpression(Identifier.Empty, followers|Parser.IdentifierOrNonReservedKeyword);
   //REVIEW: allow events with anonymous delegate type?
   e.HandlerType = e.HandlerTypeExpression = t;
   TypeExpression interfaceType = null;
   Identifier id = this.scanner.GetIdentifier();
   this.SkipIdentifierOrNonReservedKeyword();
   TypeNodeList templateArguments = null;
   int endPos = 0, arity = 0;
   while (this.currentToken == Token.Dot || this.currentToken == Token.LessThan) {
     if (interfaceType == null && this.ExplicitInterfaceImplementationIsAllowable(parentType, id)) {
       for (int i = 0, n = modifierContexts == null ? 0 : modifierContexts.Length; i < n; i++){
         this.HandleError(modifierContexts[i], Error.InvalidModifier, modifierContexts[i].SourceText);
         modifierTokens = new TokenList(0);
       }
     }
     TypeExpression intfExpr = interfaceType;
     if (intfExpr == null) {
       intfExpr = new TypeExpression(id, id.SourceContext);
     } else if( templateArguments == null) {
       SourceContext ctx = intfExpr.Expression.SourceContext;
       ctx.EndPos = id.SourceContext.EndPos;
       intfExpr.Expression = new QualifiedIdentifier(intfExpr.Expression, id, ctx);
     }
     if (templateArguments != null) {
       intfExpr.TemplateArguments = templateArguments;
       intfExpr.SourceContext.EndPos = endPos;
     }
     if (this.currentToken == Token.LessThan) {
       templateArguments = this.ParseTypeArguments(true, false, followers | Token.Dot | Token.LeftParenthesis | Token.LeftBrace, out endPos, out arity);
     } else {  //  Dot
       templateArguments = null;
       this.GetNextToken();
       id = this.scanner.GetIdentifier();
       this.SkipIdentifierOrNonReservedKeyword();
       if (intfExpr == null) id.SourceContext.Document = null;
     }
     interfaceType = intfExpr;
   }
   e.Name = id;
   MethodFlags mflags = this.GetMethodFlags(modifierTokens, modifierContexts, parentType, e);
   if ((mflags & MethodFlags.Static) != 0 && parentType is Interface){
     this.HandleError(id.SourceContext, Error.InvalidModifier, "static");
     mflags &= ~MethodFlags.Static;
     mflags |= MethodFlags.Abstract;
   }
   e.HandlerFlags = mflags|MethodFlags.SpecialName;
   bool hasAccessors = this.currentToken == Token.LeftBrace || interfaceType != null;
   if (hasAccessors){
     if (interfaceType != null){
       e.ImplementedTypeExpressions = e.ImplementedTypes = new TypeNodeList(interfaceType);
       if (this.currentToken != Token.LeftBrace){
         this.HandleError(Error.ExplicitEventFieldImpl);
         hasAccessors = false;
         goto nextDeclarator;
       }
     }
     this.Skip(Token.LeftBrace);
     TokenSet followersOrRightBrace = followers|Token.RightBrace;
     bool alreadyGivenAddOrRemoveExpectedError = false;
     bool alreadyComplainedAboutAccessors = false;
     for(;;){
       SourceContext sc = this.scanner.CurrentSourceContext;
       AttributeList accessorAttrs = this.ParseAttributes(null, followers|Parser.AddOrRemoveOrModifier|Token.LeftBrace);
       switch (this.currentToken){
         case Token.Add:
           if (parentType is Interface && !alreadyComplainedAboutAccessors){
             this.HandleError(Error.EventPropertyInInterface, parentType.FullName+"."+id);
             alreadyComplainedAboutAccessors = true;
           }else if (e.HandlerAdder != null)
             this.HandleError(Error.DuplicateAccessor);
           SourceContext scntx = this.scanner.CurrentSourceContext;
           this.GetNextToken();
           ParameterList parList = new ParameterList();
           parList.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, t, null, null));
           Method m = new Method(parentType, accessorAttrs, new Identifier("add_"+id.ToString()), parList, this.TypeExpressionFor(Token.Void), null);
           m.HidesBaseClassMember = e.HidesBaseClassMember;
           m.OverridesBaseClassMember = e.OverridesBaseClassMember;
           m.Name.SourceContext = scntx;
           if ((mflags & MethodFlags.Static) == 0)
             m.CallingConvention = CallingConventionFlags.HasThis;
           m.Flags = mflags|MethodFlags.HideBySig|MethodFlags.SpecialName;
           if (interfaceType != null){
             m.Flags = MethodFlags.Private|MethodFlags.HideBySig|MethodFlags.NewSlot|MethodFlags.Final|MethodFlags.Virtual|MethodFlags.SpecialName;
             m.ImplementedTypeExpressions = m.ImplementedTypes = new TypeNodeList(interfaceType);
           }
           if (this.currentToken != Token.LeftBrace){
             this.SkipTo(followersOrRightBrace|Token.Remove, Error.AddRemoveMustHaveBody);
             alreadyGivenAddOrRemoveExpectedError = true;
           }else
             m.Body = this.ParseBody(m, sc, followersOrRightBrace|Token.Remove);
           if (!(parentType is Interface)){
             e.HandlerAdder = m;
             m.DeclaringMember = e;
             parentType.Members.Add(m);
           }
           continue;
         case Token.Remove:
           if (parentType is Interface && !alreadyComplainedAboutAccessors){
             this.HandleError(Error.EventPropertyInInterface, parentType.FullName+"."+id);
             alreadyComplainedAboutAccessors = true;
           }else if (e.HandlerRemover != null)
             this.HandleError(Error.DuplicateAccessor);
           scntx = this.scanner.CurrentSourceContext;
           this.GetNextToken();
           parList = new ParameterList();
           parList.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, t, null, null));
           m = new Method(parentType, accessorAttrs, new Identifier("remove_"+id.ToString()), parList, this.TypeExpressionFor(Token.Void), null);
           m.HidesBaseClassMember = e.HidesBaseClassMember;
           m.OverridesBaseClassMember = e.OverridesBaseClassMember;
           m.Name.SourceContext = scntx;
           if ((mflags & MethodFlags.Static) == 0)
             m.CallingConvention = CallingConventionFlags.HasThis;
           m.Flags = mflags|MethodFlags.HideBySig|MethodFlags.SpecialName;
           if (interfaceType != null){
             m.Flags = MethodFlags.Private|MethodFlags.HideBySig|MethodFlags.NewSlot|MethodFlags.Final|MethodFlags.Virtual|MethodFlags.SpecialName;
             m.ImplementedTypeExpressions = m.ImplementedTypes = new TypeNodeList(interfaceType);
           }
           if (this.currentToken != Token.LeftBrace){
             this.SkipTo(followersOrRightBrace|Token.Add, Error.AddRemoveMustHaveBody);
             alreadyGivenAddOrRemoveExpectedError = true;
           }else
             m.Body = this.ParseBody(m, sc, followersOrRightBrace|Token.Add);
           if (!(parentType is Interface)){
             e.HandlerRemover = m;
             m.DeclaringMember = e;
             parentType.Members.Add(m);
           }
           continue;
         case Token.New:
         case Token.Public:
         case Token.Protected:
         case Token.Internal:
         case Token.Private:
         case Token.Abstract:
         case Token.Sealed:
         case Token.Static:
         case Token.Readonly:
         case Token.Volatile:
         case Token.Virtual:
         case Token.Override:
         case Token.Extern:
         case Token.Unsafe:
           this.HandleError(Error.NoModifiersOnAccessor);
           this.GetNextToken();
           break;
         default:
           if ((e.HandlerAdder == null || e.HandlerRemover == null) && this.sink != null && this.currentToken == Token.Identifier && this.scanner.endPos == this.scanner.maxPos){
             e.SourceContext.EndPos = this.scanner.startPos;
             KeywordCompletionList keywords;
             if (e.HandlerAdder != null)
               keywords = new KeywordCompletionList(this.scanner.GetIdentifier(), new KeywordCompletion("remove"));
             else if (e.HandlerRemover != null)
               keywords = new KeywordCompletionList(this.scanner.GetIdentifier(), new KeywordCompletion("add"));
             else
               keywords = new KeywordCompletionList(this.scanner.GetIdentifier(), new KeywordCompletion("add"), new KeywordCompletion("remove"));
             parentType.Members.Add(keywords);
             this.GetNextToken();
           }
           if (!alreadyGivenAddOrRemoveExpectedError && !alreadyComplainedAboutAccessors && (e.HandlerAdder == null || e.HandlerRemover == null)) {
             if (this.currentToken == Token.RightBrace)
               this.HandleError(id.SourceContext, Error.EventNeedsBothAccessors, parentType.FullName+"."+id.Name);
             else
               this.HandleError(Error.AddOrRemoveExpected);
             alreadyGivenAddOrRemoveExpectedError = true;
             if (!(Parser.EndOfFile|Token.LeftBrace|Token.RightBrace)[this.currentToken])
               this.GetNextToken();
             this.SkipTo(followersOrRightBrace|Token.LeftBrace, Error.None);
             if (this.currentToken == Token.LeftBrace){
               this.ParseBlock(followersOrRightBrace|Token.Add|Token.Remove);
               continue;
             }
           }
           break;
       }
       break;
     }
     this.Skip(Token.RightBrace); //TODO: brace matching
   }
   nextDeclarator:
     e.Name = id;
   e.SourceContext = (SourceContext)sctx;
   e.SourceContext.EndPos = this.scanner.endPos;
   parentType.Members.Add(e);
   if (!hasAccessors){
     switch(this.currentToken){
       case Token.Assign:
         this.GetNextToken();
         e.InitialHandler = this.ParseExpression(followers|Token.Semicolon);
         if (parentType is Interface && e.InitialHandler != null){
           this.HandleError(e.InitialHandler.SourceContext, Error.InterfaceEventInitializer, parentType.FullName+"."+id);
           e.InitialHandler = null;
         }
         if (this.currentToken == Token.Comma)
           goto case Token.Comma;
         else
           goto default;
       case Token.Comma:
         this.GetNextToken();
         id = this.scanner.GetIdentifier();
         this.SkipIdentifierOrNonReservedKeyword(); //REVIEW: allow interface name?
         e = new Event(parentType, attributes, (EventFlags)0, null, null, null, null, null);
         e.HandlerFlags = mflags;
         e.HandlerType = e.HandlerTypeExpression = t;
         goto nextDeclarator;
       default:
         this.Skip(Token.Semicolon);
         break;
     }
   }
 }
Example #9
0
        private static void WriteEvent(Event trigger, TextWriter writer) {
            WriteType(trigger.DeclaringType, writer);

            Event eiiTrigger = null;
            if (trigger.IsPrivate && trigger.IsVirtual) {
                Event[] eiiTriggers = ReflectionUtilities.GetImplementedEvents(trigger);
                if (eiiTriggers.Length > 0) eiiTrigger = eiiTriggers[0];
            }

            if (eiiTrigger != null) {
                TypeNode eiiType = eiiTrigger.DeclaringType;
                TextWriter eiiWriter = new StringWriter();

                if (eiiType != null && eiiType.Template != null)
                {
                    writer.Write(".");
                    WriteTemplate(eiiType, writer);
                }
                else
                {
                    WriteType(eiiType, eiiWriter);
                    writer.Write(".");
                    writer.Write(eiiWriter.ToString().Replace('.', '#'));
                }

                writer.Write("#");
                writer.Write(eiiTrigger.Name.Name);
            } else {
                writer.Write(".{0}", trigger.Name.Name);
            }
        }
Example #10
0
 private static void WriteEvent(Event trigger, TextWriter writer) {
     WriteType(trigger.DeclaringType, writer);
     writer.Write(".{0}", trigger.Name.Name);
 }
        /// <summary>
        /// Find shadow event in given type corresponding to event.
        /// </summary>
        public static Event FindShadow(this TypeNode parent, Event evnt)
        {
            if (evnt == null || evnt.Name == null)
            {
                return null;
            }

            MemberList members = parent.GetMembersNamed(evnt.Name);
            for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
            {
                var e = members[i] as Event;
                if (e == null) continue;

                return e;
            }

            return null;
        }
Example #12
0
 public override Event VisitEvent(Event evnt)
 {
     throw new NotImplementedException("Node type not yet supported");
 }
Example #13
0
    public override Event VisitEvent(Event evnt) {
      if (evnt == null || evnt.SourceContext.SourceText == null) return null;
      this.writer.WriteStartElement("Event");
      this.writer.WriteAttributeString("name", evnt.Name.Name);
      this.WriteSourceContext(evnt);

      this.writer.WriteEndElement(); // Event
      return evnt;
    }
 public EventingVisitor(Action<Event> visitEvent) { VisitedEvent += visitEvent; } public event Action<Event> VisitedEvent; public override Event VisitEvent(Event evnt) { if (VisitedEvent != null) VisitedEvent(evnt); return base.VisitEvent(evnt); }