private static bool CanAddExceptionToComment( DocumentationCommentTriviaSyntax comment, INamedTypeSymbol exceptionSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { bool containsException = false; bool containsIncludeOrExclude = false; bool isFirst = true; foreach (XmlNodeSyntax node in comment.Content) { XmlElementInfo info = SyntaxInfo.XmlElementInfo(node); if (info.Success) { switch (info.GetElementKind()) { case XmlElementKind.Include: case XmlElementKind.Exclude: { if (isFirst) { containsIncludeOrExclude = true; } break; } case XmlElementKind.InheritDoc: { return(false); } case XmlElementKind.Exception: { if (!containsException) { if (info.IsEmptyElement) { containsException = ContainsException((XmlEmptyElementSyntax)info.Element, exceptionSymbol, semanticModel, cancellationToken); } else { containsException = ContainsException((XmlElementSyntax)info.Element, exceptionSymbol, semanticModel, cancellationToken); } } break; } } if (isFirst) { isFirst = false; } else { containsIncludeOrExclude = false; } } } return(!containsIncludeOrExclude && !containsException); }
private static void AnalyzeSingleLineDocumentationCommentTrivia(SyntaxNodeAnalysisContext context) { var documentationComment = (DocumentationCommentTriviaSyntax)context.Node; if (!documentationComment.IsPartOfMemberDeclaration()) { return; } bool containsInheritDoc = false; bool containsIncludeOrExclude = false; bool containsSummaryElement = false; bool containsContentElement = false; bool isFirst = true; CancellationToken cancellationToken = context.CancellationToken; SyntaxList <XmlNodeSyntax> content = documentationComment.Content; for (int i = 0; i < content.Count; i++) { cancellationToken.ThrowIfCancellationRequested(); XmlElementInfo info = SyntaxInfo.XmlElementInfo(content[i]); if (info.Success) { switch (info.GetElementKind()) { case XmlElementKind.Include: case XmlElementKind.Exclude: { if (isFirst) { containsIncludeOrExclude = true; } break; } case XmlElementKind.InheritDoc: { containsInheritDoc = true; break; } case XmlElementKind.Content: { containsContentElement = true; break; } case XmlElementKind.Summary: { if (info.IsContentEmptyOrWhitespace) { ReportDiagnosticIfNotSuppressed(context, DiagnosticDescriptors.AddSummaryToDocumentationComment, info.Element); } containsSummaryElement = true; break; } case XmlElementKind.Code: case XmlElementKind.Example: case XmlElementKind.Remarks: case XmlElementKind.Returns: case XmlElementKind.Value: { if (info.IsContentEmptyOrWhitespace) { ReportUnusedElement(context, info.Element, i, content); } break; } } if (isFirst) { isFirst = false; } else { containsIncludeOrExclude = false; } } } if (containsInheritDoc || containsIncludeOrExclude) { return; } if (!containsSummaryElement && !containsContentElement) { ReportDiagnosticIfNotSuppressed(context, DiagnosticDescriptors.AddSummaryElementToDocumentationComment, documentationComment); } SyntaxNode parent = documentationComment.ParentTrivia.Token.Parent; bool unusedElement = !context.IsAnalyzerSuppressed(DiagnosticDescriptors.UnusedElementInDocumentationComment); bool orderParams = !context.IsAnalyzerSuppressed(DiagnosticDescriptors.OrderElementsInDocumentationComment); bool addParam = !context.IsAnalyzerSuppressed(DiagnosticDescriptors.AddParamElementToDocumentationComment); bool addTypeParam = !context.IsAnalyzerSuppressed(DiagnosticDescriptors.AddTypeParamElementToDocumentationComment); if (addParam || orderParams || unusedElement) { SeparatedSyntaxList <ParameterSyntax> parameters = ParameterListInfo.Create(parent).Parameters; if (addParam && parameters.Any()) { foreach (ParameterSyntax parameter in parameters) { if (IsMissing(documentationComment, parameter)) { ReportDiagnostic(context, DiagnosticDescriptors.AddParamElementToDocumentationComment, documentationComment); break; } } } if (orderParams || unusedElement) { Analyze(context, documentationComment.Content, parameters, XmlElementKind.Param, (nodes, name) => nodes.IndexOf(name)); } } if (addTypeParam || orderParams || unusedElement) { SeparatedSyntaxList <TypeParameterSyntax> typeParameters = TypeParameterListInfo.Create(parent).Parameters; if (addTypeParam && typeParameters.Any()) { foreach (TypeParameterSyntax typeParameter in typeParameters) { if (IsMissing(documentationComment, typeParameter)) { ReportDiagnostic(context, DiagnosticDescriptors.AddTypeParamElementToDocumentationComment, documentationComment); break; } } } if (orderParams || unusedElement) { Analyze(context, documentationComment.Content, typeParameters, XmlElementKind.TypeParam, (nodes, name) => nodes.IndexOf(name)); } } }
public static void AnalyzeSingleLineDocumentationCommentTrivia(SyntaxNodeAnalysisContext context) { var documentationComment = (DocumentationCommentTriviaSyntax)context.Node; if (!documentationComment.IsPartOfMemberDeclaration()) { return; } bool containsInheritDoc = false; bool containsIncludeOrExclude = false; bool containsSummaryElement = false; bool isFirst = true; foreach (XmlNodeSyntax node in documentationComment.Content) { XmlElementInfo info = SyntaxInfo.XmlElementInfo(node); if (info.Success) { switch (info.GetElementKind()) { case XmlElementKind.Include: case XmlElementKind.Exclude: { if (isFirst) { containsIncludeOrExclude = true; } break; } case XmlElementKind.InheritDoc: { containsInheritDoc = true; break; } case XmlElementKind.Summary: { if (info.IsEmptyElement || IsSummaryMissing((XmlElementSyntax)info.Element)) { context.ReportDiagnostic( DiagnosticDescriptors.AddSummaryToDocumentationComment, info.Element); } containsSummaryElement = true; break; } } if (isFirst) { isFirst = false; } else { containsIncludeOrExclude = false; } if (containsInheritDoc && containsSummaryElement) { break; } } } if (!containsSummaryElement && !containsInheritDoc && !containsIncludeOrExclude) { context.ReportDiagnostic( DiagnosticDescriptors.AddSummaryElementToDocumentationComment, documentationComment); } }
public static void AnalyzeSingleLineDocumentationCommentTrivia(SyntaxNodeAnalysisContext context) { var documentationComment = (DocumentationCommentTriviaSyntax)context.Node; if (!documentationComment.IsPartOfMemberDeclaration()) { return; } bool containsInheritDoc = false; bool containsIncludeOrExclude = false; bool containsSummaryElement = false; bool containsContentElement = false; bool isFirst = true; CancellationToken cancellationToken = context.CancellationToken; foreach (XmlNodeSyntax node in documentationComment.Content) { cancellationToken.ThrowIfCancellationRequested(); XmlElementInfo info = SyntaxInfo.XmlElementInfo(node); if (info.Success) { switch (info.GetElementKind()) { case XmlElementKind.Include: case XmlElementKind.Exclude: { if (isFirst) { containsIncludeOrExclude = true; } break; } case XmlElementKind.InheritDoc: { containsInheritDoc = true; break; } case XmlElementKind.Content: { containsContentElement = true; break; } case XmlElementKind.Summary: { if (info.IsContentEmptyOrWhitespace) { context.ReportDiagnostic( DiagnosticDescriptors.AddSummaryToDocumentationComment, info.Element); } containsSummaryElement = true; break; } case XmlElementKind.Code: case XmlElementKind.Example: case XmlElementKind.Remarks: case XmlElementKind.Returns: case XmlElementKind.Value: { if (info.IsContentEmptyOrWhitespace) { context.ReportDiagnostic( DiagnosticDescriptors.UnusedElementInDocumentationComment, info.Element); } break; } } if (isFirst) { isFirst = false; } else { containsIncludeOrExclude = false; } } } if (!containsSummaryElement && !containsInheritDoc && !containsIncludeOrExclude && !containsContentElement) { context.ReportDiagnostic( DiagnosticDescriptors.AddSummaryElementToDocumentationComment, documentationComment); } }
public static ImmutableArray <string> GetAttributeValues(DocumentationCommentTriviaSyntax comment, XmlElementKind elementKind, string attributeName) { HashSet <string> values = null; bool containsIncludeOrExclude = false; bool isFirst = true; foreach (XmlNodeSyntax node in comment.Content) { XmlElementInfo info = SyntaxInfo.XmlElementInfo(node); if (info.Success) { XmlElementKind kind = info.GetElementKind(); switch (kind) { case XmlElementKind.Include: case XmlElementKind.Exclude: { if (isFirst) { containsIncludeOrExclude = true; } break; } case XmlElementKind.InheritDoc: { return(default(ImmutableArray <string>)); } default: { if (!info.IsEmptyElement && kind == elementKind) { string value = GetAttributeValue((XmlElementSyntax)info.Element, attributeName); if (value != null) { (values ?? (values = new HashSet <string>())).Add(value); } } break; } } if (isFirst) { isFirst = false; } else { containsIncludeOrExclude = false; } } } if (!containsIncludeOrExclude) { return(values?.ToImmutableArray() ?? ImmutableArray <string> .Empty); } return(default(ImmutableArray <string>)); }