예제 #1
0
        private void HandleDeclaration(SyntaxNodeAnalysisContext context, SyntaxNode node, params Location[] locations)
        {
            var documentation = XmlCommentHelper.GetDocumentationStructure(node);

            if (documentation == null)
            {
                // missing documentation is reported by SA1600, SA1601, and SA1602
                return;
            }

            if (GetTopLevelElement(documentation, XmlCommentHelper.InheritdocXmlTag) != null)
            {
                // Ignore nodes with an <inheritdoc/> tag.
                return;
            }

            var xmlElement = GetTopLevelElement(documentation, XmlCommentHelper.SummaryXmlTag);

            if (xmlElement == null)
            {
                xmlElement = GetTopLevelElement(documentation, XmlCommentHelper.ContentXmlTag);
            }

            this.HandleXmlElement(context, xmlElement, locations);
        }
        private void HandleDeclaration(SyntaxNodeAnalysisContext context, TypeSyntax returnType)
        {
            var predefinedType = returnType as PredefinedTypeSyntax;

            if (predefinedType != null && predefinedType.Keyword.IsKind(SyntaxKind.VoidKeyword))
            {
                // There is no return value
                return;
            }

            var documentationStructure = XmlCommentHelper.GetDocumentationStructure(context.Node);

            if (documentationStructure == null)
            {
                return;
            }

            if (XmlCommentHelper.GetTopLevelElement(documentationStructure, XmlCommentHelper.InheritdocXmlTag) != null)
            {
                // Don't report if the documentation is inherited.
                return;
            }

            if (XmlCommentHelper.GetTopLevelElement(documentationStructure, XmlCommentHelper.ReturnsXmlTag) == null)
            {
                context.ReportDiagnostic(Diagnostic.Create(Descriptor, returnType.GetLocation()));
            }
        }
        private void HandleSyntaxNode(SyntaxNodeAnalysisContext context)
        {
            var node = context.Node;

            var documentation = XmlCommentHelper.GetDocumentationStructure(node);

            if (documentation != null)
            {
                IEnumerable <ParameterSyntax> parameterList = this.GetParameters(node);

                if (parameterList == null)
                {
                    return;
                }

                if (XmlCommentHelper.GetTopLevelElement(documentation, XmlCommentHelper.InheritdocXmlTag) != null)
                {
                    // Ignore nodes with an <inheritdoc/> tag.
                    return;
                }

                var xmlParameterNames = XmlCommentHelper.GetTopLevelElements(documentation, XmlCommentHelper.ParamTag)
                                        .Select(XmlCommentHelper.GetFirstAttributeOrDefault <XmlNameAttributeSyntax>)
                                        .Where(x => x != null)
                                        .ToImmutableArray();

                foreach (var parameter in parameterList)
                {
                    if (!xmlParameterNames.Any(x => x.Identifier.ToString() == parameter.Identifier.ToString()))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, parameter.Identifier.GetLocation()));
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Analyzes a <see cref="BaseMethodDeclarationSyntax"/> node. If it has a summary it is checked if the text starts with &quot;[firstTextPart]&lt;see cref=&quot;[className]&quot;/&gt;[secondTextPart]&quot;.
        /// </summary>
        /// <param name="context">The <see cref="SyntaxNodeAnalysisContext"/> of this analysis.</param>
        /// <param name="firstTextPart">The first part of the standard text.</param>
        /// <param name="secondTextPart">The second part of the standard text.</param>
        /// <param name="reportDiagnostic">Whether or not a diagnostic should be reported.</param>
        /// <returns>A <see cref="MatchResult"/> describing the result of the analysis.</returns>
        protected MatchResult HandleDeclaration(SyntaxNodeAnalysisContext context, string firstTextPart, string secondTextPart, bool reportDiagnostic)
        {
            var declarationSyntax = context.Node as BaseMethodDeclarationSyntax;

            if (declarationSyntax == null)
            {
                return(MatchResult.Unknown);
            }

            var documentationStructure = XmlCommentHelper.GetDocumentationStructure(declarationSyntax);

            if (documentationStructure == null)
            {
                return(MatchResult.Unknown);
            }

            var summaryElement = XmlCommentHelper.GetTopLevelElement(documentationStructure, XmlCommentHelper.SummaryXmlTag) as XmlElementSyntax;

            if (summaryElement == null)
            {
                return(MatchResult.Unknown);
            }

            // Check if the summary content could be a correct standard text
            if (summaryElement.Content.Count >= 3)
            {
                // Standard text has the form <part1><see><part2>
                var firstTextPartSyntax  = summaryElement.Content[0] as XmlTextSyntax;
                var classReferencePart   = summaryElement.Content[1] as XmlEmptyElementSyntax;
                var secondTextParSyntaxt = summaryElement.Content[2] as XmlTextSyntax;

                if (firstTextPartSyntax != null && classReferencePart != null && secondTextParSyntaxt != null)
                {
                    // Check text parts
                    var firstText  = XmlCommentHelper.GetText(firstTextPartSyntax);
                    var secondText = XmlCommentHelper.GetText(secondTextParSyntaxt);

                    if (TextPartsMatch(firstTextPart, secondTextPart, firstTextPartSyntax, secondTextParSyntaxt) &&
                        this.SeeTagIsCorrect(context, classReferencePart, declarationSyntax))
                    {
                        // We found a correct standard text
                        return(MatchResult.FoundMatch);
                    }
                }
            }

            if (reportDiagnostic)
            {
                context.ReportDiagnostic(Diagnostic.Create(this.DiagnosticDescriptor, summaryElement.GetLocation()));
            }

            // TODO: be more specific about the type of error when possible
            return(MatchResult.None);
        }
        private static void HandleMember(SyntaxNodeAnalysisContext context, TypeSyntax returnValue)
        {
            var documentation = XmlCommentHelper.GetDocumentationStructure(context.Node);

            if (context.Node != null && documentation != null)
            {
                var returnType = returnValue as PredefinedTypeSyntax;

                // Check if the return type is void.
                if (returnType != null && returnType.Keyword.IsKind(SyntaxKind.VoidKeyword))
                {
                    // Check if the return value is documented
                    var returnsElement = XmlCommentHelper.GetTopLevelElement(documentation, XmlCommentHelper.ReturnsXmlTag);

                    if (returnsElement != null)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, returnsElement.GetLocation()));
                    }
                }
            }
        }