private static Task <Document> OrderElementsAsync( Document document, XmlNodeSyntax xmlNode, CancellationToken cancellationToken) { var documentationComment = (DocumentationCommentTriviaSyntax)xmlNode.Parent; SyntaxList <XmlNodeSyntax> content = documentationComment.Content; MemberDeclarationSyntax memberDeclaration = xmlNode.FirstAncestor <MemberDeclarationSyntax>(); int firstIndex = content.IndexOf(xmlNode); SyntaxList <XmlNodeSyntax> newContent = GetNewContent(); DocumentationCommentTriviaSyntax newDocumentationComment = documentationComment.WithContent(newContent); return(document.ReplaceNodeAsync(documentationComment, newDocumentationComment, cancellationToken)); SyntaxList <XmlNodeSyntax> GetNewContent() { switch (SyntaxInfo.XmlElementInfo(xmlNode).GetElementKind()) { case XmlElementKind.Param: { SeparatedSyntaxList <ParameterSyntax> parameters = ParameterListInfo.Create(memberDeclaration).Parameters; return(SortElements(parameters, content, firstIndex, XmlElementKind.Param, (nodes, name) => nodes.IndexOf(name))); } case XmlElementKind.TypeParam: { SeparatedSyntaxList <TypeParameterSyntax> typeParameters = TypeParameterListInfo.Create(memberDeclaration).Parameters; return(SortElements(typeParameters, content, firstIndex, XmlElementKind.TypeParam, (nodes, name) => nodes.IndexOf(name))); } default: { throw new InvalidOperationException(); } } } }
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)); } } }
protected override SeparatedSyntaxList <ParameterSyntax> GetSyntaxList(SyntaxNode node) { return(ParameterListInfo.Create(node).Parameters); }