コード例 #1
0
        private static void AnalyzeSingleLineDocumentationCommentTrivia(SyntaxNodeAnalysisContext context)
        {
            var documentationComment = (DocumentationCommentTriviaSyntax)context.Node;

            XmlElementSyntax summaryElement = documentationComment.SummaryElement();

            if (summaryElement != null)
            {
                XmlElementStartTagSyntax startTag = summaryElement?.StartTag;

                if (startTag?.IsMissing == false)
                {
                    XmlElementEndTagSyntax endTag = summaryElement.EndTag;

                    if (endTag?.IsMissing == false &&
                        startTag.GetSpanEndLine() < endTag.GetSpanStartLine())
                    {
                        Match match = _regex.Match(
                            summaryElement.ToString(),
                            startTag.Span.End - summaryElement.SpanStart,
                            endTag.SpanStart - startTag.Span.End);

                        if (match.Success)
                        {
                            DiagnosticHelpers.ReportDiagnostic(context,
                                                               DiagnosticDescriptors.FormatDocumentationSummaryOnSingleLine,
                                                               summaryElement);
                        }
                    }
                }
            }
        }
        private static async Task <Document> FormatSummaryOnSingleLineAsync(
            Document document,
            DocumentationCommentTriviaSyntax documentationComment,
            CancellationToken cancellationToken)
        {
            SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            XmlElementSyntax summaryElement = documentationComment.SummaryElement();

            XmlElementStartTagSyntax startTag = summaryElement.StartTag;
            XmlElementEndTagSyntax   endTag   = summaryElement.EndTag;

            Match match = _formatSummaryOnSingleLineRegex.Match(
                summaryElement.ToString(),
                startTag.Span.End - summaryElement.SpanStart,
                endTag.SpanStart - startTag.Span.End);

            var textChange = new TextChange(
                new TextSpan(startTag.Span.End, match.Length),
                match.Groups[1].Value);

            SourceText newSourceText = sourceText.WithChanges(textChange);

            return(document.WithText(newSourceText));
        }
