1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using ILLink.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Testing.Verifiers;
namespace ILLink.RoslynAnalyzer.Tests
{
/// <summary>
/// A default verifier for diagnostic analyzers with code fixes.
/// </summary>
/// <typeparam name="TAnalyzer">The <see cref="DiagnosticAnalyzer"/> to test.</typeparam>
/// <typeparam name="TCodeFix">The <see cref="CodeFixProvider"/> to test.</typeparam>
/// <typeparam name="TTest">The test implementation to use.</typeparam>
public partial class CSharpCodeFixVerifier<TAnalyzer, TCodeFix>
where TAnalyzer : DiagnosticAnalyzer, new()
where TCodeFix : Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider, new()
{
public class Test : CSharpCodeFixTest<TAnalyzer, TCodeFix, XUnitVerifier>
{
public Test ()
{
SolutionTransforms.Add ((solution, projectId) => {
var compilationOptions = solution.GetProject (projectId)!.CompilationOptions;
compilationOptions = compilationOptions!.WithSpecificDiagnosticOptions (
compilationOptions.SpecificDiagnosticOptions.SetItems (CSharpVerifierHelper.NullableWarnings));
solution = solution.WithProjectCompilationOptions (projectId, compilationOptions);
return solution;
});
}
}
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer}.Diagnostic()"/>
public static DiagnosticResult Diagnostic ()
=> CSharpAnalyzerVerifier<TAnalyzer>.Diagnostic ();
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest}.Diagnostic(string)"/>
public static DiagnosticResult Diagnostic (string diagnosticId)
=> CSharpAnalyzerVerifier<TAnalyzer>.Diagnostic (diagnosticId);
public static DiagnosticResult Diagnostic (DiagnosticId diagnosticId)
=> CSharpAnalyzerVerifier<TAnalyzer>.Diagnostic (DiagnosticDescriptors.GetDiagnosticDescriptor (diagnosticId));
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest}.Diagnostic(DiagnosticDescriptor)"/>
public static DiagnosticResult Diagnostic (DiagnosticDescriptor descriptor)
=> CSharpAnalyzerVerifier<TAnalyzer>.Diagnostic (descriptor);
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
public static Task VerifyAnalyzerAsync (string source, (string, string)[]? analyzerOptions = null, IEnumerable<MetadataReference>? additionalReferences = null, params DiagnosticResult[] expected)
=> CSharpAnalyzerVerifier<TAnalyzer>.VerifyAnalyzerAsync (source, analyzerOptions, additionalReferences, expected);
/// <summary>
/// Verifies the analyzer provides diagnostics which, in combination with the code fix, produce the expected
/// fixed code.
/// </summary>
/// <param name="source">The source text to test. Any diagnostics are defined in markup.</param>
/// <param name="fixedSource">The expected fixed source text. Any remaining diagnostics are defined in markup.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public static Task VerifyCodeFixAsync (string source, string fixedSource)
=> VerifyCodeFixAsync (source, DiagnosticResult.EmptyDiagnosticResults, fixedSource);
/// <summary>
/// Verifies the analyzer provides diagnostics which, in combination with the code fix, produce the expected
/// fixed code.
/// </summary>
/// <param name="source">The source text to test, which may include markup syntax.</param>
/// <param name="expected">The expected diagnostic. This diagnostic is in addition to any diagnostics defined in
/// markup.</param>
/// <param name="fixedSource">The expected fixed source text. Any remaining diagnostics are defined in markup.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public static Task VerifyCodeFixAsync (string source, DiagnosticResult expected, string fixedSource)
=> VerifyCodeFixAsync (source, new[] { expected }, fixedSource);
/// <summary>
/// Verifies the analyzer provides diagnostics which, in combination with the code fix, produce the expected
/// fixed code.
/// </summary>
/// <param name="source">The source text to test, which may include markup syntax.</param>
/// <param name="expected">The expected diagnostics. These diagnostics are in addition to any diagnostics
/// defined in markup.</param>
/// <param name="fixedSource">The expected fixed source text. Any remaining diagnostics are defined in markup.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public static Task VerifyCodeFixAsync (string source, DiagnosticResult[] expected, string fixedSource)
{
var test = new Test {
TestCode = source,
FixedCode = fixedSource,
};
test.ExpectedDiagnostics.AddRange (expected);
return test.RunAsync (CancellationToken.None);
}
}
}
|