/// <summary> /// Initializes a new instance of the Accessor class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="accessorType"> /// The type of the accessor. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Accessor( CsDocument document, CsElement parent, AccessorType accessorType, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.Accessor, declaration.Name + " accessor", header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(accessorType); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.Ignore(unsafeCode); Param.Ignore(generated); this.accessorType = accessorType; // Make sure the type and name match. Debug.Assert( (accessorType == AccessorType.Get && declaration.Name == "get") || (accessorType == AccessorType.Set && declaration.Name == "set") || (accessorType == AccessorType.Add && declaration.Name == "add") || (accessorType == AccessorType.Remove && declaration.Name == "remove"), "The accessor type does not match its name."); this.FillDetails(parent); }
/// <summary> /// Initializes a new instance of the Property class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="returnType"> /// The property return type. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Property( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, TypeToken returnType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Property, "property " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.AssertNotNull(returnType, "returnType"); Param.Ignore(unsafeCode); Param.Ignore(generated); this.returnType = returnType; // If this is an explicit interface member implementation and our access modifier // is currently set to private because we don't have one, then it should be public instead. if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } }
/// <summary> /// Initializes a new instance of the Class class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="typeConstraints"> /// The list of type constraints on the class, if any. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Class( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, ICollection<TypeParameterConstraintClause> typeConstraints, bool unsafeCode, bool generated) : base(document, parent, ElementType.Class, "class " + declaration.Name, header, attributes, declaration, typeConstraints, unsafeCode, generated) { Param.Ignore(document, parent, header, attributes, declaration, typeConstraints, unsafeCode, generated); }
/// <summary> /// Initializes a new instance of the AssemblyOrModuleAttribute class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> /// <param name="attributes"> /// The actual attribute that this Assembly or Module level attribute contains. /// </param> internal AssemblyOrModuleAttribute(CsDocument document, CsElement parent, Declaration declaration, bool generated, ICollection<Attribute> attributes) : base( document, parent, ElementType.AssemblyOrModuleAttribute, "assembly or module attribute " + declaration.Name, null, attributes, declaration, false, generated) { Param.Ignore(document, parent, declaration, generated); }
/// <summary> /// Initializes a new instance of the Destructor class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Destructor( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.Destructor, "destructor " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.Ignore(unsafeCode); Param.Ignore(generated); // Static destructors are always public. if (this.Declaration.ContainsModifier(CsTokenType.Static)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } }
/// <summary> /// Initializes a new instance of the Constructor class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="parameters"> /// The parameters to the constructor. /// </param> /// <param name="initializerExpression"> /// The constructor initializer, if there is one. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Constructor( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, IList<Parameter> parameters, MethodInvocationExpression initializerExpression, bool unsafeCode, bool generated) : base(document, parent, ElementType.Constructor, "constructor " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.AssertNotNull(parameters, "parameters"); Param.Ignore(initializerExpression); Param.Ignore(unsafeCode); Param.Ignore(generated); // Static constructors are treated as private and handled as a special case for ordering. if (this.Declaration.ContainsModifier(CsTokenType.Static)) { this.Declaration.AccessModifierType = AccessModifierType.Private; } this.parameters = parameters; Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only."); // Add the qualifications this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName); // If there is an initializer expression, add it to the statement list for this constructor. if (initializerExpression != null) { this.initializer = initializerExpression; ConstructorInitializerStatement initializerStatement = new ConstructorInitializerStatement(initializerExpression.Tokens, initializerExpression); this.AddStatement(initializerStatement); } }
/// <summary> /// Initializes a new instance of the <see cref="EnumItem"/> class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="initialization"> /// The initialization expression, if there is one. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal EnumItem( CsDocument document, Enum parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, Expression initialization, bool unsafeCode, bool generated) : base(document, parent, ElementType.EnumItem, "enum item " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.Ignore(document, parent, header, attributes, declaration, initialization, unsafeCode, generated); this.initialization = initialization; if (this.initialization != null) { this.AddExpression(this.initialization); } }
/// <summary> /// Parses and returns a extern alias directive. /// </summary> /// <param name="parent"> /// The parent of the namespace. /// </param> /// <param name="elementReference"> /// A reference to the element being created. /// </param> /// <param name="generated"> /// Indicates whether the code is marked as generated code. /// </param> /// <returns> /// Returns the element. /// </returns> private ExternAliasDirective ParseExternAliasDirective(CsElement parent, Reference<ICodePart> elementReference, bool generated) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(generated); // Add the extern token. Node<CsToken> firstToken = this.tokens.InsertLast(this.GetToken(CsTokenType.Extern, SymbolType.Extern, elementReference)); // Add the alias token. this.tokens.Add(this.GetToken(CsTokenType.Alias, SymbolType.Other, elementReference)); // Add the identifier token. CsToken identifier = this.GetToken(CsTokenType.Other, SymbolType.Other, elementReference); this.tokens.Add(identifier); // Create the declaration. CsTokenList declarationTokens = new CsTokenList(this.tokens, firstToken, this.tokens.Last); Declaration declaration = new Declaration(declarationTokens, identifier.Text, ElementType.ExternAliasDirective, AccessModifierType.Public); // Get the closing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); // Create the extern alias directive. ExternAliasDirective element = new ExternAliasDirective(this.document, parent, declaration, generated); elementReference.Target = element; return element; }
/// <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; }
/// <summary> /// Initializes a new instance of the ClassBase class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="type"> /// The element type. /// </param> /// <param name="name"> /// The name of this element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="typeConstraints"> /// The list of type constraints on the element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal ClassBase( CsDocument document, CsElement parent, ElementType type, string name, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, ICollection<TypeParameterConstraintClause> typeConstraints, bool unsafeCode, bool generated) : base(document, parent, type, name, header, attributes, declaration, unsafeCode, generated) { Param.Ignore(document, parent, type, name, header, attributes, declaration, typeConstraints, unsafeCode, generated); this.typeConstraints = typeConstraints; // Set the parent of the type constraint clauses. if (typeConstraints != null) { Debug.Assert(typeConstraints.IsReadOnly, "The typeconstraints collection should be read-only."); foreach (TypeParameterConstraintClause constraint in typeConstraints) { constraint.ParentElement = this; } } }
/// <summary> /// Parses and returns a property. /// </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 Property ParseProperty( 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; // Properties 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, PropertyModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the field type. TypeToken propertyType = this.GetTypeToken(elementReference, unsafeCode, true); Node<CsToken> propertyTypeNode = this.tokens.InsertLast(propertyType); // Get the name of the property. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); Node<CsToken> propertyNameNode = this.tokens.InsertLast(name); // 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, name.Text, ElementType.Property, accessModifier, modifiers); Property property = new Property(this.document, parent, xmlHeader, attributes, declaration, propertyType, unsafeCode, generated); elementReference.Target = property; if (this.IsBodiedExpression()) { this.ParseStatementContainer(property, true, unsafeCode); } else { // Parse the body of the property. this.ParseElementContainer(property, elementReference, null, unsafeCode); // Check if current property has initializer (C#6). Symbol nextSymbol = this.GetNextSymbol(SkipSymbols.WhiteSpace, elementReference, true); if (nextSymbol != null && nextSymbol.SymbolType == SymbolType.Equals) { // Get all of the variable declarators. IList<VariableDeclaratorExpression> declarators = this.ParsePropertyDeclarators(elementReference, unsafeCode, propertyType, propertyNameNode); if (declarators.Count == 0) { throw this.CreateSyntaxException(); } VariableDeclarationExpression declarationExpression = new VariableDeclarationExpression( new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), new LiteralExpression(this.tokens, propertyTypeNode), declarators); // Get the trailing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); // Create the variable declaration statement and add it to the field. property.VariableDeclarationStatement = new VariableDeclarationStatement( new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), false, declarationExpression); } } return property; }
/// <summary> /// Initializes a new instance of the Namespace class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="type"> /// The element type. /// </param> /// <param name="name"> /// The name of this element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Namespace( CsDocument document, CsElement parent, ElementType type, string name, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, type, name, header, attributes, declaration, unsafeCode, generated) { Param.Ignore(document, parent, type, name, header, attributes, declaration, unsafeCode, generated); }
/// <summary> /// Parses and returns a constructor. /// </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 Constructor ParseConstructor( 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; Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, ConstructorModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the name of the constructor. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(name); // Get the parameter list. IList<Parameter> parameters = this.ParseParameterList(elementReference, unsafeCode, SymbolType.OpenParenthesis); // Get the constructor initializer if there is one. MethodInvocationExpression constructorInitializer = null; Symbol symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType == SymbolType.Colon) { this.tokens.Add(this.GetToken(CsTokenType.BaseColon, SymbolType.Colon, elementReference)); // The next symbol must be the keyword base or this. symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType != SymbolType.This && symbol.SymbolType != SymbolType.Base) { throw this.CreateSyntaxException(); } Reference<ICodePart> initializerNameExpressionReference = new Reference<ICodePart>(); Node<CsToken> initializerNameTokenNode = this.tokens.InsertLast(this.GetToken(CsTokenType.Other, symbol.SymbolType, initializerNameExpressionReference)); // Get the name expression. LiteralExpression initializerNameExpression = new LiteralExpression(this.tokens, initializerNameTokenNode); initializerNameExpressionReference.Target = initializerNameExpression; // Get the initializer expression. constructorInitializer = this.GetMethodInvocationExpression(initializerNameExpression, ExpressionPrecedence.None, unsafeCode); } // 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, name.Text, ElementType.Constructor, accessModifier, modifiers); Constructor constructor = new Constructor( this.document, parent, xmlHeader, attributes, declaration, parameters, constructorInitializer, unsafeCode, generated); elementReference.Target = constructor; // If the constructor is extern, it will not have a body. if (modifiers.ContainsKey(CsTokenType.Extern)) { // Get the closing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); } else { // Get the body. this.ParseStatementContainer(constructor, true, unsafeCode); } return constructor; }
/// <summary> /// Parses and returns a method. /// </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 Method ParseMethod( 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; // Get the declared modifiers for the method. Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, MethodModifiers); // Methods within interfaces always have the access of the parent interface. Interface parentInterface = parent as Interface; if (parentInterface != null) { accessModifier = parentInterface.AccessModifier; } unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); TypeToken returnType = null; if (!modifiers.ContainsKey(CsTokenType.Implicit) && !modifiers.ContainsKey(CsTokenType.Explicit)) { // Get the return type. returnType = this.GetTypeToken(elementReference, unsafeCode, true); this.tokens.Add(returnType); } // Get the name of the method. string methodName = null; Symbol symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType == SymbolType.Operator) { this.tokens.Add(this.GetToken(CsTokenType.Operator, SymbolType.Operator, elementReference)); // Advance up to the next symbol. this.AdvanceToNextCodeSymbol(elementReference); // The overloaded item will either be a type or a symbol. int endIndex = -1; CsToken operatorType = null; if (this.HasTypeSignature(1, unsafeCode, out endIndex)) { // The overloaded item is a type. operatorType = this.GetTypeToken(elementReference, unsafeCode, true); } else { // The overloaded item is a symbol. operatorType = this.ConvertOperatorOverloadSymbol(elementReference); } this.tokens.Add(operatorType); methodName = "operator " + operatorType.Text; } else { CsToken name = this.GetElementNameToken(elementReference, unsafeCode); methodName = name.Text; this.tokens.Add(name); } // Get the parameter list. IList<Parameter> parameters = this.ParseParameterList(elementReference, unsafeCode, SymbolType.OpenParenthesis, modifiers.ContainsKey(CsTokenType.Static)); // Check whether there are any type constraint clauses. ICollection<TypeParameterConstraintClause> typeConstraints = null; symbol = this.GetNextSymbol(elementReference); if (symbol.Text == "where") { typeConstraints = this.ParseTypeConstraintClauses(elementReference, unsafeCode); } // 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, methodName, ElementType.Method, accessModifier, modifiers); Method method = new Method(this.document, parent, xmlHeader, attributes, declaration, returnType, parameters, typeConstraints, unsafeCode, generated); elementReference.Target = method; // If the element is extern, abstract, or containing within an interface, it will not have a body. if (modifiers.ContainsKey(CsTokenType.Abstract) || modifiers.ContainsKey(CsTokenType.Extern) || parent.ElementType == ElementType.Interface) { // Get the closing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); } else { // Get the method body or bodied expression C# 6. this.ParseStatementContainer(method, true, unsafeCode); } return method; }
///// <summary> ///// Parses and returns an assembly or module attribute. ///// </summary> ///// <param name="parent">The parent of the namespace.</param> ///// <param name="elementReference">A reference to the element being created.</param> ///// <param name="generated">Indicates whether the code is marked as generated code.</param> ///// <returns>Returns the element.</returns> private AssemblyOrModuleAttribute ParseAssemblyOrModuleAttribute(CsElement parent, Reference<ICodePart> elementReference, bool generated) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(generated); Attribute attribute = this.GetAttribute(elementReference, false); Node<CsToken> firstToken = this.tokens.InsertLast(attribute); // Create the declaration. CsTokenList declarationTokens = new CsTokenList(this.tokens, firstToken, this.tokens.Last); Declaration declaration = new Declaration(declarationTokens, attribute.Text, ElementType.AssemblyOrModuleAttribute, AccessModifierType.Public); ICollection<Attribute> attributes = new List<Attribute>(1) { attribute }.ToArray(); AssemblyOrModuleAttribute element = new AssemblyOrModuleAttribute(this.document, parent, declaration, generated, attributes); elementReference.Target = element; return element; }
/// <summary> /// Parses and returns a class, struct, or interface. /// </summary> /// <param name="elementType"> /// The type of the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="elementReference"> /// A reference to the element being created. /// </param> /// <param name="partialElements"> /// The collection of partial elements found while parsing the files. /// </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 ClassBase ParseClass( ElementType elementType, CsElement parent, Reference<ICodePart> elementReference, Dictionary<string, List<CsElement>> partialElements, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Attribute> attributes) { Param.Ignore(elementType); Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.AssertNotNull(partialElements, "partialElements"); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(xmlHeader); Param.Ignore(attributes); Node<CsToken> previousTokenNode = this.tokens.Last; // Top-level classes, structs, and interfaces received Internal access by default, while classes, structs, and interfaces // declared within a class receive Private access by default. AccessModifierType accessModifier = AccessModifierType.Internal; if (parent.ElementType == ElementType.Class) { accessModifier = AccessModifierType.Private; } // Get the modifiers and access. Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, ClassModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the element keyword, depending on the element type. CsTokenType keywordType = CsTokenType.Class; SymbolType symbolType = SymbolType.Class; if (elementType == ElementType.Struct) { keywordType = CsTokenType.Struct; symbolType = SymbolType.Struct; } else if (elementType == ElementType.Interface) { keywordType = CsTokenType.Interface; symbolType = SymbolType.Interface; } else { Debug.Assert(elementType == ElementType.Class, "The method can only be called for a class, struct, or interface"); } // Add the keyword token. this.tokens.Add(this.GetToken(keywordType, symbolType, elementReference)); // Add the class name token. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(name); // Get the base classes. Symbol symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType == SymbolType.Colon) { // Add the colon token. this.tokens.Add(this.GetToken(CsTokenType.BaseColon, SymbolType.Colon, elementReference)); // Get each of the base classes and interfaces. while (true) { this.tokens.Add(this.GetTypeToken(elementReference, unsafeCode, false)); symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType != SymbolType.Comma) { break; } this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, elementReference)); } } // Check whether there are any type constraint clauses. ICollection<TypeParameterConstraintClause> typeConstraints = null; symbol = this.GetNextSymbol(elementReference); if (symbol.Text == "where") { typeConstraints = this.ParseTypeConstraintClauses(elementReference, unsafeCode); } // 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, name.Text, elementType, accessModifier, modifiers); // Create the element. ClassBase item = null; if (keywordType == CsTokenType.Class) { item = new Class(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated); } else if (keywordType == CsTokenType.Struct) { item = new Struct(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated); } else { Debug.Assert(keywordType == CsTokenType.Interface, "Invalid element type"); item = new Interface(this.document, parent, xmlHeader, attributes, declaration, typeConstraints, unsafeCode, generated); } elementReference.Target = item; // Parse the body of the element. this.ParseElementContainer(item, elementReference, partialElements, unsafeCode); return item; }
/// <summary> /// Parses and returns a property, indexer, or event accessor. /// </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 Accessor ParseAccessor( 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; Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, null); // Get the accessor type token. AccessorType accessorType = AccessorType.Get; CsToken accessorName = null; Symbol symbol = this.GetNextSymbol(elementReference); if (symbol.Text == "get") { accessorName = this.GetToken(CsTokenType.Get, SymbolType.Other, elementReference); if (parent.ElementType != ElementType.Property && parent.ElementType != ElementType.Indexer) { throw this.CreateSyntaxException(); } } else if (symbol.Text == "set") { accessorType = AccessorType.Set; accessorName = this.GetToken(CsTokenType.Set, SymbolType.Other, elementReference); if (parent.ElementType != ElementType.Property && parent.ElementType != ElementType.Indexer) { throw this.CreateSyntaxException(); } } else if (symbol.Text == "add") { accessorType = AccessorType.Add; accessorName = this.GetToken(CsTokenType.Add, SymbolType.Other, elementReference); if (parent.ElementType != ElementType.Event) { throw this.CreateSyntaxException(); } } else if (symbol.Text == "remove") { accessorType = AccessorType.Remove; accessorName = this.GetToken(CsTokenType.Remove, SymbolType.Other, elementReference); if (parent.ElementType != ElementType.Event) { throw this.CreateSyntaxException(); } } else { throw this.CreateSyntaxException(); } this.tokens.Add(accessorName); // 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, accessorName.Text, ElementType.Accessor, accessModifier, modifiers); Accessor accessor = new Accessor(this.document, parent, accessorType, xmlHeader, attributes, declaration, unsafeCode, generated); elementReference.Target = accessor; // Get the method body. this.ParseStatementContainer(accessor, true, unsafeCode); return accessor; }
/// <summary> /// Initializes a new instance of the Field class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="fieldType"> /// The type of the field. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Field( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, TypeToken fieldType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Field, "field " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.AssertNotNull(fieldType, "fieldType"); Param.Ignore(unsafeCode); Param.Ignore(generated); this.type = fieldType; // Determine whether the item is const /readonly / static. this.isConst = this.Declaration.ContainsModifier(CsTokenType.Const); this.isReadOnly = this.Declaration.ContainsModifier(CsTokenType.Readonly); this.isStatic = this.Declaration.ContainsModifier(CsTokenType.Static); }
/// <summary> /// Initializes a new instance of the <see cref="Enum"/> class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Enum( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.Enum, "enum " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.Ignore(document, parent, header, attributes, declaration, unsafeCode, generated); }
/// <summary> /// Parses and returns a field. /// </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 Field ParseField( 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; Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, FieldModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the field type. TypeToken fieldType = this.GetTypeToken(elementReference, unsafeCode, true); Node<CsToken> fieldTypeNode = this.tokens.InsertLast(fieldType); // Get all of the variable declarators. IList<VariableDeclaratorExpression> declarators = this.ParseFieldDeclarators(elementReference, unsafeCode, fieldType); if (declarators.Count == 0) { throw this.CreateSyntaxException(); } VariableDeclarationExpression declarationExpression = new VariableDeclarationExpression( new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), new LiteralExpression(this.tokens, fieldTypeNode), declarators); // Create the field. 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, declarators[0].Identifier.Text, ElementType.Field, accessModifier, modifiers); Field field = new Field(this.document, parent, xmlHeader, attributes, declaration, fieldType, unsafeCode, generated); elementReference.Target = field; // Get the trailing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); // Create the variable declaration statement and add it to the field. field.VariableDeclarationStatement = new VariableDeclarationStatement( new CsTokenList(this.tokens, declarators[0].Tokens.First, this.tokens.Last), field.Const, declarationExpression); return field; }
/// <summary> /// Parses and returns a delegate. /// </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 Delegate ParseDelegate( 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; // The access defaults to public for a top-level element, or private for a nested element. AccessModifierType accessModifier = AccessModifierType.Public; if (parent.ElementType == ElementType.Class || parent.ElementType == ElementType.Struct) { accessModifier = AccessModifierType.Private; } // Get the modifiers and access. Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, DelegateModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the delegate keyword. this.tokens.Add(this.GetToken(CsTokenType.Delegate, SymbolType.Delegate, elementReference)); // Get the return type. TypeToken returnType = this.GetTypeToken(elementReference, unsafeCode, true); this.tokens.Add(returnType); // Get the name of the delegate. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(name); // Get the parameter list. IList<Parameter> parameters = this.ParseParameterList(elementReference, unsafeCode, SymbolType.OpenParenthesis); // Check whether there are any type constraint clauses. ICollection<TypeParameterConstraintClause> typeConstraints = null; Symbol symbol = this.GetNextSymbol(elementReference); if (symbol.Text == "where") { typeConstraints = this.ParseTypeConstraintClauses(elementReference, unsafeCode); } // 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, name.Text, ElementType.Delegate, accessModifier, modifiers); // Get the closing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); Delegate element = new Delegate(this.document, parent, xmlHeader, attributes, declaration, returnType, parameters, typeConstraints, unsafeCode, generated); elementReference.Target = element; return element; }
/// <summary> /// Parses and returns an indexer. /// </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 Indexer ParseIndexer( 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; // Indexers 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, IndexerModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Get the return type. TypeToken returnType = this.GetTypeToken(elementReference, unsafeCode, true); this.tokens.Add(returnType); // Get the name of the indexer. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(name); // Get the parameter list. IList<Parameter> parameters = this.ParseParameterList(elementReference, unsafeCode, SymbolType.OpenSquareBracket); // 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, name.Text, ElementType.Indexer, accessModifier, modifiers); Indexer indexer = new Indexer(this.document, parent, xmlHeader, attributes, declaration, returnType, parameters, unsafeCode, generated); elementReference.Target = indexer; // Parse the body of the indexer. this.ParseElementContainer(indexer, elementReference, null, unsafeCode); return indexer; }
/// <summary> /// Initializes a new instance of the Destructor class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Destructor( CsDocument document, CsElement parent, XmlHeader header, ICollection <Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.Destructor, "destructor " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.Ignore(unsafeCode); Param.Ignore(generated); // Static destructors are always public. if (this.Declaration.ContainsModifier(CsTokenType.Static)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } }
/// <summary> /// Parses and returns a namespace. /// </summary> /// <param name="parent"> /// The parent of the namespace. /// </param> /// <param name="elementReference"> /// A reference to the element being created. /// </param> /// <param name="partialElements"> /// The collection of partial elements found while parsing the files. /// </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 Namespace ParseNamespace( CsElement parent, Reference<ICodePart> elementReference, Dictionary<string, List<CsElement>> partialElements, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Attribute> attributes) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.AssertNotNull(partialElements, "partialElements"); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(xmlHeader); Param.Ignore(attributes); // Add the namespace token. Node<CsToken> firstToken = this.tokens.InsertLast(this.GetToken(CsTokenType.Namespace, SymbolType.Namespace, elementReference)); // Add the namespace name token. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(name); // Create the declaration. CsTokenList declarationTokens = new CsTokenList(this.tokens, firstToken, this.tokens.Last); Declaration declaration = new Declaration(declarationTokens, name.Text, ElementType.Namespace, AccessModifierType.Public); // Create the namespace. Namespace @namespace = new Namespace(this.document, parent, xmlHeader, attributes, declaration, unsafeCode, generated); elementReference.Target = @namespace; // Parse the body of the namespace. this.ParseElementContainer(@namespace, elementReference, partialElements, unsafeCode); return @namespace; }
/// <summary> /// Initializes a new instance of the Method class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="returnType"> /// The method's return type. /// </param> /// <param name="parameters"> /// The parameters to the method. /// </param> /// <param name="typeConstraints"> /// The list of type constraints on the element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element resides within a block of unsafe code. /// </param> /// <param name="generated"> /// Indicates whether the code element was generated or written by hand. /// </param> internal Method( CsDocument document, CsElement parent, XmlHeader header, ICollection <Attribute> attributes, Declaration declaration, TypeToken returnType, IList <Parameter> parameters, ICollection <TypeParameterConstraintClause> typeConstraints, bool unsafeCode, bool generated) : base(document, parent, ElementType.Method, "method " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parent, "parent"); Param.Ignore(header); Param.Ignore(attributes); Param.AssertNotNull(declaration, "declaration"); Param.Ignore(returnType); Param.AssertNotNull(parameters, "parameters"); Param.Ignore(typeConstraints); Param.Ignore(unsafeCode); Param.Ignore(generated); Debug.Assert( returnType != null || declaration.ContainsModifier(CsTokenType.Explicit, CsTokenType.Implicit), "A method's return type can only be null in an explicit or implicit operator overload method."); this.returnType = returnType; this.parameters = parameters; this.typeConstraints = typeConstraints; Debug.Assert(parameters.IsReadOnly, "The parameters collection should be read-only."); // Determine whether this is an extension method. The method must be static. if (this.parameters.Count > 0 && this.Declaration.ContainsModifier(CsTokenType.Static)) { // Look at this first parameter. Since the parameters collection is not an indexable list, the // easiest way to do this is to foreach through the parameter list and break after the first one. foreach (Parameter parameter in this.parameters) { if ((parameter.Modifiers & ParameterModifiers.This) != 0) { this.extensionMethod = true; } break; } } // Add the qualifications. this.QualifiedName = CodeParser.AddQualifications(this.parameters, this.QualifiedName); // If this is an explicit interface member implementation and our access modifier // is currently set to private because we don't have one, then it should be public instead. if (this.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1 && !this.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } // Set the parent of the type constraint clauses. if (typeConstraints != null) { foreach (TypeParameterConstraintClause constraint in typeConstraints) { constraint.ParentElement = this; } } }
/// <summary> /// Parses and returns a using directive. /// </summary> /// <param name="parent"> /// The parent of the namespace. /// </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> /// <returns> /// Returns the element. /// </returns> private UsingDirective ParseUsingDirective(CsElement parent, Reference<ICodePart> elementReference, bool unsafeCode, bool generated) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(unsafeCode); Param.Ignore(generated); // Add the using token. Node<CsToken> firstToken = this.tokens.InsertLast(this.GetToken(CsTokenType.Using, SymbolType.Using, elementReference)); int index = this.GetNextCodeSymbolIndex(2); if (index == -1) { throw this.CreateSyntaxException(); } // Check static word introduce in C# 6 Symbol staticSymbol = this.symbols.Peek(index); if (staticSymbol != null && staticSymbol.SymbolType == SymbolType.Static) { CsToken staticToken = this.GetToken(CsTokenType.Static, SymbolType.Static, elementReference); this.tokens.Add(staticToken); } // The next symbol will either be the namespace, or an alias. To determine this, look past this to see if there is an equals sign. Symbol peekAhead = this.GetNextSymbol(SymbolType.Other, elementReference); index = this.GetNextCodeSymbolIndex(2); if (index == -1) { throw this.CreateSyntaxException(); } CsToken alias = null; peekAhead = this.symbols.Peek(index); if (peekAhead.SymbolType == SymbolType.Equals) { // There is an alias. First collect the alias. alias = this.GetToken(CsTokenType.Other, SymbolType.Other, elementReference); this.tokens.Add(alias); // Next collect the equals sign. this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, elementReference)); } // Collect and add the namespace token. TypeToken @namespace = this.GetTypeToken(elementReference, unsafeCode, false); this.tokens.Add(@namespace); // Create the declaration. CsTokenList declarationTokens = new CsTokenList(this.tokens, firstToken, this.tokens.Last); Declaration declaration = new Declaration( declarationTokens, alias == null ? @namespace.Text : alias.Text, ElementType.UsingDirective, AccessModifierType.Public); // Get the closing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); // Create the using directive. UsingDirective element = new UsingDirective(this.document, parent, declaration, generated, @namespace.Text, alias == null ? null : alias.Text); elementReference.Target = element; return element; }
/// <summary> /// Parses and returns an <see cref="Enum"/>. /// </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 Enum ParseEnum( 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; // The access defaults to public for a top-level element, or private for a nested element. AccessModifierType accessModifier = AccessModifierType.Public; if (parent.ElementType == ElementType.Class || parent.ElementType == ElementType.Struct) { accessModifier = AccessModifierType.Private; } // Get the modifiers and access. Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, EnumModifiers); // Get the enum keyword. this.tokens.Add(this.GetToken(CsTokenType.Enum, SymbolType.Enum, elementReference)); // Add the enum name token. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(name); // Get the base type. Symbol symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType == SymbolType.Colon) { // Add the colon token and the base item name. this.tokens.Add(this.GetToken(CsTokenType.BaseColon, SymbolType.Colon, elementReference)); this.tokens.Add(this.GetTypeToken(elementReference, unsafeCode, false)); } // 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, name.Text, ElementType.Enum, accessModifier, modifiers); // Create the enum element. Enum @enum = new Enum(this.document, parent, xmlHeader, attributes, declaration, unsafeCode, generated); elementReference.Target = @enum; // Get the opening curly bracket. Bracket openingCurlyBracket = this.GetBracketToken(CsTokenType.OpenCurlyBracket, SymbolType.OpenCurlyBracket, elementReference); Node<CsToken> openingCurlyBracketNode = this.tokens.InsertLast(openingCurlyBracket); // Get each of the enum items. @enum.Items = this.ParseEnumItems(@enum, elementReference, unsafeCode); // Get the closing curly bracket. Bracket closingCurlyBracket = this.GetBracketToken(CsTokenType.CloseCurlyBracket, SymbolType.CloseCurlyBracket, elementReference); Node<CsToken> closingCurlyBracketNode = this.tokens.InsertLast(closingCurlyBracket); openingCurlyBracket.MatchingBracketNode = closingCurlyBracketNode; closingCurlyBracket.MatchingBracketNode = openingCurlyBracketNode; return @enum; }
/// <summary> /// Sets the inherited items of the class. /// </summary> /// <param name="declaration"> /// The class declaration. /// </param> protected void SetInheritedItems(Declaration declaration) { Param.RequireNotNull(declaration, "declaration"); // Pull out the name of the base class and any implemented interfaces // from the declaration of this class. bool colon = false; bool comma = false; List<string> interfaces = new List<string>(); foreach (CsToken token in declaration.Tokens) { if (colon) { if (token.CsTokenType != CsTokenType.WhiteSpace && token.CsTokenType != CsTokenType.EndOfLine && token.CsTokenType != CsTokenType.SingleLineComment && token.CsTokenType != CsTokenType.MultiLineComment && token.CsTokenType != CsTokenType.PreprocessorDirective) { if (token.Text.Length >= 2 && token.Text[0] == 'I' && char.IsUpper(token.Text[1])) { interfaces.Add(CodeParser.TrimType(token.Text)); } else { this.baseClass = CodeParser.TrimType(token.Text); } colon = false; } } else if (comma) { if (token.CsTokenType != CsTokenType.WhiteSpace && token.CsTokenType != CsTokenType.EndOfLine && token.CsTokenType != CsTokenType.SingleLineComment && token.CsTokenType != CsTokenType.MultiLineComment && token.CsTokenType != CsTokenType.PreprocessorDirective) { interfaces.Add(CodeParser.TrimType(token.Text)); comma = false; } } else { if (token.CsTokenType == CsTokenType.Where) { break; } else if (token.Text == ":") { if (this.baseClass.Length > 0) { break; } else { colon = true; } } else if (token.CsTokenType == CsTokenType.Comma) { comma = true; } } } if (interfaces.Count > 0) { this.implementedInterfaces = interfaces.ToArray(); } }
/// <summary> /// Parses and returns the items within an <see cref="Enum"/> element. /// </summary> /// <param name="parent"> /// The parent <see cref="Enum"/> element. /// </param> /// <param name="parentReference"> /// Reference to the parent of the items we're creating. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code is marked as unsafe. /// </param> /// <returns> /// Returns the element. /// </returns> private ICollection<EnumItem> ParseEnumItems(Enum parent, Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(parent, "parent"); Param.Ignore(unsafeCode); Param.AssertNotNull(parentReference, "parentReference"); List<EnumItem> enumItems = new List<EnumItem>(); SkipSymbols skip = SkipSymbols.All; skip &= ~SkipSymbols.XmlHeader; Symbol symbol = this.GetNextSymbol(skip, parentReference); while (symbol.SymbolType != SymbolType.CloseCurlyBracket) { // Get the enum header. XmlHeader xmlHeader = null; ICollection<Attribute> attributes; Reference<ICodePart> enumItemReference = new Reference<ICodePart>(); this.MoveToElementDeclaration(parent, parentReference, enumItemReference, unsafeCode, out xmlHeader, out attributes); // If the next symbol is a close curly bracket, quit. symbol = this.GetNextSymbol(enumItemReference); if (symbol.SymbolType == SymbolType.CloseCurlyBracket) { break; } // Get the enum item name. Node<CsToken> firstEnumItemToken = this.tokens.InsertLast(this.GetToken(CsTokenType.Other, SymbolType.Other, enumItemReference)); Expression initializationExpression = null; // See if there is an equals sign. symbol = this.GetNextSymbol(enumItemReference); if (symbol.SymbolType == SymbolType.Equals) { this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, enumItemReference)); // Get the constant expression being assigned. initializationExpression = this.GetNextExpression(ExpressionPrecedence.None, enumItemReference, unsafeCode); } CsTokenList enumItemTokens = new CsTokenList(this.tokens, firstEnumItemToken, this.tokens.Last); Declaration enumItemDeclaration = new Declaration(enumItemTokens, firstEnumItemToken.Value.Text, ElementType.EnumItem, AccessModifierType.Public); EnumItem enumItem = new EnumItem( this.document, parent, xmlHeader, attributes, enumItemDeclaration, initializationExpression, unsafeCode, this.symbols.Generated); enumItemReference.Target = enumItem; enumItem.Tokens = new CsTokenList(this.tokens, firstEnumItemToken, this.tokens.Last); enumItems.Add(enumItem); // Add any suppressed rules. this.AddRuleSuppressionsForElement(enumItem); parent.AddElement(enumItem); symbol = this.GetNextSymbol(parentReference); // If the symbol is not a comma, quit. if (symbol.SymbolType == SymbolType.Comma) { this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, parentReference)); } else { break; } symbol = this.GetNextSymbol(skip, parentReference); } // Return the enum items as a read-only collection. return enumItems.ToArray(); }
/// <summary> /// Parses and returns a destructor. /// </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 Destructor ParseDestructor( 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; Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, DestructorModifiers); unsafeCode |= modifiers.ContainsKey(CsTokenType.Unsafe); // Move past the tilde symbol. this.tokens.Add(this.GetToken(CsTokenType.DestructorTilde, SymbolType.Tilde, elementReference)); // Get the name of the destructor. CsToken nameToken = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(nameToken); string destructorName = "~" + nameToken.Text; // Get the opening and closing parenthesis. Bracket openingParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, elementReference); Node<CsToken> openingParenthesisNode = this.tokens.InsertLast(openingParenthesis); Bracket closingParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, elementReference); Node<CsToken> closingParenthesisNode = this.tokens.InsertLast(closingParenthesis); openingParenthesis.MatchingBracketNode = closingParenthesisNode; closingParenthesis.MatchingBracketNode = openingParenthesisNode; // 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, destructorName, ElementType.Destructor, accessModifier, modifiers); Destructor destructor = new Destructor(this.document, parent, xmlHeader, attributes, declaration, unsafeCode, generated); elementReference.Target = destructor; // If the destructor is extern, it will not have a body. if (modifiers.ContainsKey(CsTokenType.Extern)) { // Get the closing semicolon. this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); } else { // Get the body. this.ParseStatementContainer(destructor, true, unsafeCode); } return destructor; }
/// <summary> /// Initializes a new instance of the CsElement class. /// </summary> /// <param name="document"> /// The document that contains the element. /// </param> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="type"> /// The element type. /// </param> /// <param name="name"> /// The name of this element. /// </param> /// <param name="header"> /// The Xml header for this element. /// </param> /// <param name="attributes"> /// The list of attributes attached to this element. /// </param> /// <param name="declaration"> /// The declaration code for this element. /// </param> /// <param name="unsafeCode"> /// Indicates whether the element is unsafe. /// </param> /// <param name="generated"> /// Indicates whether the element was generated or written by hand. /// </param> internal CsElement( CsDocument document, CsElement parent, ElementType type, string name, XmlHeader header, ICollection <Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(CodePartType.Element) { Param.AssertNotNull(document, "document"); Param.Ignore(parent); Param.Ignore(type); Param.AssertNotNull(name, "name"); Param.Ignore(header); Param.Ignore(attributes); Param.Ignore(declaration); Param.Ignore(unsafeCode); Param.Ignore(generated); this.document = document; if (this.document == null) { throw new ArgumentException(Strings.DocumentMustBeCsDocument, "document"); } if (parent != null && parent.Document != document) { throw new ArgumentException(Strings.ElementMustBeInParentsDocument, "parent"); } this.type = type; this.name = CodeLexer.DecodeEscapedText(name, true); this.header = header; this.attributes = attributes; this.declaration = declaration; this.unsafeCode = unsafeCode; this.generated = generated; if (!unsafeCode && this.declaration.ContainsModifier(CsTokenType.Unsafe)) { this.unsafeCode = true; } // Fill in the element reference in the header object. if (this.header != null) { Debug.Assert(this.header.Element == null, "The header element should not be empty."); this.header.Element = this; } // Fill in the element reference in the attributes list items. if (this.attributes != null) { Debug.Assert(this.attributes.IsReadOnly, "The attributes collection should be read-only."); foreach (Attribute attribute in this.attributes) { Debug.Assert(attribute.Element == null, "The attribute element should not be empty"); attribute.Element = this; } } // Set the fully qualified base name if (parent != null) { this.fullyQualifiedBase = parent.FullyQualifiedName; this.MergeAccess(parent.ActualAccess); } else { if (this.declaration != null) { this.actualAccess = this.declaration.AccessModifierType; } else { this.actualAccess = AccessModifierType.Public; } } // Set the fully qualified name this.fullyQualifiedName = this.fullyQualifiedBase; if (this.declaration != null && this.declaration.Name != null && this.declaration.Name.Length > 0) { if (this.fullyQualifiedBase != null && this.fullyQualifiedBase.Length > 0) { this.fullyQualifiedName += "."; } int index = this.declaration.Name.LastIndexOf("\\", StringComparison.Ordinal); if (index != -1) { this.fullyQualifiedName += this.declaration.Name.Substring(index + 1, this.declaration.Name.Length - index - 1); } else { this.fullyQualifiedName += this.declaration.Name; } index = this.fullyQualifiedName.IndexOf(".cs.", StringComparison.OrdinalIgnoreCase); if (-1 == index) { this.fullNamespaceName = this.fullyQualifiedName; } else { this.fullNamespaceName = this.fullyQualifiedName.Substring(index + 4, this.fullyQualifiedName.Length - index - 4); } } // There is only one type of element which is allowed to have a token // list consisting of nothing other than whitespace, newlines, etc., // which is the document root. This happens if you have a document which // contains nothing other than whitespace. Due to this we do not want to // trim down the token list for the root element, but we do want to for // all other types of elements. if (type == ElementType.Root) { this.TrimTokens = false; } }
/// <summary> /// Parses the contents of the document. /// </summary> internal void ParseDocument() { Debug.Assert(this.document == null, "A CodeParser instance may only be used once."); // Find the list of symbols in the document. List<Symbol> symbolList = this.lexer.GetSymbols(this.lexer.SourceCode, this.lexer.SourceCode.Project.Configuration); // Create the symbol manager class. this.symbols = new SymbolManager(symbolList); // Create the document object. this.document = new CsDocument(this.lexer.SourceCode, this.parser, this.tokens); Reference<ICodePart> documentRootReference = new Reference<ICodePart>(); // Get the file header if it exists. FileHeader fileHeader = this.GetFileHeader(documentRootReference); // Let the symbol manager know if this document contains generated code. if (fileHeader.Generated) { this.symbols.IncrementGeneratedCodeBlocks(); } this.document.FileHeader = fileHeader; // Create a declaration for the root element. Declaration declaration = new Declaration( new CsTokenList(this.document.Tokens), Strings.Root, ElementType.Root, AccessModifierType.Public, new Dictionary<CsTokenType, CsToken>()); // Create the root element for the document. DocumentRoot root = new DocumentRoot(this.document, declaration, fileHeader.Generated); documentRootReference.Target = root; // Parse the contents of the document. this.ParseElementContainerBody(root, documentRootReference, this.parser.PartialElements, false); // Check if there are any tokens in the document. if (this.document.Tokens.Count > 0) { // Fill in the token list for the root element. root.Tokens = new CsTokenList(this.document.Tokens, this.document.Tokens.First, this.document.Tokens.Last); // Fill in the location for the element. root.Location = CsToken.JoinLocations(this.document.Tokens.First, this.document.Tokens.Last); } // Add the root element to the document. this.document.RootElement = root; // When in debug mode, ensure that all tokens are correctly mapped to a parent element. this.DebugValidateParentReferences(); }
/// <summary> /// Parses and returns an empty element. /// </summary> /// <param name="parent"> /// The parent of the namespace. /// </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> /// <returns> /// Returns the element. /// </returns> private EmptyElement ParseEmptyElement(CsElement parent, Reference<ICodePart> elementReference, bool unsafeCode, bool generated) { Param.AssertNotNull(parent, "parent"); Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(unsafeCode); Param.Ignore(generated); this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon, elementReference)); // Create the declaration. CsTokenList declarationTokens = new CsTokenList(this.tokens, this.tokens.Last, this.tokens.Last); Declaration declaration = new Declaration(declarationTokens, string.Empty, ElementType.EmptyElement, AccessModifierType.Public); // Create the element. EmptyElement element = new EmptyElement(this.document, parent, declaration, unsafeCode, generated); elementReference.Target = element; return element; }