コード例 #3
0
        public static void Analyze(SyntaxNodeAnalysisContext context, DocumentationCommentTriviaSyntax documentationComment)
        {
            XmlElementSyntax summaryElement = FormatSummaryRefactoring.GetSummaryElement(documentationComment);

            if (summaryElement != null)
            {
                XmlElementStartTagSyntax startTag = summaryElement?.StartTag;

                if (startTag?.IsMissing == false)
                {
                    XmlElementEndTagSyntax endTag = summaryElement.EndTag;

                    if (endTag?.IsMissing == false &&
                        startTag.GetSpanEndLine() < endTag.GetSpanStartLine())
                    {
                        Match match = FormatSummaryRefactoring.Regex.Match(
                            summaryElement.ToString(),
                            startTag.Span.End - summaryElement.Span.Start,
                            endTag.Span.Start - startTag.Span.End);

                        if (match.Success)
                        {
                            context.ReportDiagnostic(
                                DiagnosticDescriptors.FormatDocumentationSummaryOnSingleLine,
                                summaryElement.GetLocation());
                        }
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Checks summary element.
        /// </summary>
        /// <param name="nodeKind">Kind of node.</param>
        /// <param name="xmlElement">The XML element.</param>
        /// <param name="location">Location.</param>
        /// <param name="message">Message.</param>
        /// <returns>True if there is no error.</returns>
        private static bool CheckSummaryElement(SyntaxKind nodeKind, XmlElementSyntax xmlElement, ref Location location, ref string message)
        {
            // Check xml start/end tags
            if (!BTAnalyzer.CheckXmlTags(xmlElement, ref location, ref message))
            {
                return(false);
            }

            // Set location
            location = xmlElement.StartTag.GetLocation();
            Position position = Position.Origin;

            // Check XML element text
            string[] lines = xmlElement.ToString().Split(new string[] { "///" }, StringSplitOptions.None);

            // Check
            int offset = lines[0].Length + 3;

            for (int i = 1; i < lines.Length; i++)
            {
                string trimmedLine = lines[i].TrimEnd(' ', '\r', '\n');
                if (' ' != trimmedLine[0])
                {
                    message  = ErrorCode.MissingSpace;
                    location = BTAnalyzer.GetLocation(xmlElement.SyntaxTree, location, new Position(0, 0), offset);
                    return(false);
                }

                // Ignore first and last lines
                if ((0 < i) && (i < lines.Length - 1))
                {
                    // Validate text
                    foreach (StringValidator.Validate validate in BTAnalyzer.GetSummaryValidator(nodeKind))
                    {
                        if (!validate(trimmedLine, ref message, ref position))
                        {
                            location = BTAnalyzer.GetLocation(xmlElement.SyntaxTree, location, position, offset);
                            return(false);
                        }
                    }
                }

                // Increase offset
                offset += lines[i].Length + 3;
            }

            // Return true
            return(true);
        }
コード例 #5
0
        private static Task <Document> FormatSummaryOnSingleLineAsync(
            Document document,
            DocumentationCommentTriviaSyntax documentationComment,
            CancellationToken cancellationToken)
        {
            XmlElementSyntax summaryElement = documentationComment.SummaryElement();

            XmlElementStartTagSyntax startTag = summaryElement.StartTag;
            XmlElementEndTagSyntax   endTag   = summaryElement.EndTag;

            Match match = _formatSummaryOnSingleLineRegex.Match(
                summaryElement.ToString(),
                startTag.Span.End - summaryElement.SpanStart,
                endTag.SpanStart - startTag.Span.End);

            return(document.WithTextChangeAsync(
                       new TextSpan(startTag.Span.End, match.Length),
                       match.Groups[1].Value,
                       cancellationToken));
        }
コード例 #6
0
        /// <summary>
        /// Checks param element.
        /// </summary>
        /// <param name="xmlElement">XML element.</param>
        /// <param name="location">Location.</param>
        /// <param name="message">Message.</param>
        /// <param name="paramCommentNameList">Parameter comment name list.</param>
        /// <returns>True if there is no error.</returns>
        private static bool CheckParamElement(XmlElementSyntax xmlElement, ref Location location, ref string message, ref List <string> paramCommentNameList)
        {
            // Check tags
            if (!BTAnalyzer.CheckXmlTags(xmlElement, ref location, ref message))
            {
                return(false);
            }

            // Set location
            location = xmlElement.StartTag.GetLocation();
            Position position = Position.Origin;

            // Add param name to the list
            XmlNameAttributeSyntax xmlNameAttribute = xmlElement.StartTag.Attributes.Where(attr => SyntaxKind.XmlNameAttribute == attr.Kind()).FirstOrDefault() as XmlNameAttributeSyntax;

            if (null == xmlNameAttribute)
            {
                message = ErrorCode.MissingNameAttribute;
                return(false);
            }
            paramCommentNameList.Add(xmlNameAttribute.Identifier.ToString());

            // Remove <see cref .. /> elements, remove start and end tags
            // Check XML element text
            string text = xmlElement.ToString().Replace(xmlElement.StartTag.ToString(), String.Empty).Replace(xmlElement.EndTag.ToString(), String.Empty).TrimStart('/');

            foreach (StringValidator.Validate validate in BTAnalyzer.ParamTextValidators)
            {
                if (!validate(text, ref message, ref position))
                {
                    location = BTAnalyzer.GetLocation(xmlElement.SyntaxTree, location, position, xmlElement.StartTag.ToString().Length);
                    return(false);
                }
            }

            // Return true
            return(true);
        }
コード例 #7
0
 public override void VisitXmlElement(XmlElementSyntax node)
 {
     Debug.Fail(node.ToString());
     base.VisitXmlElement(node);
 }
コード例 #8
0
        /// <summary>
        /// Checks returns element.
        /// </summary>
        /// <param name="xmlElement">XML element.</param>
        /// <param name="location">Location.</param>
        /// <param name="message">Message.</param>
        /// <param name="returnCount">Return count.</param>
        /// <returns>True if valid.</returns>
        private static bool CheckReturnElement(XmlElementSyntax xmlElement, ref Location location, ref string message, ref int returnCount)
        {
            // Check tags
            if (!BTAnalyzer.CheckXmlTags(xmlElement, ref location, ref message))
            {
                return(false);
            }

            // Increment number of <returns>
            returnCount++;

            // Set location
            location = xmlElement.StartTag.GetLocation();
            Position position = Position.Origin;

            // Check
            if (xmlElement.ToString().Contains("\r\n"))
            {
                string[] lines  = xmlElement.ToString().Split(new string[] { "///" }, StringSplitOptions.None);
                int      offset = lines[0].Length + 3;
                for (int i = 1; i < lines.Length; i++)
                {
                    string trimmedLine = lines[i].TrimEnd(' ', '\r', '\n');
                    if (' ' != trimmedLine[0])
                    {
                        message  = ErrorCode.MissingSpace;
                        location = BTAnalyzer.GetLocation(xmlElement.SyntaxTree, location, new Position(0, 0), offset);
                        return(false);
                    }

                    // Ignore first and last line
                    if ((0 < i) && (i < lines.Length - 1))
                    {
                        // Validate text
                        foreach (StringValidator.Validate validate in BTAnalyzer.ReturnTextValidators)
                        {
                            if (!validate(trimmedLine, ref message, ref position))
                            {
                                location = BTAnalyzer.GetLocation(xmlElement.SyntaxTree, location, position, offset);
                                return(false);
                            }
                        }
                    }

                    // Add offset, 3 for the removed ///
                    offset += lines[i].Length + 3;
                }
            }
            else
            {
                string text        = xmlElement.ToString().Replace(xmlElement.StartTag.ToString(), string.Empty).Replace(xmlElement.EndTag.ToString(), string.Empty);
                string trimmedLine = text.TrimEnd(' ', '\r', '\n');
                foreach (StringValidator.Validate validate in BTAnalyzer.ReturnTextValidators)
                {
                    if (!validate(trimmedLine, ref message, ref position))
                    {
                        location = BTAnalyzer.GetLocation(xmlElement.SyntaxTree, location, position, xmlElement.StartTag.ToString().Length);
                        return(false);
                    }
                }
            }

            // Return true
            return(true);
        }