CodeFixVerifier.Helper.cs 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // Most of the code in this file comes from the default Roslyn Analyzer project template
  4. using Microsoft.CodeAnalysis;
  5. using Microsoft.CodeAnalysis.CodeActions;
  6. using Microsoft.CodeAnalysis.Formatting;
  7. using Microsoft.CodeAnalysis.Simplification;
  8. namespace TestHelper;
  9. /// <summary>
  10. /// Diagnostic Producer class with extra methods dealing with applying codefixes
  11. /// All methods are static
  12. /// </summary>
  13. public abstract partial class CodeFixVerifier : DiagnosticVerifier
  14. {
  15. /// <summary>
  16. /// Apply the inputted CodeAction to the inputted document.
  17. /// Meant to be used to apply codefixes.
  18. /// </summary>
  19. /// <param name="document">The Document to apply the fix on</param>
  20. /// <param name="codeAction">A CodeAction that will be applied to the Document.</param>
  21. /// <returns>A Document with the changes from the CodeAction</returns>
  22. private static Document ApplyFix(Document document, CodeAction codeAction)
  23. {
  24. var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;
  25. var solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution;
  26. return solution.GetDocument(document.Id);
  27. }
  28. /// <summary>
  29. /// Compare two collections of Diagnostics,and return a list of any new diagnostics that appear only in the second collection.
  30. /// 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,
  31. /// this method may not necessarily return the new one.
  32. /// </summary>
  33. /// <param name="diagnostics">The Diagnostics that existed in the code before the CodeFix was applied</param>
  34. /// <param name="newDiagnostics">The Diagnostics that exist in the code after the CodeFix was applied</param>
  35. /// <returns>A list of Diagnostics that only surfaced in the code after the CodeFix was applied</returns>
  36. private static IEnumerable<Diagnostic> GetNewDiagnostics(IEnumerable<Diagnostic> diagnostics, IEnumerable<Diagnostic> newDiagnostics)
  37. {
  38. var oldArray = diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray();
  39. var newArray = newDiagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray();
  40. int oldIndex = 0;
  41. int newIndex = 0;
  42. while (newIndex < newArray.Length)
  43. {
  44. if (oldIndex < oldArray.Length && oldArray[oldIndex].Id == newArray[newIndex].Id)
  45. {
  46. ++oldIndex;
  47. ++newIndex;
  48. }
  49. else
  50. {
  51. yield return newArray[newIndex++];
  52. }
  53. }
  54. }
  55. /// <summary>
  56. /// Get the existing compiler diagnostics on the inputted document.
  57. /// </summary>
  58. /// <param name="document">The Document to run the compiler diagnostic analyzers on</param>
  59. /// <returns>The compiler diagnostics that were found in the code</returns>
  60. private static IEnumerable<Diagnostic> GetCompilerDiagnostics(Document document)
  61. {
  62. return document.GetSemanticModelAsync().Result.GetDiagnostics();
  63. }
  64. /// <summary>
  65. /// Given a document, turn it into a string based on the syntax root
  66. /// </summary>
  67. /// <param name="document">The Document to be converted to a string</param>
  68. /// <returns>A string containing the syntax of the Document after formatting</returns>
  69. private static string GetStringFromDocument(Document document)
  70. {
  71. var simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
  72. var root = simplifiedDoc.GetSyntaxRootAsync().Result;
  73. root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace);
  74. return root.GetText().ToString();
  75. }
  76. }