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())); } } } }
/// <summary> /// Analyzes a <see cref="BaseMethodDeclarationSyntax"/> node. If it has a summary it is checked if the text starts with "[firstTextPart]<see cref="[className]"/>[secondTextPart]". /// </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())); } } } }