-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathCodeFixVerifier.Helper.cs
More file actions
90 lines (83 loc) · 4.3 KB
/
CodeFixVerifier.Helper.cs
File metadata and controls
90 lines (83 loc) · 4.3 KB
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Simplification;
namespace TestHelper
{
/// <summary>
/// Diagnostic Producer class with extra methods dealing with applying codefixes
/// All methods are static
/// </summary>
public abstract partial class CodeFixVerifier : DiagnosticVerifier
{
/// <summary>
/// Apply the inputted CodeAction to the inputted document.
/// Meant to be used to apply codefixes.
/// </summary>
/// <param name="document">The Document to apply the fix on</param>
/// <param name="codeAction">A CodeAction that will be applied to the Document.</param>
/// <returns>A Document with the changes from the CodeAction</returns>
private static async Task<Document> ApplyFix(Document document, CodeAction codeAction)
{
System.Collections.Immutable.ImmutableArray<CodeActionOperation> operations = await codeAction.GetOperationsAsync(CancellationToken.None);
Solution solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution;
return solution.GetDocument(document.Id)
?? throw new InvalidOperationException("Could not get document from solution");
}
/// <summary>
/// Compare two collections of Diagnostics,and return a list of any new diagnostics that appear only in the second collection.
/// Note: Considers Diagnostics to be the same if they have the same Ids. In the case of multiple diagnostics with the same Id in a row,
/// this method may not necessarily return the new one.
/// </summary>
/// <param name="diagnostics">The Diagnostics that existed in the code before the CodeFix was applied</param>
/// <param name="newDiagnostics">The Diagnostics that exist in the code after the CodeFix was applied</param>
/// <returns>A list of Diagnostics that only surfaced in the code after the CodeFix was applied</returns>
private static IEnumerable<Diagnostic> GetNewDiagnostics(IEnumerable<Diagnostic> diagnostics, IEnumerable<Diagnostic> newDiagnostics)
{
Diagnostic[] oldArray = [.. diagnostics.OrderBy(d => d.Location.SourceSpan.Start)];
Diagnostic[] newArray = [.. newDiagnostics.OrderBy(d => d.Location.SourceSpan.Start)];
int oldIndex = 0;
int newIndex = 0;
while (newIndex < newArray.Length)
{
if (oldIndex < oldArray.Length && oldArray[oldIndex].Id == newArray[newIndex].Id)
{
++oldIndex;
++newIndex;
}
else
{
yield return newArray[newIndex++];
}
}
}
/// <summary>
/// Get the existing compiler diagnostics on the inputted document.
/// </summary>
/// <param name="document">The Document to run the compiler diagnostic analyzers on</param>
/// <returns>The compiler diagnostics that were found in the code</returns>
private static IEnumerable<Diagnostic> GetCompilerDiagnostics(Document document)
{
return (document.GetSemanticModelAsync().Result
?? throw new InvalidOperationException("Could not get semantic model")).GetDiagnostics();
}
/// <summary>
/// Given a document, turn it into a string based on the syntax root
/// </summary>
/// <param name="document">The Document to be converted to a string</param>
/// <returns>A string containing the syntax of the Document after formatting</returns>
private static string GetStringFromDocument(Document document)
{
Document simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
SyntaxNode root = simplifiedDoc.GetSyntaxRootAsync().Result
?? throw new InvalidOperationException("Could not get syntax root");
root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace);
return root.GetText().ToString();
}
}
}