Skip to content

Commit e007966

Browse files
committed
Add fix all status to the status page
1 parent ed1b03a commit e007966

4 files changed

Lines changed: 93 additions & 9 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Status.Generator
5+
{
6+
/// <summary>
7+
/// This enum captures the status of the implementation of a fix all provider.
8+
/// </summary>
9+
public enum FixAllStatus
10+
{
11+
/// <summary>
12+
/// No fix all provider is implemented for the given code fix.
13+
/// </summary>
14+
None,
15+
16+
/// <summary>
17+
/// The fix all provider for this code fix uses a custom optimized implementation.
18+
/// </summary>
19+
CustomImplementation,
20+
21+
/// <summary>
22+
/// The fix all capability is provided by the default batch fixer.
23+
/// This implementation might have various problems e.g. bad performance or it might not fix all problems at once.
24+
/// </summary>
25+
BatchFixer,
26+
}
27+
}

StyleCop.Analyzers/StyleCop.Analyzers.Status.Generator/SolutionReader.cs

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class SolutionReader
3737
private Compilation analyzerCompilation;
3838
private Compilation codeFixCompilation;
3939
private ITypeSymbol booleanType;
40+
private Type batchFixerType;
4041

4142
private SolutionReader()
4243
{
@@ -99,7 +100,6 @@ public async Task<ImmutableList<StyleCopDiagnostic>> GetDiagnosticsAsync()
99100
}
100101

101102
string shortName = match.Groups["name"].Value;
102-
CodeFixStatus codeFixStatus;
103103
string noCodeFixReason = null;
104104

105105
// Check if this syntax tree represents a diagnostic
@@ -130,7 +130,7 @@ public async Task<ImmutableList<StyleCopDiagnostic>> GetDiagnosticsAsync()
130130

131131
foreach (var descriptorInfo in descriptorInfos)
132132
{
133-
codeFixStatus = this.HasCodeFix(descriptorInfo.Id, classSymbol, out noCodeFixReason);
133+
var (codeFixStatus, fixAllStatus) = this.GetCodeFixAndFixAllStatus(descriptorInfo.Id, classSymbol, out noCodeFixReason);
134134
string status = this.GetStatus(classSymbol, syntaxRoot, semanticModel, descriptorInfo);
135135
if (descriptorInfo.CustomTags.Contains(WellKnownDiagnosticTags.NotConfigurable))
136136
{
@@ -147,6 +147,7 @@ public async Task<ImmutableList<StyleCopDiagnostic>> GetDiagnosticsAsync()
147147
Title = descriptorInfo.Title.ToString(),
148148
HelpLink = descriptorInfo.HelpLinkUri,
149149
CodeFixStatus = codeFixStatus,
150+
FixAllStatus = fixAllStatus,
150151
NoCodeFixReason = noCodeFixReason,
151152
};
152153
diagnostics.Add(diagnostic);
@@ -192,6 +193,8 @@ private async Task InitializeAsync()
192193
this.noCodeFixAttributeTypeSymbol = this.analyzerCompilation.GetTypeByMetadataName("StyleCop.Analyzers.NoCodeFixAttribute");
193194
this.diagnosticAnalyzerTypeSymbol = this.analyzerCompilation.GetTypeByMetadataName(typeof(DiagnosticAnalyzer).FullName);
194195

196+
this.batchFixerType = this.codeFixAssembly.GetType("StyleCop.Analyzers.Helpers.CustomBatchFixAllProvider");
197+
195198
this.InitializeCodeFixTypes();
196199
}
197200

@@ -284,18 +287,22 @@ private IEnumerable<DiagnosticDescriptor> GetDescriptor(INamedTypeSymbol classSy
284287
return analyzer.SupportedDiagnostics;
285288
}
286289

