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)); }
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()); } } } } }
/// <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); }
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)); }
/// <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); }
public override void VisitXmlElement(XmlElementSyntax node) { Debug.Fail(node.ToString()); base.VisitXmlElement(node); }
/// <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); }