/// <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;
        }
Beispiel #2
0
        /// <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(destructor));
                }
            }
        }
Beispiel #3
0
 /// <summary>
 /// Gets the example expected summary text for a destructor.
 /// </summary>
 /// <param name="destructor">
 /// The destructor.
 /// </param>
 /// <returns>
 /// Returns the example summary text.
 /// </returns>
 private static string GetExampleSummaryTextForDestructor(Destructor destructor)
 {
     return string.Format(CultureInfo.InvariantCulture, CachedCodeStrings.ExampleHeaderSummaryForDestructor, destructor.Declaration.Name.Substring(1));
 }
        /// <summary>
        /// The save.
        /// </summary>
        /// <param name="destructor">
        /// The destructor.
        /// </param>
        private void Save(Destructor destructor)
        {
            // 1 to destHeader
            this.SaveModifiersBefore(destructor);

            // 1 to destHeader
            this.headerWriter.Write(destructor.Declaration.Name);

            // 2 to Source
            this.cppWriter.Write(this.currentClassNamespace);
            this.cppWriter.Write("::");
            this.cppWriter.Write(destructor.Declaration.Name);

            this.SaveParametersAndBody(destructor);

            this.cppWriter.WriteLine();
        }