287-
private CodeFixStatus HasCodeFix(string diagnosticId, INamedTypeSymbol classSymbol, out string noCodeFixReason)
290+
private (CodeFixStatus, FixAllStatus) GetCodeFixAndFixAllStatus(string diagnosticId, INamedTypeSymbol classSymbol, out string noCodeFixReason)
288291
{
289-
CodeFixStatus status;
292+
CodeFixStatus codeFixStatus;
293+
FixAllStatus fixAllStatus;
290294

291295
noCodeFixReason = null;
292296

293-
var noCodeFixAttribute = classSymbol.GetAttributes().SingleOrDefault(x => x.AttributeClass == this.noCodeFixAttributeTypeSymbol);
297+
var noCodeFixAttribute = classSymbol
298+
.GetAttributes()
299+
.SingleOrDefault(x => x.AttributeClass == this.noCodeFixAttributeTypeSymbol);
294300

295301
bool hasCodeFix = noCodeFixAttribute == null;
296302
if (!hasCodeFix)
297303
{
298-
status = CodeFixStatus.NotImplemented;
304+
codeFixStatus = CodeFixStatus.NotImplemented;
305+
fixAllStatus = FixAllStatus.None;
299306
if (noCodeFixAttribute.ConstructorArguments.Length > 0)
300307
{
301308
noCodeFixReason = noCodeFixAttribute.ConstructorArguments[0].Value as string;
@@ -304,12 +311,41 @@ private CodeFixStatus HasCodeFix(string diagnosticId, INamedTypeSymbol classSymb
304311
else
305312
{
306313
// Check if the code fix actually exists
307-
hasCodeFix = this.CodeFixProviders.Any(x => x.FixableDiagnosticIds.Contains(diagnosticId));
314+
var codeFixes = this.CodeFixProviders
315+
.Where(x => x.FixableDiagnosticIds.Contains(diagnosticId))
316+
.Select(x => this.IsBatchFixer(x))
317+
.Where(x => x != null)
318+
.Select(x => (bool)x).ToArray();
319+
320+
hasCodeFix = codeFixes.Length > 0;
321+
322+
codeFixStatus = hasCodeFix ? CodeFixStatus.Implemented : CodeFixStatus.NotYetImplemented;
308323

309-
status = hasCodeFix ? CodeFixStatus.Implemented : CodeFixStatus.NotYetImplemented;
324+
if (codeFixes.Any(x => x))
325+
{
326+
fixAllStatus = FixAllStatus.BatchFixer;
327+
}
328+
else
329+
{
330+
fixAllStatus = FixAllStatus.CustomImplementation;
331+
}
310332
}
311333

312-
return status;
334+
return (codeFixStatus, fixAllStatus);
335+
}
336+
337+
private bool? IsBatchFixer(CodeFixProvider provider)
338+
{
339+
var fixAllProvider = provider.GetFixAllProvider();
340+
341+
if (fixAllProvider == null)
342+
{
343+
return null;
344+
}
345+
else
346+
{
347+
return fixAllProvider.GetType() == this.batchFixerType;
348+
}
313349
}
314350

315351
private bool InheritsFrom(INamedTypeSymbol declaration, INamedTypeSymbol possibleBaseType)

StyleCop.Analyzers/StyleCop.Analyzers.Status.Generator/StyleCopDiagnostic.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ public class StyleCopDiagnostic
5959
[JsonConverter(typeof(StringEnumConverter))]
6060
public CodeFixStatus CodeFixStatus { get; set; }
6161

62+
/// <summary>
63+
/// Gets or sets a value that represents how the fix all functionality is implemented.
64+
/// </summary>
65+
/// <value>
66+
/// A value that represents how the fix all functionality is implemented.
67+
/// </value>
68+
[JsonConverter(typeof(StringEnumConverter))]
69+
public FixAllStatus FixAllStatus { get; set; }
70+
6271
/// <summary>
6372
/// Gets or sets the reason why a code fix is not implemented, or <see langword="null"/> if there is
6473
/// no reason.

docs/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ <h2>This page is reporting the current status of <a href="https://github.com/Dot
7878
<td style="overflow: visible; width: 0;">
7979
Code Fix
8080
</td>
81+
<td style="overflow: visible; width: 0;">
82+
Fix All Provider
83+
</td>
8184
<td></td>
8285
</tr>
8386
</thead>
@@ -125,6 +128,15 @@ <h2>This page is reporting the current status of <a href="https://github.com/Dot
125128
<i class="fa fa-times" style="color: red;"></i>
126129
{{/if}}
127130
</td>
131+
<td style="overflow: visible; width: 0;">
132+
{{if FixAllStatus === "BatchFixer"}}
133+
<i class="fa fa-hourglass" style="color: blue;"></i>
134+
{{else CodeFixStatus === CustomImplementation}}
135+
<i class="fa fa-check" style="color: green;"></i>
136+
{{else}}
137+
<i class="fa fa-times" style="color: red;"></i>
138+
{{/if}}
139+
</td>
128140
<td></td>
129141
</tr>
130142

0 commit comments

Comments
 (0)