From 6161f3c1ffc811f32421d5c7b96e63c719fe9dbc Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 19 Jun 2017 23:24:28 -0500 Subject: [PATCH] Update SA1615 to suppress messages when documentation for an element is optional Fixes #2445 --- .../DocumentationRules/SA1615UnitTests.cs | 19 +++++++++++++ ...A1615ElementReturnValueMustBeDocumented.cs | 27 ++++++++++++++----- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1615UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1615UnitTests.cs index 7a756650a..ca8b13ee4 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1615UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1615UnitTests.cs @@ -330,6 +330,25 @@ public int MethodName() await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } + [Fact] + [WorkItem(2445, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2445")] + public async Task TestPrivateMethodMissingReturnsAsync() + { + var testCode = @" +internal class ClassName +{ + /// + private int Test1(int arg) { throw new System.NotImplementedException(); } + + /** + * + */ + private int Test2(int arg) { throw new System.NotImplementedException(); } +}"; + + await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + /// protected override Project ApplyCompilationOptions(Project project) { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1615ElementReturnValueMustBeDocumented.cs b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1615ElementReturnValueMustBeDocumented.cs index a6357f6b9..3d4eae311 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1615ElementReturnValueMustBeDocumented.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/SA1615ElementReturnValueMustBeDocumented.cs @@ -12,6 +12,7 @@ namespace StyleCop.Analyzers.DocumentationRules using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Settings.ObjectModel; /// /// A C# element is missing documentation for its return value. @@ -41,8 +42,8 @@ internal class SA1615ElementReturnValueMustBeDocumented : DiagnosticAnalyzer private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.DocumentationRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); - private static readonly Action MethodDeclarationAction = HandleMethodDeclaration; - private static readonly Action DelegateDeclarationAction = HandleDelegateDeclaration; + private static readonly Action MethodDeclarationAction = HandleMethodDeclaration; + private static readonly Action DelegateDeclarationAction = HandleDelegateDeclaration; /// public override ImmutableArray SupportedDiagnostics { get; } = @@ -58,22 +59,34 @@ public override void Initialize(AnalysisContext context) context.RegisterSyntaxNodeAction(DelegateDeclarationAction, SyntaxKind.DelegateDeclaration); } - private static void HandleMethodDeclaration(SyntaxNodeAnalysisContext context) + private static void HandleMethodDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { var node = (MethodDeclarationSyntax)context.Node; - HandleDeclaration(context, node.ReturnType); + Accessibility declaredAccessibility = node.GetDeclaredAccessibility(context.SemanticModel, context.CancellationToken); + Accessibility effectiveAccessibility = node.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken); + bool needsComment = SA1600ElementsMustBeDocumented.NeedsComment(settings.DocumentationRules, node.Kind(), node.Parent.Kind(), declaredAccessibility, effectiveAccessibility); + HandleDeclaration(context, needsComment, node.ReturnType); } - private static void HandleDelegateDeclaration(SyntaxNodeAnalysisContext context) + private static void HandleDelegateDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings) { var node = (DelegateDeclarationSyntax)context.Node; - HandleDeclaration(context, node.ReturnType); + Accessibility declaredAccessibility = node.GetDeclaredAccessibility(context.SemanticModel, context.CancellationToken); + Accessibility effectiveAccessibility = node.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken); + bool needsComment = SA1600ElementsMustBeDocumented.NeedsComment(settings.DocumentationRules, node.Kind(), node.Parent.Kind(), declaredAccessibility, effectiveAccessibility); + HandleDeclaration(context, needsComment, node.ReturnType); } - private static void HandleDeclaration(SyntaxNodeAnalysisContext context, TypeSyntax returnType) + private static void HandleDeclaration(SyntaxNodeAnalysisContext context, bool needsComment, TypeSyntax returnType) { + if (!needsComment) + { + // Documentation is optional for this element. + return; + } + var predefinedType = returnType as PredefinedTypeSyntax; if (predefinedType != null && predefinedType.Keyword.IsKind(SyntaxKind.VoidKeyword))