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()); } } } } }
protected override void HandleInlineCodeElement(ref SyntaxNodeAnalysisContext context, XmlElementSyntax xmlElement) { // This rule will only apply if the content is a single XmlTextSyntax containing a single // XmlTextLiteralToken token if (xmlElement.Content.Count != 1) { return; } if (!(xmlElement.Content[0] is XmlTextSyntax xmlText)) { return; } if (xmlText.TextTokens.Count != 1) { return; } var semanticModel = context.SemanticModel; var documentedSymbol = semanticModel.GetDeclaredSymbol(xmlElement.FirstAncestorOrSelf <SyntaxNode>(SyntaxNodeExtensionsEx.IsSymbolDeclaration), context.CancellationToken); if (!documentedSymbol.HasAnyParameter(xmlText.TextTokens[0].ValueText, StringComparer.Ordinal)) { return; } context.ReportDiagnostic(Diagnostic.Create(Descriptor, xmlElement.GetLocation())); }
private static void HandleXmlElement(SyntaxNodeAnalysisContext context) { XmlElementSyntax element = (XmlElementSyntax)context.Node; var name = element.StartTag?.Name; if (string.Equals(name.ToString(), XmlCommentHelper.TypeParamXmlTag) && XmlCommentHelper.IsConsideredEmpty(element)) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, element.GetLocation())); } }
private void HandleXmlElement(SyntaxNodeAnalysisContext context) { XmlElementSyntax syntax = (XmlElementSyntax)context.Node; if (!string.Equals("placeholder", syntax.StartTag?.Name?.ToString(), StringComparison.Ordinal)) { return; } context.ReportDiagnostic(Diagnostic.Create(Descriptor, syntax.GetLocation())); }
private void HandleXmlElement(SyntaxNodeAnalysisContext context) { XmlElementSyntax emptyElement = context.Node as XmlElementSyntax; var name = emptyElement?.StartTag?.Name; if (string.Equals(name.ToString(), XmlCommentHelper.ReturnsXmlTag) && XmlCommentHelper.IsConsideredEmpty(emptyElement)) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, emptyElement.GetLocation())); } }
protected override void HandleInlineCodeElement(ref SyntaxNodeAnalysisContext context, XmlElementSyntax xmlElement) { // Currently this rule will only apply if the content is a single XmlTextSyntax containing a single // XmlTextLiteralToken token if (xmlElement.Content.Count != 1) { return; } if (!(xmlElement.Content[0] is XmlTextSyntax xmlText)) { return; } if (xmlText.TextTokens.Count != 1) { return; } var semanticModel = context.SemanticModel; var documentedSymbol = semanticModel.GetDeclaredSymbol(xmlElement.FirstAncestorOrSelf <SyntaxNode>(SyntaxNodeExtensionsEx.IsSymbolDeclaration), context.CancellationToken); var name = xmlText.TextTokens[0].ValueText; for (var currentSymbol = documentedSymbol; currentSymbol != null; currentSymbol = currentSymbol?.ContainingSymbol) { switch (currentSymbol.Kind) { case SymbolKind.NamedType: var namedType = (INamedTypeSymbol)currentSymbol; var matchingMembers = namedType.GetMembers(name); if (matchingMembers.Length != 1) { return; } if (matchingMembers[0].Kind == SymbolKind.Property || matchingMembers[0].Kind == SymbolKind.Field || matchingMembers[0].Kind == SymbolKind.Event) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, xmlElement.GetLocation())); } return; case SymbolKind.Namespace: case SymbolKind.NetModule: return; default: continue; } } }
public static void Analyze(SyntaxNodeAnalysisContext context, DocumentationCommentTriviaSyntax documentationComment) { XmlElementSyntax summaryElement = FormatSummaryRefactoring.GetSummaryElement(documentationComment); if (summaryElement?.StartTag?.IsMissing == false && summaryElement.EndTag?.IsMissing == false && summaryElement.IsSingleLine(includeExteriorTrivia: false, trim: false)) { context.ReportDiagnostic( DiagnosticDescriptors.FormatDocumentationSummaryOnMultipleLines, summaryElement.GetLocation()); } }
/// <summary> /// Checks XML start and end tags. /// </summary> /// <param name="xmlElement">XML element.</param> /// <param name="location">Location.</param> /// <param name="message">Message.</param> /// <returns>True if valid.</returns> private static bool CheckXmlTags(XmlElementSyntax xmlElement, ref Location location, ref string message) { // Start/End tag string startTag = xmlElement.StartTag.Name.ToString(); string endTag = xmlElement.EndTag.Name.ToString(); if (string.IsNullOrWhiteSpace(startTag) || string.IsNullOrWhiteSpace(endTag)) { message = ErrorCode.ErrorsInComment; location = xmlElement.GetLocation(); return(false); } // Only allows summary or param tag if (!BTAnalyzer.IsValidXmlCommentTag(startTag) || !BTAnalyzer.IsValidXmlCommentTag(endTag)) { message = ErrorCode.InvalidXmlTag; location = xmlElement.GetLocation(); return(false); } // Return true return(true); }
/// <summary> /// Checks that the XML element has valid content. /// </summary> /// <param name="context">Analysis context.</param> /// <param name="element">XML documentation element.</param> private static void EnsureNonEmptyContent( SyntaxNodeAnalysisContext context, XmlElementSyntax element) { // Check whether the content exists. if (string.IsNullOrWhiteSpace(element.Content.ToString())) { // Empty element. // Create the diagnostic message and report it. var diagnostic = Diagnostic.Create( XmlDocumentationNoEmptyContent.Rule, element.GetLocation(), element.StartTag.Name.ToString()); context.ReportDiagnostic(diagnostic); } }
private void AnalyzeDocumentationComment(SyntaxNodeAnalysisContext context) { if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true) { return; } var documentationComment = (DocumentationCommentTriviaSyntax)context.Node; XmlElementSyntax summaryElement = FormatSummaryRefactoring.GetSummaryElement(documentationComment); if (summaryElement?.StartTag?.IsMissing == false && summaryElement.EndTag?.IsMissing == false && summaryElement.IsSingleLine(includeExteriorTrivia: false, trim: false)) { context.ReportDiagnostic( DiagnosticDescriptors.FormatDocumentationSummaryOnMultipleLines, summaryElement.GetLocation()); } }
protected override void HandleInlineCodeElement(ref SyntaxNodeAnalysisContext context, XmlElementSyntax xmlElement) { // This rule will only apply if the content is a single XmlTextSyntax containing a single // XmlTextLiteralToken token if (xmlElement.Content.Count != 1) { return; } if (!(xmlElement.Content[0] is XmlTextSyntax xmlText)) { return; } if (xmlText.TextTokens.Count != 1) { return; } switch (xmlText.TextTokens[0].ValueText) { case "null": case "static": case "virtual": case "true": case "false": case "abstract": case "sealed": case "async": case "await": break; default: return; } context.ReportDiagnostic(Diagnostic.Create(Descriptor, xmlElement.GetLocation())); }