/// <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(); }
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()); }
/// <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); } }
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; }
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); } } } }
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); }
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; } } }
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); } }
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; }
public override Event VisitEvent(Event evnt) { throw new NotImplementedException("Node type not yet supported"); }
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); }