Beispiel #1
0
        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);
 }