Skip to content

Commit da6e8df

Browse files
committed
IsAnalyzerSuppressed improvement
1 parent 3c31e20 commit da6e8df

13 files changed

+106
-51
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/FileHeaderTestBase.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
namespace StyleCop.Analyzers.Test.DocumentationRules
55
{
66
using System.Collections.Generic;
7+
using System.Linq;
78
using System.Threading;
89
using System.Threading.Tasks;
910
using Microsoft.CodeAnalysis;
1011
using Microsoft.CodeAnalysis.Testing;
1112
using StyleCop.Analyzers.DocumentationRules;
1213
using StyleCop.Analyzers.Test.Verifiers;
13-
using TestHelper;
1414
using Xunit;
1515

1616
/// <summary>
@@ -97,6 +97,9 @@ protected virtual string GetSettings()
9797
protected virtual IEnumerable<string> GetDisabledDiagnostics()
9898
=> new[] { FileHeaderAnalyzers.SA1639Descriptor.Id };
9999

100+
protected virtual IEnumerable<string> GetExplicitlyEnabledDiagnostics()
101+
=> Enumerable.Empty<string>();
102+
100103
protected Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
101104
=> this.VerifyCSharpFixAsync(source, new[] { expected }, fixedSource: null, cancellationToken);
102105

@@ -121,6 +124,7 @@ protected Task VerifyCSharpFixAsync(string source, DiagnosticResult[] expected,
121124
test.ExpectedDiagnostics.AddRange(expected);
122125
test.RemainingDiagnostics.AddRange(remainingDiagnostics);
123126
test.DisabledDiagnostics.AddRange(this.GetDisabledDiagnostics());
127+
test.ExplicitlyEnabledDiagnostics.AddRange(this.GetExplicitlyEnabledDiagnostics());
124128
return test.RunAsync(cancellationToken);
125129
}
126130
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1639UnitTests.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,11 @@ protected override IEnumerable<string> GetDisabledDiagnostics()
9191
{
9292
return Enumerable.Empty<string>();
9393
}
94+
95+
/// <inheritdoc/>
96+
protected override IEnumerable<string> GetExplicitlyEnabledDiagnostics()
97+
{
98+
yield return FileHeaderAnalyzers.SA1639Descriptor.Id;
99+
}
94100
}
95101
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/StyleCopCodeFixVerifier`2.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,27 @@ public CSharpTest()
177177
/// </value>
178178
public string SettingsFileName { get; set; } = SettingsHelper.SettingsFileName;
179179

180+
/// <summary>
181+
/// Gets the list of diagnostic identifier that will be explicitly enabled in the compilation options.
182+
/// </summary>
183+
/// <value>
184+
/// The list of explicitly enabled diagnostic identifiers.
185+
/// </value>
186+
public List<string> ExplicitlyEnabledDiagnostics { get; } = new List<string>();
187+
188+
protected override CompilationOptions CreateCompilationOptions()
189+
{
190+
var compilationOptions = base.CreateCompilationOptions();
191+
var specificDiagnosticOptions = compilationOptions.SpecificDiagnosticOptions;
192+
193+
foreach (var id in this.ExplicitlyEnabledDiagnostics)
194+
{
195+
specificDiagnosticOptions = specificDiagnosticOptions.SetItem(id, ReportDiagnostic.Warn);
196+
}
197+
198+
return compilationOptions.WithSpecificDiagnosticOptions(specificDiagnosticOptions);
199+
}
200+
180201
protected override IEnumerable<CodeFixProvider> GetCodeFixProviders()
181202
{
182203
var codeFixProvider = new TCodeFix();

StyleCop.Analyzers/StyleCop.Analyzers/DocumentationRules/FileHeaderAnalyzers.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ private static void HandleCompilationStart(CompilationStartAnalysisContext conte
182182
var compilation = context.Compilation;
183183

184184
// Disabling SA1633 will disable all other header related diagnostics.
185-
if (!compilation.IsAnalyzerSuppressed(SA1633Identifier))
185+
if (!compilation.IsAnalyzerSuppressed(SA1633DescriptorMissing))
186186
{
187187
context.RegisterSyntaxTreeAction((ctx, settings) => Analyzer.HandleSyntaxTree(ctx, settings, compilation));
188188
}
@@ -215,12 +215,12 @@ public static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopS
215215
return;
216216
}
217217

218-
if (!compilation.IsAnalyzerSuppressed(SA1634Identifier))
218+
if (!compilation.IsAnalyzerSuppressed(SA1634Descriptor))
219219
{
220220
CheckCopyrightHeader(context, settings.DocumentationRules, compilation, fileHeader);
221221
}
222222

223-
if (!compilation.IsAnalyzerSuppressed(SA1639Identifier))
223+
if (!compilation.IsAnalyzerSuppressed(SA1639Descriptor))
224224
{
225225
CheckSummaryHeader(context, compilation, fileHeader);
226226
}
@@ -234,15 +234,15 @@ public static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopS
234234
return;
235235
}
236236

237-
if (!compilation.IsAnalyzerSuppressed(SA1635Identifier))
237+
if (!compilation.IsAnalyzerSuppressed(SA1635Descriptor))
238238
{
239239
if (string.IsNullOrWhiteSpace(fileHeader.CopyrightText))
240240
{
241241
context.ReportDiagnostic(Diagnostic.Create(SA1635Descriptor, fileHeader.GetLocation(context.Tree)));
242242
return;
243243
}
244244

245-
if (compilation.IsAnalyzerSuppressed(SA1636Identifier))
245+
if (compilation.IsAnalyzerSuppressed(SA1636Descriptor))
246246
{
247247
return;
248248
}
@@ -265,17 +265,17 @@ private static void CheckCopyrightHeader(SyntaxTreeAnalysisContext context, Docu
265265
return;
266266
}
267267

268-
if (!compilation.IsAnalyzerSuppressed(SA1637Identifier))
268+
if (!compilation.IsAnalyzerSuppressed(SA1637Descriptor))
269269
{
270270
CheckFile(context, compilation, fileHeader, copyrightElement);
271271
}
272272

273-
if (!compilation.IsAnalyzerSuppressed(SA1640Identifier))
273+
if (!compilation.IsAnalyzerSuppressed(SA1640Descriptor))
274274
{
275275
CheckCompanyName(context, documentationSettings, compilation, fileHeader, copyrightElement);
276276
}
277277

278-
if (!compilation.IsAnalyzerSuppressed(SA1635Identifier))
278+
if (!compilation.IsAnalyzerSuppressed(SA1635Descriptor))
279279
{
280280
CheckCopyrightText(context, documentationSettings, compilation, fileHeader, copyrightElement);
281281
}
@@ -291,7 +291,7 @@ private static void CheckFile(SyntaxTreeAnalysisContext context, Compilation com
291291
return;
292292
}
293293

294-
if (compilation.IsAnalyzerSuppressed(SA1638Identifier))
294+
if (compilation.IsAnalyzerSuppressed(SA1638Descriptor))
295295
{
296296
return;
297297
}
@@ -314,7 +314,7 @@ private static void CheckCopyrightText(SyntaxTreeAnalysisContext context, Docume
314314
return;
315315
}
316316

317-
if (compilation.IsAnalyzerSuppressed(SA1636Identifier))
317+
if (compilation.IsAnalyzerSuppressed(SA1636Descriptor))
318318
{
319319
return;
320320
}
@@ -345,7 +345,7 @@ private static void CheckCompanyName(SyntaxTreeAnalysisContext context, Document
345345
return;
346346
}
347347

348-
if (compilation.IsAnalyzerSuppressed(SA1641Identifier))
348+
if (compilation.IsAnalyzerSuppressed(SA1641Descriptor))
349349
{
350350
return;
351351
}

StyleCop.Analyzers/StyleCop.Analyzers/Helpers/DiagnosticOptionsHelper.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,44 +19,52 @@ internal static class DiagnosticOptionsHelper
1919
/// Determines if the diagnostic identified by the given identifier is currently suppressed.
2020
/// </summary>
2121
/// <param name="context">The context that will be used to determine if the diagnostic is currently suppressed.</param>
22-
/// <param name="diagnosticId">The diagnostic identifier to check.</param>
22+
/// <param name="descriptor">The diagnostic descriptor to check.</param>
2323
/// <returns>True if the diagnostic is currently suppressed.</returns>
24-
internal static bool IsAnalyzerSuppressed(this SyntaxNodeAnalysisContext context, string diagnosticId)
24+
internal static bool IsAnalyzerSuppressed(this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor)
2525
{
26-
return context.SemanticModel.Compilation.IsAnalyzerSuppressed(diagnosticId);
26+
return context.SemanticModel.Compilation.IsAnalyzerSuppressed(descriptor);
2727
}
2828

2929
/// <summary>
3030
/// Determines if the diagnostic identified by the given identifier is currently suppressed.
3131
/// </summary>
3232
/// <param name="context">The context that will be used to determine if the diagnostic is currently suppressed.</param>
33-
/// <param name="diagnosticId">The diagnostic identifier to check.</param>
33+
/// <param name="descriptor">The diagnostic descriptor to check.</param>
3434
/// <returns>True if the diagnostic is currently suppressed.</returns>
35-
internal static bool IsAnalyzerSuppressed(this CompilationStartAnalysisContext context, string diagnosticId)
35+
internal static bool IsAnalyzerSuppressed(this CompilationStartAnalysisContext context, DiagnosticDescriptor descriptor)
3636
{
37-
return context.Compilation.IsAnalyzerSuppressed(diagnosticId);
37+
return context.Compilation.IsAnalyzerSuppressed(descriptor);
3838
}
3939

4040
/// <summary>
4141
/// Determines if the diagnostic identified by the given identifier is currently suppressed.
4242
/// </summary>
4343
/// <param name="compilation">The compilation that will be used to determine if the diagnostic is currently suppressed.</param>
44-
/// <param name="diagnosticId">The diagnostic identifier to check.</param>
44+
/// <param name="descriptor">The diagnostic descriptor to check.</param>
4545
/// <returns>True if the diagnostic is currently suppressed.</returns>
46-
internal static bool IsAnalyzerSuppressed(this Compilation compilation, string diagnosticId)
46+
internal static bool IsAnalyzerSuppressed(this Compilation compilation, DiagnosticDescriptor descriptor)
4747
{
48-
return compilation.Options.IsAnalyzerSuppressed(diagnosticId);
48+
return compilation.Options.IsAnalyzerSuppressed(descriptor);
4949
}
5050

5151
/// <summary>
5252
/// Determines if the diagnostic identified by the given identifier is currently suppressed.
5353
/// </summary>
5454
/// <param name="compilationOptions">The compilation options that will be used to determine if the diagnostic is currently suppressed.</param>
55-
/// <param name="diagnosticId">The diagnostic identifier to check.</param>
55+
/// <param name="descriptor">The diagnostic descriptor to check.</param>
5656
/// <returns>True if the diagnostic is currently suppressed.</returns>
57-
internal static bool IsAnalyzerSuppressed(this CompilationOptions compilationOptions, string diagnosticId)
57+
internal static bool IsAnalyzerSuppressed(this CompilationOptions compilationOptions, DiagnosticDescriptor descriptor)
5858
{
59-
return compilationOptions.SpecificDiagnosticOptions.GetValueOrDefault(diagnosticId, ReportDiagnostic.Default) == ReportDiagnostic.Suppress;
59+
switch (compilationOptions.SpecificDiagnosticOptions.GetValueOrDefault(descriptor.Id))
60+
{
61+
case ReportDiagnostic.Suppress:
62+
return true;
63+
case ReportDiagnostic.Default:
64+
return !descriptor.IsEnabledByDefault;
65+
default:
66+
return false;
67+
}
6068
}
6169

6270
/// <summary>

StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1501StatementMustNotBeOnASingleLine.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public override void Initialize(AnalysisContext context)
8282
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
8383
{
8484
// If SA1503 is suppressed, we need to handle compound blocks as well.
85-
if (context.IsAnalyzerSuppressed(SA1503BracesMustNotBeOmitted.DiagnosticId))
85+
if (context.IsAnalyzerSuppressed(SA1503BracesMustNotBeOmitted.Descriptor))
8686
{
8787
context.RegisterSyntaxNodeAction(HandleIfStatement, SyntaxKind.IfStatement);
8888
context.RegisterSyntaxNodeAction(ctx => CheckChildStatement(ctx, ctx.Node, ((DoStatementSyntax)ctx.Node).Statement), SyntaxKind.DoStatement);
@@ -146,7 +146,7 @@ private static void HandleIfStatement(SyntaxNodeAnalysisContext context)
146146
}
147147
}
148148

149-
if (!context.IsAnalyzerSuppressed(SA1520UseBracesConsistently.DiagnosticId))
149+
if (!context.IsAnalyzerSuppressed(SA1520UseBracesConsistently.Descriptor))
150150
{
151151
// inconsistencies will be reported as SA1520, as long as it's not suppressed
152152
if (clauses.OfType<BlockSyntax>().Any())
@@ -190,7 +190,7 @@ private static void CheckChildStatement(SyntaxNodeAnalysisContext context, Synta
190190
return;
191191
}
192192

193-
if (!context.IsAnalyzerSuppressed(SA1519BracesMustNotBeOmittedFromMultiLineChildStatement.DiagnosticId))
193+
if (!context.IsAnalyzerSuppressed(SA1519BracesMustNotBeOmittedFromMultiLineChildStatement.Descriptor))
194194
{
195195
// diagnostics for multi-line statements is handled by SA1519, as long as it's not suppressed
196196
FileLinePositionSpan lineSpan = childStatement.GetLineSpan();

StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1503BracesMustNotBeOmitted.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,18 @@ internal class SA1503BracesMustNotBeOmitted : DiagnosticAnalyzer
6161
/// The ID for diagnostics produced by the <see cref="SA1503BracesMustNotBeOmitted"/> analyzer.
6262
/// </summary>
6363
public const string DiagnosticId = "SA1503";
64+
65+
/// <summary>
66+
/// The diagnostic descriptor for the <see cref="SA1503BracesMustNotBeOmitted"/> analyzer.
67+
/// </summary>
68+
public static readonly DiagnosticDescriptor Descriptor =
69+
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.LayoutRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
70+
6471
private const string Title = "Braces should not be omitted";
6572
private const string MessageFormat = "Braces should not be omitted";
6673
private const string Description = "The opening and closing braces for a C# statement have been omitted.";
6774
private const string HelpLink = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1503.md";
6875

69-
private static readonly DiagnosticDescriptor Descriptor =
70-
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.LayoutRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
71-
7276
private static readonly Action<SyntaxNodeAnalysisContext> IfStatementAction = HandleIfStatement;
7377
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> UsingStatementAction = HandleUsingStatement;
7478

@@ -111,7 +115,7 @@ private static void HandleIfStatement(SyntaxNodeAnalysisContext context)
111115
}
112116
}
113117

114-
if (context.SemanticModel.Compilation.Options.SpecificDiagnosticOptions.GetValueOrDefault(SA1520UseBracesConsistently.DiagnosticId, ReportDiagnostic.Default) != ReportDiagnostic.Suppress)
118+
if (!context.IsAnalyzerSuppressed(SA1520UseBracesConsistently.Descriptor))
115119
{
116120
// inconsistencies will be reported as SA1520, as long as it's not suppressed
117121
if (clauses.OfType<BlockSyntax>().Any())
@@ -144,7 +148,7 @@ private static void CheckChildStatement(SyntaxNodeAnalysisContext context, State
144148
return;
145149
}
146150

147-
if (context.SemanticModel.Compilation.Options.SpecificDiagnosticOptions.GetValueOrDefault(SA1519BracesMustNotBeOmittedFromMultiLineChildStatement.DiagnosticId, ReportDiagnostic.Default) != ReportDiagnostic.Suppress)
151+
if (!context.IsAnalyzerSuppressed(SA1519BracesMustNotBeOmittedFromMultiLineChildStatement.Descriptor))
148152
{
149153
// diagnostics for multi-line statements is handled by SA1519, as long as it's not suppressed
150154
FileLinePositionSpan lineSpan = childStatement.GetLineSpan();

StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1507CodeMustNotContainMultipleBlankLinesInARow.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,18 @@ internal class SA1507CodeMustNotContainMultipleBlankLinesInARow : DiagnosticAnal
4646
/// analyzer.
4747
/// </summary>
4848
public const string DiagnosticId = "SA1507";
49+
50+
/// <summary>
51+
/// The diagnostic descriptor for the <see cref="SA1507CodeMustNotContainMultipleBlankLinesInARow"/> analyzer.
52+
/// </summary>
53+
public static readonly DiagnosticDescriptor Descriptor =
54+
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.LayoutRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
55+
4956
private const string Title = "Code should not contain multiple blank lines in a row";
5057
private const string MessageFormat = "Code should not contain multiple blank lines in a row";
5158
private const string Description = "The C# code contains multiple blank lines in a row.";
5259
private const string HelpLink = "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1507.md";
5360

54-
private static readonly DiagnosticDescriptor Descriptor =
55-
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.LayoutRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink);
56-
5761
private static readonly Action<SyntaxTreeAnalysisContext> SyntaxTreeAction = HandleSyntaxTree;
5862

5963
/// <inheritdoc/>

StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1512SingleLineCommentsMustNotBeFollowedByBlankLine.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,10 @@ public override void Initialize(AnalysisContext context)
103103

104104
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
105105
{
106-
var diagnosticOptions = context.Compilation.Options.SpecificDiagnosticOptions;
107-
context.RegisterSyntaxTreeAction(c => HandleSyntaxTreeAnalysis(c, diagnosticOptions));
106+
context.RegisterSyntaxTreeAction(c => HandleSyntaxTreeAnalysis(c, context.Compilation));
108107
}
109108

110-
private static void HandleSyntaxTreeAnalysis(SyntaxTreeAnalysisContext context, ImmutableDictionary<string, ReportDiagnostic> specificDiagnosticOptions)
109+
private static void HandleSyntaxTreeAnalysis(SyntaxTreeAnalysisContext context, Compilation compilation)
111110
{
112111
var syntaxRoot = context.Tree.GetRoot(context.CancellationToken);
113112

@@ -144,7 +143,7 @@ private static void HandleSyntaxTreeAnalysis(SyntaxTreeAnalysisContext context,
144143
}
145144
else if (trailingBlankLineCount > 1)
146145
{
147-
if (specificDiagnosticOptions.GetValueOrDefault(SA1507CodeMustNotContainMultipleBlankLinesInARow.DiagnosticId, ReportDiagnostic.Default) != ReportDiagnostic.Suppress)
146+
if (!compilation.IsAnalyzerSuppressed(SA1507CodeMustNotContainMultipleBlankLinesInARow.Descriptor))
148147
{
149148
// ignore comments that are followed by multiple blank lines -> the multiple blank lines will be reported by SA1507
150149
continue;

0 commit comments

Comments
 (0)