-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCodeFixBenchmark.cs
91 lines (70 loc) · 3.09 KB
/
CodeFixBenchmark.cs
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
using System.Collections.Immutable;
using F0.Benchmarking.Extensions;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Simplification;
namespace F0.Benchmarking.CodeAnalysis.CodeFixes;
public sealed class CodeFixBenchmark<TDiagnosticAnalyzer, TCodeFix> : AnalyzerBenchmark
where TDiagnosticAnalyzer : DiagnosticAnalyzer, new()
where TCodeFix : CodeFixProvider, new()
{
private readonly DiagnosticAnalyzer analyzer;
private readonly CodeFixProvider provider;
private Document document;
private Diagnostic diagnostic;
private ImmutableArray<CodeActionOperation> operations;
internal CodeFixBenchmark()
{
analyzer = new TDiagnosticAnalyzer();
provider = new TCodeFix();
document = null!;
diagnostic = null!;
}
public void Initialize(string code, LanguageVersion languageVersion)
=> InitializeAsync(code, languageVersion).GetAwaiter().GetResult();
public async Task InitializeAsync(string code, LanguageVersion languageVersion)
{
var text = code.Untabify();
document = CreateDocument(text, languageVersion);
var analyzers = ImmutableArray.Create(analyzer);
var compilation = await document.Project.GetCompilationAsync(CancellationToken.None).ConfigureAwait(false);
var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, null, CancellationToken.None);
var allDiagnostics = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false);
diagnostic = allDiagnostics.Single();
}
public void Invoke()
=> InvokeAsync().GetAwaiter().GetResult();
public async Task InvokeAsync()
{
var actions = ImmutableArray.CreateBuilder<CodeAction>();
void registerCodeFix(CodeAction a, ImmutableArray<Diagnostic> d) => actions.Add(a);
var context = new CodeFixContext(document, diagnostic, registerCodeFix, CancellationToken.None);
await provider.RegisterCodeFixesAsync(context).ConfigureAwait(false);
var codeAction = actions.Single();
operations = await codeAction.GetOperationsAsync(CancellationToken.None).ConfigureAwait(false);
}
public void Inspect(string expectedCode)
=> InspectAsync(expectedCode).GetAwaiter().GetResult();
public async Task InspectAsync(string expectedCode)
{
var expectedText = expectedCode.Untabify();
var edit = operations.OfType<ApplyChangesOperation>().Single();
var changedDocument = edit.ChangedSolution.GetDocument(document.Id);
var reducedDocument = await Simplifier.ReduceAsync(changedDocument, Simplifier.Annotation, null, CancellationToken.None).ConfigureAwait(false);
var formattedDocument = await Formatter.FormatAsync(reducedDocument, Formatter.Annotation, null, CancellationToken.None).ConfigureAwait(false);
var actualText = await formattedDocument.GetTextAsync(CancellationToken.None).ConfigureAwait(false);
var actualCode = actualText.ToString();
if (!actualCode.Equals(expectedText, StringComparison.Ordinal))
{
var message = $"""
Unexpected result:
```cs
{actualCode}
```
""";
throw new InvalidOperationException(message);
}
}
}