You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

CodeFixVerifier.Helper.cs 3.9 KiB

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