|
3 | 3 |
|
4 | 4 | namespace StyleCop.Analyzers.MaintainabilityRules |
5 | 5 | { |
| 6 | + using System.Collections.Immutable; |
| 7 | + using System.Linq; |
| 8 | + using System.Threading; |
6 | 9 | using System.Threading.Tasks; |
| 10 | + using Helpers; |
7 | 11 | using Microsoft.CodeAnalysis; |
8 | 12 | using Microsoft.CodeAnalysis.CodeActions; |
9 | 13 | using Microsoft.CodeAnalysis.CodeFixes; |
10 | 14 |
|
11 | 15 | internal sealed class SA1412FixAllProvider : FixAllProvider |
12 | 16 | { |
13 | | - public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext) |
| 17 | + public override Task<CodeAction> GetFixAsync(FixAllContext fixAllContext) |
14 | 18 | { |
15 | | - Solution newSolution; |
| 19 | + string title = string.Format(MaintainabilityResources.SA1412CodeFix, fixAllContext.CodeActionEquivalenceKey.Substring(fixAllContext.CodeActionEquivalenceKey.IndexOf('.') + 1)); |
16 | 20 |
|
| 21 | + CodeAction fixAction; |
17 | 22 | switch (fixAllContext.Scope) |
18 | 23 | { |
19 | 24 | case FixAllScope.Document: |
20 | | - newSolution = await FixDocumentAsync(fixAllContext, fixAllContext.Document).ConfigureAwait(false); |
| 25 | + fixAction = CodeAction.Create( |
| 26 | + title, |
| 27 | + cancellationToken => this.GetDocumentFixesAsync(fixAllContext.WithCancellationToken(cancellationToken)), |
| 28 | + nameof(SA1412FixAllProvider)); |
21 | 29 | break; |
22 | 30 |
|
23 | 31 | case FixAllScope.Project: |
24 | | - newSolution = await GetProjectFixesAsync(fixAllContext, fixAllContext.Project).ConfigureAwait(false); |
| 32 | + fixAction = CodeAction.Create( |
| 33 | + title, |
| 34 | + cancellationToken => this.GetProjectFixesAsync(fixAllContext.WithCancellationToken(cancellationToken), fixAllContext.Project), |
| 35 | + nameof(SA1412FixAllProvider)); |
25 | 36 | break; |
26 | 37 |
|
27 | 38 | case FixAllScope.Solution: |
28 | | - newSolution = fixAllContext.Solution; |
29 | | - var projectIds = newSolution.ProjectIds; |
30 | | - for (int i = 0; i < projectIds.Count; i++) |
31 | | - { |
32 | | - newSolution = await GetProjectFixesAsync(fixAllContext, newSolution.GetProject(projectIds[i])).ConfigureAwait(false); |
33 | | - } |
34 | | - |
| 39 | + fixAction = CodeAction.Create( |
| 40 | + title, |
| 41 | + cancellationToken => this.GetSolutionFixesAsync(fixAllContext.WithCancellationToken(cancellationToken)), |
| 42 | + nameof(SA1412FixAllProvider)); |
35 | 43 | break; |
36 | 44 |
|
37 | 45 | case FixAllScope.Custom: |
38 | 46 | default: |
39 | | - return null; |
| 47 | + fixAction = null; |
| 48 | + break; |
40 | 49 | } |
41 | 50 |
|
42 | | - return CodeAction.Create( |
43 | | - string.Format(MaintainabilityResources.SA1412CodeFix, fixAllContext.CodeActionEquivalenceKey.Substring(fixAllContext.CodeActionEquivalenceKey.IndexOf('.') + 1)), |
44 | | - token => Task.FromResult(newSolution)); |
| 51 | + return Task.FromResult(fixAction); |
45 | 52 | } |
46 | 53 |
|
47 | | - private static async Task<Solution> FixDocumentAsync(FixAllContext fixAllContext, Document document) |
| 54 | + private static async Task<Solution> FixDocumentAsync(Solution solution, DocumentId documentId, ImmutableArray<Diagnostic> diagnostics, string codeActionEquivalenceKey, CancellationToken cancellationToken) |
48 | 55 | { |
49 | | - Solution solution = document.Project.Solution; |
50 | | - var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false); |
51 | | - if (diagnostics.Length == 0) |
| 56 | + if (diagnostics.IsEmpty) |
52 | 57 | { |
53 | 58 | return solution; |
54 | 59 | } |
55 | 60 |
|
56 | 61 | string equivalenceKey = nameof(SA1412CodeFixProvider) + "." + diagnostics[0].Properties[SA1412StoreFilesAsUtf8.EncodingProperty]; |
57 | | - if (fixAllContext.CodeActionEquivalenceKey != equivalenceKey) |
| 62 | + if (codeActionEquivalenceKey != equivalenceKey) |
58 | 63 | { |
59 | 64 | return solution; |
60 | 65 | } |
61 | 66 |
|
62 | | - return await SA1412CodeFixProvider.GetTransformedSolutionAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false); |
| 67 | + Document document = solution.GetDocument(documentId); |
| 68 | + return await SA1412CodeFixProvider.GetTransformedSolutionAsync(document, cancellationToken).ConfigureAwait(false); |
63 | 69 | } |
64 | 70 |
|
65 | | - private static async Task<Solution> GetProjectFixesAsync(FixAllContext fixAllContext, Project project) |
| 71 | + private async Task<Solution> GetDocumentFixesAsync(FixAllContext fixAllContext) |
66 | 72 | { |
67 | | - Solution solution = project.Solution; |
| 73 | + var documentDiagnosticsToFix = await FixAllContextHelper.GetDocumentDiagnosticsToFixAsync(fixAllContext).ConfigureAwait(false); |
| 74 | + ImmutableArray<Diagnostic> diagnostics; |
| 75 | + if (!documentDiagnosticsToFix.TryGetValue(fixAllContext.Document, out diagnostics)) |
| 76 | + { |
| 77 | + return fixAllContext.Document.Project.Solution; |
| 78 | + } |
| 79 | + |
| 80 | + return await FixDocumentAsync(fixAllContext.Document.Project.Solution, fixAllContext.Document.Id, diagnostics, fixAllContext.CodeActionEquivalenceKey, fixAllContext.CancellationToken).ConfigureAwait(false); |
| 81 | + } |
68 | 82 |
|
69 | | - var documentIds = project.DocumentIds; |
| 83 | + private async Task<Solution> GetSolutionFixesAsync(FixAllContext fixAllContext, ImmutableArray<Document> documents) |
| 84 | + { |
| 85 | + var documentDiagnosticsToFix = await FixAllContextHelper.GetDocumentDiagnosticsToFixAsync(fixAllContext).ConfigureAwait(false); |
70 | 86 |
|
71 | | - foreach (var documentId in documentIds) |
| 87 | + Solution solution = fixAllContext.Solution; |
| 88 | + foreach (var document in documents) |
72 | 89 | { |
73 | | - solution = await FixDocumentAsync(fixAllContext, solution.GetDocument(documentId)).ConfigureAwait(false); |
| 90 | + ImmutableArray<Diagnostic> diagnostics; |
| 91 | + if (!documentDiagnosticsToFix.TryGetValue(document, out diagnostics)) |
| 92 | + { |
| 93 | + continue; |
| 94 | + } |
| 95 | + |
| 96 | + solution = await FixDocumentAsync(solution, document.Id, diagnostics, fixAllContext.CodeActionEquivalenceKey, fixAllContext.CancellationToken).ConfigureAwait(false); |
74 | 97 | } |
75 | 98 |
|
76 | 99 | return solution; |
77 | 100 | } |
| 101 | + |
| 102 | + private Task<Solution> GetProjectFixesAsync(FixAllContext fixAllContext, Project project) |
| 103 | + { |
| 104 | + return this.GetSolutionFixesAsync(fixAllContext, project.Documents.ToImmutableArray()); |
| 105 | + } |
| 106 | + |
| 107 | + private Task<Solution> GetSolutionFixesAsync(FixAllContext fixAllContext) |
| 108 | + { |
| 109 | + ImmutableArray<Document> documents = fixAllContext.Solution.Projects.SelectMany(i => i.Documents).ToImmutableArray(); |
| 110 | + return this.GetSolutionFixesAsync(fixAllContext, documents); |
| 111 | + } |
78 | 112 | } |
79 | 113 | } |
0 commit comments