Skip to content

Commit ca2ab10

Browse files
committed
Update SA1302 code fix to support conflict resolution
Fixes #436
1 parent 1e5a42c commit ca2ab10

3 files changed

Lines changed: 43 additions & 8 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/SA1302CodeFixProvider.cs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace StyleCop.Analyzers.NamingRules
55
{
66
using System.Collections.Immutable;
77
using System.Composition;
8+
using System.Linq;
9+
using System.Threading;
810
using System.Threading.Tasks;
911
using Helpers;
1012
using Microsoft.CodeAnalysis;
@@ -27,22 +29,43 @@ internal class SA1302CodeFixProvider : CodeFixProvider
2729
ImmutableArray.Create(SA1302InterfaceNamesMustBeginWithI.DiagnosticId);
2830

2931
/// <inheritdoc/>
30-
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
32+
public override Task RegisterCodeFixesAsync(CodeFixContext context)
3133
{
32-
var document = context.Document;
33-
var root = await document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
34-
3534
foreach (var diagnostic in context.Diagnostics)
3635
{
37-
var token = root.FindToken(diagnostic.Location.SourceSpan.Start);
38-
var newName = "I" + token.ValueText;
3936
context.RegisterCodeFix(
4037
CodeAction.Create(
41-
string.Format(NamingResources.RenameToCodeFix, newName),
42-
cancellationToken => RenameHelper.RenameSymbolAsync(document, root, token, newName, cancellationToken),
38+
NamingResources.SA1302CodeFix,
39+
cancellationToken => CreateChangedSolutionAsync(context.Document, diagnostic, cancellationToken),
4340
nameof(SA1302CodeFixProvider)),
4441
diagnostic);
4542
}
43+
44+
return SpecializedTasks.CompletedTask;
45+
}
46+
47+
private static async Task<Solution> CreateChangedSolutionAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
48+
{
49+
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
50+
var token = root.FindToken(diagnostic.Location.SourceSpan.Start);
51+
var baseName = "I" + token.ValueText;
52+
var index = 0;
53+
var newName = baseName;
54+
55+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
56+
var declaredSymbol = semanticModel.GetDeclaredSymbol(token.Parent, cancellationToken);
57+
INamedTypeSymbol interfaceType = declaredSymbol as INamedTypeSymbol;
58+
if (interfaceType != null)
59+
{
60+
var containingNamespace = semanticModel.Compilation.GetCompilationNamespace(interfaceType.ContainingNamespace);
61+
while (containingNamespace.GetMembers(newName).Any())
62+
{
63+
index++;
64+
newName = baseName + index;
65+
}
66+
}
67+
68+
return await RenameHelper.RenameSymbolAsync(document, root, token, newName, cancellationToken).ConfigureAwait(false);
4669
}
4770
}
4871
}

StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/NamingResources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/NamingResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@
120120
<data name="RenameToCodeFix" xml:space="preserve">
121121
<value>Rename To '{0}'</value>
122122
</data>
123+
<data name="SA1302CodeFix" xml:space="preserve">
124+
<value>Prefix interface name with 'I'</value>
125+
</data>
123126
<data name="SA1312Description" xml:space="preserve">
124127
<value>The name of a variable in C# does not begin with a lower-case letter.</value>
125128
</data>

0 commit comments

Comments
 (0)