/// <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> /// Checks a destructor to ensure that the summary text matches the expected text. /// </summary> /// <param name="destructor">The destructor to check.</param> /// <param name="formattedDocs">The formatted header documentation.</param> private void CheckDestructorSummaryText(Destructor destructor, XmlDocument formattedDocs) { Param.AssertNotNull(destructor, "destructor"); Param.AssertNotNull(formattedDocs, "formattedDocs"); XmlNode node = formattedDocs.SelectSingleNode("root/summary"); if (node != null) { string summaryText = node.InnerXml.Trim(); // Get a regex to match the type name. string typeRegex = BuildCrefValidationStringForType((ClassBase)destructor.FindParentElement()); // Get the full expected summary text. string expectedRegex = GetExpectedSummaryTextForDestructor(typeRegex); if (!Regex.IsMatch(summaryText, expectedRegex)) { this.AddViolation( destructor, Rules.DestructorSummaryDocumentationMustBeginWithStandardText, GetExampleSummaryTextForDestructor()); } } }
private Destructor ParseDestructor(CsElement parent, bool unsafeCode, bool generated, XmlHeader xmlHeader, ICollection<Microsoft.StyleCop.CSharp.Attribute> attributes) { Microsoft.StyleCop.Node<CsToken> last = this.tokens.Last; AccessModifierType @private = AccessModifierType.Private; Dictionary<CsTokenType, CsToken> elementModifiers = this.GetElementModifiers(ref @private, DestructorModifiers); unsafeCode |= elementModifiers.ContainsKey(CsTokenType.Unsafe); this.tokens.Add(this.GetToken(CsTokenType.DestructorTilde, SymbolType.Tilde)); CsToken elementNameToken = this.GetElementNameToken(unsafeCode); this.tokens.Add(elementNameToken); string name = "~" + elementNameToken.Text; Bracket bracketToken = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis); Microsoft.StyleCop.Node<CsToken> node2 = this.tokens.InsertLast(bracketToken); Bracket item = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis); Microsoft.StyleCop.Node<CsToken> node3 = this.tokens.InsertLast(item); bracketToken.MatchingBracketNode = node3; item.MatchingBracketNode = node2; Microsoft.StyleCop.Node<CsToken> firstItemNode = (last == null) ? this.tokens.First : last.Next; CsTokenList tokens = new CsTokenList(this.tokens, firstItemNode, this.tokens.Last); Declaration declaration = new Declaration(tokens, name, ElementType.Destructor, @private, elementModifiers); Destructor element = new Destructor(this.document, parent, xmlHeader, attributes, declaration, unsafeCode, generated); if (elementModifiers.ContainsKey(CsTokenType.Extern)) { this.tokens.Add(this.GetToken(CsTokenType.Semicolon, SymbolType.Semicolon)); return element; } this.ParseStatementContainer(element, true, unsafeCode); return element; }