/// <summary> /// Initializes a new instance of the Destructor class. /// </summary> /// <param name="document">The documenent 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; } }
internal Field(CsDocument document, CsElement parent, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes, Declaration declaration, TypeToken fieldType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Field, "field " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { this.type = fieldType; this.isConst = base.Declaration.ContainsModifier(new CsTokenType[] { CsTokenType.Const }); this.isReadOnly = base.Declaration.ContainsModifier(new CsTokenType[] { CsTokenType.Readonly }); }
/// <summary> /// Initializes a new instance of the Field class. /// </summary> /// <param name="document">The documenent 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 or readonly. this.isConst = this.Declaration.ContainsModifier(CsTokenType.Const); this.isReadOnly = this.Declaration.ContainsModifier(CsTokenType.Readonly); }
/// <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; } } }
internal Method(CsDocument document, CsElement parent, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.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) { this.returnType = returnType; this.parameters = parameters; this.typeConstraints = typeConstraints; if ((this.parameters.Count > 0) && base.Declaration.ContainsModifier(new CsTokenType[] { CsTokenType.Static })) { foreach (Parameter parameter in this.parameters) { if ((parameter.Modifiers & ParameterModifiers.This) != ParameterModifiers.None) { this.extensionMethod = true; } break; } } base.QualifiedName = CodeParser.AddQualifications(this.parameters, base.QualifiedName); if ((base.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1) && !base.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { base.Declaration.AccessModifierType = AccessModifierType.Public; } if (typeConstraints != null) { foreach (TypeParameterConstraintClause clause in typeConstraints) { clause.ParentElement = this; } } }
/// <summary> /// Initializes a new instance of the 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); } }
internal Property(CsDocument document, CsElement parent, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes, Declaration declaration, TypeToken returnType, bool unsafeCode, bool generated) : base(document, parent, ElementType.Property, "property " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { this.returnType = returnType; if ((base.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1) && !base.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { base.Declaration.AccessModifierType = AccessModifierType.Public; } }
internal Indexer(CsDocument document, CsElement parent, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes, Declaration declaration, TypeToken returnType, IList<Parameter> parameters, bool unsafeCode, bool generated) : base(document, parent, ElementType.Indexer, "indexer " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { this.returnType = returnType; this.parameters = parameters; base.QualifiedName = CodeParser.AddQualifications(this.parameters, base.QualifiedName); if ((base.Declaration.Name.IndexOf(".", StringComparison.Ordinal) > -1) && !base.Declaration.Name.StartsWith("this.", StringComparison.Ordinal)) { base.Declaration.AccessModifierType = AccessModifierType.Public; } }
/// <summary> /// Initializes a new instance of the Constructor class. /// </summary> /// <param name="document">The documenent 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 always public. if (this.Declaration.ContainsModifier(CsTokenType.Static)) { this.Declaration.AccessModifierType = AccessModifierType.Public; } 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 Delegate 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 return type.</param> /// <param name="parameters">The parameters to the delegate.</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 this is generated code.</param> internal Delegate( 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.Delegate, "delegate " + 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.AssertNotNull(parameters, "parameters"); Param.Ignore(typeConstraints); Param.Ignore(unsafeCode); Param.Ignore(generated); this.returnType = returnType; this.typeConstraints = typeConstraints; 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); // Set the parent of the type constraint clauses. if (typeConstraints != null) { Debug.Assert(typeConstraints.IsReadOnly, "The collection of type constraints should be read-only."); foreach (TypeParameterConstraintClause constraint in typeConstraints) { constraint.ParentElement = this; } } }
internal ClassBase(CsDocument document, CsElement parent, ElementType type, string name, XmlHeader header, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes, Declaration declaration, ICollection<TypeParameterConstraintClause> typeConstraints, bool unsafeCode, bool generated) : base(document, parent, type, name, header, attributes, declaration, unsafeCode, generated) { this.baseClass = string.Empty; this.implementedInterfaces = new string[0]; this.typeConstraints = typeConstraints; if (typeConstraints != null) { foreach (TypeParameterConstraintClause clause in typeConstraints) { clause.ParentElement = this; } } }
/// <summary> /// Initializes a new instance of the Indexer class. /// </summary> /// <param name="document">The documenent 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 return type of the indexer.</param> /// <param name="parameters">The parameters to the indexer.</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 Indexer( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, TypeToken returnType, IList<Parameter> parameters, bool unsafeCode, bool generated) : base(document, parent, ElementType.Indexer, "indexer " + 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(unsafeCode); Param.Ignore(generated); this.returnType = returnType; 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 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 Namespace 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 Namespace( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, bool unsafeCode, bool generated) : base(document, parent, ElementType.Namespace, "namespace " + declaration.Name, header, attributes, declaration, unsafeCode, generated) { Param.Ignore(document, parent, header, attributes, declaration, unsafeCode, generated); }
/// <summary> /// Initializes a new instance of the Accessor class. /// </summary> /// <param name="document">The documenent 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 Interface 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 Interface( CsDocument document, CsElement parent, XmlHeader header, ICollection<Attribute> attributes, Declaration declaration, ICollection<TypeParameterConstraintClause> typeConstraints, bool unsafeCode, bool generated) : base(document, parent, ElementType.Interface, "interface " + 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 Property class. /// </summary> /// <param name="document">The documenent 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> /// 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> /// Parses the contents of the header for validity. /// </summary> /// <param name="element">The element.</param> /// <param name="header">The header.</param> /// <param name="lineNumber">The line number that the header element begins on.</param> /// <param name="partialElement">Indicates whether the element has the partial attribute.</param> private void ParseHeader(CsElement element, XmlHeader header, int lineNumber, bool partialElement) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(header, "header"); Param.AssertGreaterThanZero(lineNumber, "lineNumber"); Param.Ignore(partialElement); // Load this into an xml document. XmlDocument rawDocs = null; XmlDocument formattedDocs = null; this.LoadHeaderIntoDocuments(element, header, lineNumber, out rawDocs, out formattedDocs); if (rawDocs != null && formattedDocs != null) { // Insert any documentation present in 'include' tags. if (this.InsertIncludedDocumentation(element, Path.GetDirectoryName(element.Document.SourceCode.Path), formattedDocs)) { this.CheckForBlankLinesInDocumentationHeader(element, header); this.CheckHeaderSummary(element, lineNumber, partialElement, formattedDocs); // Check element parameters and return types. if (element.ElementType == ElementType.Method) { Method item = element as Method; this.CheckHeaderParams(element, item.Parameters, formattedDocs); this.CheckHeaderReturnValue(element, item.ReturnType, formattedDocs); } else if (element.ElementType == ElementType.Constructor) { Constructor item = element as Constructor; this.CheckHeaderParams(element, item.Parameters, formattedDocs); this.CheckConstructorSummaryText(item, formattedDocs); } else if (element.ElementType == ElementType.Delegate) { Microsoft.StyleCop.CSharp.Delegate item = element as Microsoft.StyleCop.CSharp.Delegate; this.CheckHeaderParams(element, item.Parameters, formattedDocs); this.CheckHeaderReturnValue(element, item.ReturnType, formattedDocs); } else if (element.ElementType == ElementType.Indexer) { Indexer item = element as Indexer; this.CheckHeaderParams(element, item.Parameters, formattedDocs); } else if (element.ElementType == ElementType.Property) { // Check value tags on properties. this.CheckPropertyValueTag(element, formattedDocs); // Check that the property summary starts with the correct text. this.CheckPropertySummaryFormatting(element as Property, formattedDocs); } else if (element.ElementType == ElementType.Destructor) { this.CheckDestructorSummaryText((Destructor)element, formattedDocs); } // Check for repeating comments on all element types which can contain params or typeparams. if (element.ElementType == ElementType.Method || element.ElementType == ElementType.Constructor || element.ElementType == ElementType.Delegate || element.ElementType == ElementType.Indexer || element.ElementType == ElementType.Class || element.ElementType == ElementType.Struct || element.ElementType == ElementType.Interface) { this.CheckForRepeatingComments(element, formattedDocs); } // Check generic type parameters. if (element.ElementType == ElementType.Class || element.ElementType == ElementType.Method || element.ElementType == ElementType.Delegate || element.ElementType == ElementType.Interface || element.ElementType == ElementType.Struct) { this.CheckGenericTypeParams(element, formattedDocs); } } } }
/// <summary> /// Loads the header text for the element into a document and returns it. /// </summary> /// <param name="element">The element containing the header.</param> /// <param name="header">The header to load.</param> /// <param name="lineNumber">The line number that the header begins on.</param> /// <param name="rawDocs">Returns the docs with whitepace and newlines left in place.</param> /// <param name="formattedDocs">Returns the docs with newlines filtered out.</param> private void LoadHeaderIntoDocuments(CsElement element, XmlHeader header, int lineNumber, out XmlDocument rawDocs, out XmlDocument formattedDocs) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(header, "header"); Param.AssertGreaterThanZero(lineNumber, "lineNumber"); rawDocs = new XmlDocument(); formattedDocs = new XmlDocument(); try { string correctxml = "<root>" + header.RawText + "</root>"; rawDocs.LoadXml(correctxml); correctxml = "<root>" + header.Text + "</root>"; formattedDocs.LoadXml(correctxml); } catch (XmlException xmlex) { this.AddViolation(element, lineNumber, Rules.DocumentationMustContainValidXml, xmlex.Message); rawDocs = formattedDocs = null; } }
/// <summary> /// Checks the documentation header to see whether it contains any blank lines. /// </summary> /// <param name="element">The element containing the header.</param> /// <param name="header">The documentation header.</param> private void CheckForBlankLinesInDocumentationHeader(CsElement element, XmlHeader header) { Param.AssertNotNull(element, "element"); Param.AssertNotNull(header, "header"); if (!element.Generated) { int blankLineCount = 0; for (Node<CsToken> tokenNode = header.ChildTokens.First; tokenNode != null && tokenNode != header.ChildTokens.Last.Next; tokenNode = tokenNode.Next) { CsToken token = tokenNode.Value; if (token.CsTokenType == CsTokenType.EndOfLine) { ++blankLineCount; if (blankLineCount > 1) { this.AddViolation(element, token.LineNumber, Rules.DocumentationHeadersMustNotContainBlankLines); break; } } else if (token.CsTokenType == CsTokenType.XmlHeaderLine) { if (tokenNode == header.ChildTokens.First || tokenNode == header.ChildTokens.Last) { if (IsXmlHeaderLineEmpty(token)) { this.AddViolation(element, token.LineNumber, Rules.DocumentationHeadersMustNotContainBlankLines); break; } } else if (!IsXmlHeaderLineEmpty(token)) { blankLineCount = 0; } } } } }
/// <summary> /// Gets an xml header. /// </summary> /// <param name="elementReference">A reference to the element being created.</param> /// <returns>Returns the header or null if there is no header.</returns> private XmlHeader GetXmlHeader(Reference<ICodePart> elementReference) { Param.AssertNotNull(elementReference, "elementReference"); // Get the first symbol and make sure it is the right type. int index = 1; Symbol firstSymbol = this.symbols.Peek(index); Debug.Assert(firstSymbol != null && firstSymbol.SymbolType == SymbolType.XmlHeaderLine, "Expected an xml documentation header line"); // Marks the end of the header. int end = -1; int endOfLineCount = 0; var xmlHeaderReference = new Reference<ICodePart>(); // Loop until the entire header is found. Symbol symbol = firstSymbol; while (symbol != null) { if (symbol.SymbolType == SymbolType.XmlHeaderLine) { // This type of token belongs in the header. end = index; endOfLineCount = 0; } else if (symbol.SymbolType == SymbolType.EndOfLine) { if (++endOfLineCount > 1) { // If there are two newlines in a row, this is the // end of the Xml header. break; } } else if (symbol.SymbolType == SymbolType.WhiteSpace || symbol.SymbolType == SymbolType.SingleLineComment) { endOfLineCount = 0; } else { // This is the end of the header. break; } // Advance the index and get the next symbol. symbol = this.symbols.Peek(++index); } // Make sure we've advanced at least one symbol. Debug.Assert(end != -1, "Should have advanced at least one symbol"); // Add all of the symbols for the header to a token list. MasterList<CsToken> headerTokens = new MasterList<CsToken>(); for (int i = 1; i <= end; ++i) { this.symbols.Advance(); Debug.Assert(this.symbols.Current != null, "The current symbol should not be null"); headerTokens.Add(this.ConvertSymbol(this.symbols.Current, TokenTypeFromSymbolType(this.symbols.Current.SymbolType), xmlHeaderReference)); } // Get the location of the header. CodeLocation location = CodeLocation.Join(firstSymbol.Location, this.symbols.Current.Location); // Create the Xml header object. var xmlHeader = new XmlHeader(headerTokens, location, elementReference, this.symbols.Generated); xmlHeaderReference.Target = xmlHeader; return xmlHeader; }
/// <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 return type. TypeToken returnType = this.GetTypeToken(elementReference, unsafeCode, true); this.tokens.Add(returnType); // Get the name of the property. CsToken name = this.GetElementNameToken(elementReference, unsafeCode); this.tokens.Add(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, returnType, unsafeCode, generated); elementReference.Target = property; // Parse the body of the property. this.ParseElementContainer(property, elementReference, null, unsafeCode); return property; }
/// <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> /// 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; // Methods within interfaces always have the access of the parent interface. Interface parentInterface = parent as Interface; if (parentInterface != null) { accessModifier = parentInterface.AccessModifier; } // Get the declared modifiers for the method. Dictionary<CsTokenType, CsToken> modifiers = this.GetElementModifiers(elementReference, ref accessModifier, MethodModifiers); 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. this.ParseStatementContainer(method, true, unsafeCode); } return method; }
/// <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 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); var 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. var 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> /// Parses and returns an 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> /// 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)); var element = new Delegate( this.document, parent, xmlHeader, attributes, declaration, returnType, parameters, typeConstraints, unsafeCode, generated); elementReference.Target = element; return element; }
private void CheckXmlHeaderComment(DocumentRoot root, XmlHeader header) { for (Node<CsToken> node = header.ChildTokens.First; node != null; node = node.Next) { CsToken token = node.Value; if ((token.CsTokenType == CsTokenType.XmlHeaderLine) && (token.Text.Length > 3)) { if ((((token.Text[3] != ' ') && (token.Text[3] != '\t')) && ((token.Text[3] != '/') && (token.Text[2] != '\n'))) && (token.Text[2] != '\r')) { base.AddViolation(root, token.LineNumber, Microsoft.StyleCop.CSharp.Rules.DocumentationLinesMustBeginWithSingleSpace, new object[0]); continue; } if ((token.Text.Length > 4) && ((token.Text[4] == ' ') || (token.Text[4] == '\t'))) { bool flag = true; for (Node<CsToken> node2 = node.Previous; node2 != null; node2 = node2.Previous) { if (node2.Value.CsTokenType == CsTokenType.XmlHeaderLine) { for (Node<CsToken> node3 = node.Next; node3 != null; node3 = node3.Next) { if (node3.Value.CsTokenType == CsTokenType.XmlHeaderLine) { flag = false; break; } } break; } } if (flag) { base.AddViolation(root, token.LineNumber, Microsoft.StyleCop.CSharp.Rules.DocumentationLinesMustBeginWithSingleSpace, new object[0]); } } } } }
/// <summary> /// Parses and returns an element. /// </summary> /// <param name="elementType">The type of element to parse.</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 CsElement ParseElement( 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.Ignore(partialElements); Param.Ignore(unsafeCode); Param.Ignore(generated); Param.Ignore(xmlHeader); Param.Ignore(attributes); switch (elementType) { case ElementType.Namespace: return this.ParseNamespace(parent, elementReference, partialElements, unsafeCode, generated, xmlHeader, attributes); case ElementType.ExternAliasDirective: return this.ParseExternAliasDirective(parent, elementReference, generated); case ElementType.UsingDirective: return this.ParseUsingDirective(parent, elementReference, unsafeCode, generated); case ElementType.Class: case ElementType.Struct: case ElementType.Interface: return this.ParseClass(elementType, parent, elementReference, partialElements, unsafeCode, generated, xmlHeader, attributes); case ElementType.Enum: return this.ParseEnum(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Delegate: return this.ParseDelegate(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Field: return this.ParseField(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Method: return this.ParseMethod(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Constructor: return this.ParseConstructor(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Destructor: return this.ParseDestructor(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Property: return this.ParseProperty(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Indexer: return this.ParseIndexer(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Event: return this.ParseEvent(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.Accessor: return this.ParseAccessor(parent, elementReference, unsafeCode, generated, xmlHeader, attributes); case ElementType.EmptyElement: return this.ParseEmptyElement(parent, elementReference, unsafeCode, generated); default: Debug.Fail("Unexpected element type."); throw new StyleCopException(); } }