-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add suppressor support to CSharpVerifier and new base classes
- Loading branch information
1 parent
ab53655
commit 687c8f1
Showing
4 changed files
with
267 additions
and
0 deletions.
There are no files selected for viewing
177 changes: 177 additions & 0 deletions
177
src/xunit.analyzers.tests/Utility/CSharpVerifier.Suppressors.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using Microsoft.CodeAnalysis.Testing; | ||
|
||
public partial class CSharpVerifier<TAnalyzer> | ||
{ | ||
// ----- Multi-version ----- | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress another analyzers. Runs against | ||
/// xUnit.net v2 and v3, using C# 6. | ||
/// </summary> | ||
/// <param name="source">The code to verify</param> | ||
/// <param name="suppressedAnalyzer">The analyzer that is expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static async Task VerifySuppressor( | ||
string source, | ||
DiagnosticAnalyzer suppressedAnalyzer, | ||
params DiagnosticResult[] diagnostics) | ||
{ | ||
await VerifySuppressorV2(LanguageVersion.CSharp6, [source], [suppressedAnalyzer], diagnostics); | ||
await VerifySuppressorV3(LanguageVersion.CSharp6, [source], [suppressedAnalyzer], diagnostics); | ||
} | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress another analyzers. Runs against | ||
/// xUnit.net v2 and v3, using the provided version of C#. | ||
/// </summary> | ||
/// <param name="source">The code to verify</param> | ||
/// <param name="suppressedAnalyzer">The analyzer that is expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static async Task VerifySuppressor( | ||
LanguageVersion languageVersion, | ||
string source, | ||
DiagnosticAnalyzer suppressedAnalyzer, | ||
params DiagnosticResult[] diagnostics) | ||
{ | ||
await VerifySuppressorV2(languageVersion, [source], [suppressedAnalyzer], diagnostics); | ||
await VerifySuppressorV3(languageVersion, [source], [suppressedAnalyzer], diagnostics); | ||
} | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress one or more other analyzers. Runs against | ||
/// xUnit.net v2 and v3, using the provided version of C#. | ||
/// </summary> | ||
/// <param name="languageVersion">The language version to compile with</param> | ||
/// <param name="sources">The code to verify</param> | ||
/// <param name="suppressedAnalyzers">The analyzer(s) that are expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static async Task VerifySuppressor( | ||
LanguageVersion languageVersion, | ||
string[] sources, | ||
DiagnosticAnalyzer[] suppressedAnalyzers, | ||
params DiagnosticResult[] diagnostics) | ||
{ | ||
await VerifySuppressorV2(languageVersion, sources, suppressedAnalyzers, diagnostics); | ||
await VerifySuppressorV3(languageVersion, sources, suppressedAnalyzers, diagnostics); | ||
} | ||
|
||
// ----- v2 ----- | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress another analyzers. Runs against | ||
/// xUnit.net v2, using C# 6. | ||
/// </summary> | ||
/// <param name="source">The code to verify</param> | ||
/// <param name="suppressedAnalyzer">The analyzer that is expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static Task VerifySuppressorV2( | ||
string source, | ||
DiagnosticAnalyzer suppressedAnalyzer, | ||
params DiagnosticResult[] diagnostics) => | ||
VerifySuppressorV2(LanguageVersion.CSharp6, [source], [suppressedAnalyzer], diagnostics); | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress another analyzers. Runs against | ||
/// xUnit.net v2, using the provided version of C#. | ||
/// </summary> | ||
/// <param name="languageVersion">The language version to compile with</param> | ||
/// <param name="source">The code to verify</param> | ||
/// <param name="suppressedAnalyzer">The analyzer that is expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static Task VerifySuppressorV2( | ||
LanguageVersion languageVersion, | ||
string source, | ||
DiagnosticAnalyzer suppressedAnalyzer, | ||
params DiagnosticResult[] diagnostics) => | ||
VerifySuppressorV2(languageVersion, [source], [suppressedAnalyzer], diagnostics); | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress one or more other analyzers. Runs against | ||
/// xUnit.net v2, using the provided version of C#. | ||
/// </summary> | ||
/// <param name="languageVersion">The language version to compile with</param> | ||
/// <param name="sources">The code to verify</param> | ||
/// <param name="suppressedAnalyzers">The analyzer(s) that are expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static Task VerifySuppressorV2( | ||
LanguageVersion languageVersion, | ||
string[] sources, | ||
DiagnosticAnalyzer[] suppressedAnalyzers, | ||
params DiagnosticResult[] diagnostics) | ||
{ | ||
var test = new TestV2(languageVersion); | ||
|
||
foreach (var suppressedAnalyzer in suppressedAnalyzers) | ||
test.AddDiagnosticAnalyzer(suppressedAnalyzer); | ||
|
||
foreach (var source in sources) | ||
test.TestState.Sources.Add(source); | ||
|
||
test.TestState.ExpectedDiagnostics.AddRange(diagnostics); | ||
test.TestState.OutputKind = OutputKind.ConsoleApplication; | ||
test.TestState.Sources.Add("internal class Program { public static void Main() { } }"); | ||
return test.RunAsync(); | ||
} | ||
|
||
// ----- v3 ----- | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress another analyzers. Runs against | ||
/// xUnit.net v3, using C# 6. | ||
/// </summary> | ||
/// <param name="source">The code to verify</param> | ||
/// <param name="suppressedAnalyzer">The analyzer that is expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static Task VerifySuppressorV3( | ||
string source, | ||
DiagnosticAnalyzer suppressedAnalyzer, | ||
params DiagnosticResult[] diagnostics) => | ||
VerifySuppressorV3(LanguageVersion.CSharp6, [source], [suppressedAnalyzer], diagnostics); | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress another analyzers. Runs against | ||
/// xUnit.net v3, using the provided version of C#. | ||
/// </summary> | ||
/// <param name="languageVersion">The language version to compile with</param> | ||
/// <param name="source">The code to verify</param> | ||
/// <param name="suppressedAnalyzer">The analyzer that is expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static Task VerifySuppressorV3( | ||
LanguageVersion languageVersion, | ||
string source, | ||
DiagnosticAnalyzer suppressedAnalyzer, | ||
params DiagnosticResult[] diagnostics) => | ||
VerifySuppressorV3(languageVersion, [source], [suppressedAnalyzer], diagnostics); | ||
|
||
/// <summary> | ||
/// Verify that an analyzer was used to suppress one or more other analyzers. Runs against | ||
/// xUnit.net v3, using the provided version of C#. | ||
/// </summary> | ||
/// <param name="languageVersion">The language version to compile with</param> | ||
/// <param name="sources">The code to verify</param> | ||
/// <param name="suppressedAnalyzers">The analyzer(s) that are expected to be suppressed</param> | ||
/// <param name="diagnostics">Any expected diagnostics that still exist after the suppression</param> | ||
public static Task VerifySuppressorV3( | ||
LanguageVersion languageVersion, | ||
string[] sources, | ||
DiagnosticAnalyzer[] suppressedAnalyzers, | ||
params DiagnosticResult[] diagnostics) | ||
{ | ||
var test = new TestV3(languageVersion); | ||
|
||
foreach (var suppressedAnalyzer in suppressedAnalyzers) | ||
test.AddDiagnosticAnalyzer(suppressedAnalyzer); | ||
|
||
foreach (var source in sources) | ||
test.TestState.Sources.Add(source); | ||
|
||
test.TestState.ExpectedDiagnostics.AddRange(diagnostics); | ||
test.TestState.OutputKind = OutputKind.ConsoleApplication; | ||
test.TestState.Sources.Add("internal class Program { public static void Main() { } }"); | ||
return test.RunAsync(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using System.Collections.Immutable; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
|
||
namespace Xunit.Analyzers; | ||
|
||
/// <summary> | ||
/// Base class for diagnostic suppressors which support xUnit.net v2 and v3. | ||
/// </summary> | ||
public abstract class XunitDiagnosticSuppressor : DiagnosticSuppressor | ||
{ | ||
protected XunitDiagnosticSuppressor(SuppressionDescriptor descriptor) => | ||
SupportedSuppressions = new[] { descriptor }.ToImmutableArray(); | ||
|
||
protected SuppressionDescriptor Descriptor => SupportedSuppressions[0]; | ||
|
||
/// <inheritdoc/> | ||
public override ImmutableArray<SuppressionDescriptor> SupportedSuppressions { get; } | ||
|
||
/// <summary> | ||
/// Override this factory method to influence the creation of <see cref="XunitContext"/>. | ||
/// Typically used by derived classes wanting to provide version overrides for specific | ||
/// references. | ||
/// </summary> | ||
/// <param name="compilation">The Roslyn compilation context</param> | ||
protected virtual XunitContext CreateXunitContext(Compilation compilation) => | ||
new(compilation); | ||
|
||
/// <inheritdoc/> | ||
public sealed override void ReportSuppressions(SuppressionAnalysisContext context) | ||
{ | ||
var xunitContext = CreateXunitContext(context.Compilation); | ||
|
||
if (ShouldAnalyze(xunitContext)) | ||
foreach (var diagnostic in context.ReportedDiagnostics) | ||
if (ShouldSuppress(diagnostic, context, xunitContext)) | ||
context.ReportSuppression(Suppression.Create(Descriptor, diagnostic)); | ||
} | ||
|
||
/// <summary> | ||
/// Override this method to influence when we should consider diagnostic analysis. By | ||
/// default analyzes all assemblies that have a reference to xUnit.net v2 or v3. | ||
/// </summary> | ||
/// <param name="xunitContext">The xUnit.net context</param> | ||
/// <returns>Return <c>true</c> to analyze source; return <c>false</c> to skip analysis</returns> | ||
protected virtual bool ShouldAnalyze(XunitContext xunitContext) => | ||
Guard.ArgumentNotNull(xunitContext).HasV2References || xunitContext.HasV3References; | ||
|
||
/// <summary> | ||
/// Analyzes the given diagnostic to determine if it should be suppressed. | ||
/// </summary> | ||
/// <param name="context">The Roslyn supression analysis context</param> | ||
/// <param name="xunitContext">The xUnit.net context</param> | ||
protected abstract bool ShouldSuppress( | ||
Diagnostic diagnostic, | ||
SuppressionAnalysisContext context, | ||
XunitContext xunitContext); | ||
} |
16 changes: 16 additions & 0 deletions
16
src/xunit.analyzers/Utility/XunitV2DiagnosticSuppressor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace Xunit.Analyzers; | ||
|
||
/// <summary> | ||
/// Base class for diagnostic suppressors which support xUnit.net v2 only. | ||
/// </summary> | ||
public abstract class XunitV2DiagnosticSuppressor : XunitDiagnosticSuppressor | ||
{ | ||
protected XunitV2DiagnosticSuppressor(SuppressionDescriptor descriptor) : | ||
base(descriptor) | ||
{ } | ||
|
||
protected override bool ShouldAnalyze(XunitContext xunitContext) => | ||
Guard.ArgumentNotNull(xunitContext).HasV2References; | ||
} |
16 changes: 16 additions & 0 deletions
16
src/xunit.analyzers/Utility/XunitV3DiagnosticSuppressor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace Xunit.Analyzers; | ||
|
||
/// <summary> | ||
/// Base class for diagnostic suppressors which support xUnit.net v3 only. | ||
/// </summary> | ||
public abstract class XunitV3DiagnosticSuppressor : XunitDiagnosticSuppressor | ||
{ | ||
protected XunitV3DiagnosticSuppressor(SuppressionDescriptor descriptor) : | ||
base(descriptor) | ||
{ } | ||
|
||
protected override bool ShouldAnalyze(XunitContext xunitContext) => | ||
Guard.ArgumentNotNull(xunitContext).HasV3References; | ||
} |