/// <summary> /// Parses and returns a event. /// </summary> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="elementReference"> /// A reference to the element being created. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code is marked as unsafe. /// </param> /// <param name="generated"> /// Indicates whether the code is marked as generated code. /// </param> /// <param name="xmlHeader"> /// The element's documentation header. /// </param> /// <param name="attributes"> /// The attributes on the element. /// </param> /// <returns> /// Returns the element. /// </returns> private Event ParseEvent( CsElement parent, Reference<ICodePart> elementReference, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Attribute> attributes) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(xmlHeader); Param.Ignore(attributes); Node<CsToken> previousTokenNode = this.tokens.Last; // Get the modifiers and access. AccessModifierType accessModifier = AccessModifierType.Private; // Events within interfaces always have the access of the parent interface. Interface parentInterface = parent as Interface; if (parentInterface != null) { accessModifier = parentInterface.AccessModifier; } // Get declared modifiers. Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, EventModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the event keyword. this.tokens.Add(this.GetToken(CsTokenType.Event, SymbolType.Event, elementReference)); // Get the event type. TypeToken eventHandlerType = this.GetTypeToken(elementReference, unsafeCode, true); this.tokens.Add(eventHandlerType); List<EventDeclaratorExpression> declarators = new List<EventDeclaratorExpression>(); string firstEventName = null; while (true) { Symbol symbol = this.GetNextSymbol(SymbolType.Other, elementReference); Reference<ICodePart> declaratorExpressionReference = new Reference<ICodePart>(); // Get the identifier. LiteralExpression identifier = this.GetTypeTokenExpression(declaratorExpressionReference, unsafeCode, false); if (identifier == null || identifier.Tokens.First == null) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } if (firstEventName == null) { firstEventName = identifier.Token.Text; } // Get the initializer if it exists. Expression initializer = null; symbol = this.GetNextSymbol(declaratorExpressionReference); if (symbol.SymbolType == SymbolType.Equals) { // Add the equals token. this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, declaratorExpressionReference)); initializer = this.GetNextExpression(ExpressionPrecedence.None, declaratorExpressionReference, unsafeCode); } // Create the token list for the declarator. CsTokenList partialTokens = new CsTokenList(this.tokens, identifier.Tokens.First, this.tokens.Last); // Create and add the declarator. EventDeclaratorExpression declaratorExpression = new EventDeclaratorExpression(partialTokens, identifier, initializer); declaratorExpressionReference.Target = declaratorExpression; declarators.Add(declaratorExpression); // Now check if the next character is a comma. If so there is another declarator. symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType != SymbolType.Comma) { // There are no more declarators. break; } // Add the comma. this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, elementReference)); } // Create the declaration. Node<CsToken> firstTokenNode = previousTokenNode == null ? this.tokens.First : previousTokenNode.Next; CsTokenList declarationTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last); Declaration declaration = new Declaration(declarationTokens, firstEventName, ElementType.Event, accessModifier, modifiers); Event @event = new Event(this.document, parent, xmlHeader, attributes, declaration, eventHandlerType, declarators.ToArray(), unsafeCode, generated); elementReference.Target = @event; Symbol s = this.GetNextSymbol(elementReference); if (s.SymbolType == SymbolType.Semicolon) { this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); } else { // Parse the body of the event. this.ParseElementContainer(@event, elementReference, null, unsafeCode); } return @event; }
private void Save(Event @event) { // 1 to destHeader if (!(@event.Parent is Namespace)) { this.SaveModifiersBefore(@event); } // 1 to destHeader this.headerWriter.Write("event "); this.Save(new TypeResolver(@event.EventHandlerType, this), this.headerWriter, SavingOptions.UseFullyQualifiedNames); this.headerWriter.Write(" "); this.headerWriter.Write(@event.Declaration.Name); this.headerWriter.WriteLine(';'); }