Skip to content

Commit 24ccd60

Browse files
committed
Update RenameToUpperCaseCodeFixProvider to support conflict resolution
Fixes #437
1 parent 575d877 commit 24ccd60

1 file changed

Lines changed: 23 additions & 46 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/RenameToUpperCaseCodeFixProvider.cs

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ namespace StyleCop.Analyzers.NamingRules
2626
[Shared]
2727
internal class RenameToUpperCaseCodeFixProvider : CodeFixProvider
2828
{
29+
/// <summary>
30+
/// During conflict resolution for fields, this suffix is tried before falling back to 1, 2, 3, etc...
31+
/// </summary>
2932
private const string Suffix = "Value";
3033

3134
/// <inheritdoc/>
@@ -52,8 +55,9 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
5255
foreach (var diagnostic in context.Diagnostics)
5356
{
5457
var token = root.FindToken(diagnostic.Location.SourceSpan.Start);
55-
var newName = char.ToUpper(token.ValueText[0]) + token.ValueText.Substring(1);
56-
var memberSyntax = this.GetParentTypeDeclaration(token);
58+
var baseName = char.ToUpper(token.ValueText[0]) + token.ValueText.Substring(1);
59+
var newName = baseName;
60+
var memberSyntax = GetParentTypeDeclaration(token);
5761

5862
if (memberSyntax is NamespaceDeclarationSyntax)
5963
{
@@ -62,9 +66,9 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
6266
{
6367
IdentifierNameSyntax identifierSyntax = (IdentifierNameSyntax)token.Parent;
6468

65-
var newIdentifierSyntac = identifierSyntax.WithIdentifier(SyntaxFactory.Identifier(newName));
69+
var newIdentifierSyntax = identifierSyntax.WithIdentifier(SyntaxFactory.Identifier(newName));
6670

67-
var newRoot = root.ReplaceNode(identifierSyntax, newIdentifierSyntac);
71+
var newRoot = root.ReplaceNode(identifierSyntax, newIdentifierSyntax);
6872
return Task.FromResult(context.Document.WithSyntaxRoot(newRoot));
6973
};
7074

@@ -79,65 +83,38 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
7983
{
8084
SemanticModel semanticModel = await document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
8185

82-
var typeDeclarationSymbol = semanticModel.GetDeclaredSymbol(memberSyntax);
83-
if (typeDeclarationSymbol == null)
86+
var declaredSymbol = semanticModel.GetDeclaredSymbol(memberSyntax);
87+
if (declaredSymbol == null)
8488
{
8589
continue;
8690
}
8791

88-
if (!this.IsValidNewMemberName(typeDeclarationSymbol, newName))
92+
bool usedSuffix = false;
93+
if (declaredSymbol.Kind == SymbolKind.Field && !RenameHelper.IsValidNewMemberName(semanticModel, declaredSymbol, newName))
8994
{
95+
usedSuffix = true;
9096
newName = newName + Suffix;
9197
}
9298

99+
int index = 0;
100+
while (!RenameHelper.IsValidNewMemberName(semanticModel, declaredSymbol, newName))
101+
{
102+
usedSuffix = false;
103+
index++;
104+
newName = baseName + index;
105+
}
106+
93107
context.RegisterCodeFix(
94108
CodeAction.Create(
95109
string.Format(NamingResources.RenameToCodeFix, newName),
96110
cancellationToken => RenameHelper.RenameSymbolAsync(document, root, token, newName, cancellationToken),
97-
nameof(RenameToUpperCaseCodeFixProvider) + "_" + diagnostic.Id),
111+
nameof(RenameToUpperCaseCodeFixProvider) + "_" + diagnostic.Id + "_" + usedSuffix + "_" + index),
98112
diagnostic);
99113
}
100114
}
101115
}
102116

103-
private bool IsValidNewMemberName(ISymbol typeSymbol, string name)
104-
{
105-
if (typeSymbol == null)
106-
{
107-
throw new ArgumentNullException(nameof(typeSymbol));
108-
}
109-
else if (typeSymbol.Name == name)
110-
{
111-
return false;
112-
}
113-
114-
var members = (typeSymbol as INamedTypeSymbol)?.GetMembers(name);
115-
if (members.HasValue && !members.Value.IsDefaultOrEmpty)
116-
{
117-
return false;
118-
}
119-
120-
var containingType = typeSymbol.ContainingSymbol as INamedTypeSymbol;
121-
if (containingType != null)
122-
{
123-
// The name can't be the same as the name of the containing type
124-
if (containingType.Name == name)
125-
{
126-
return false;
127-
}
128-
129-
// The name can't be the same as the name of an other member of the same type
130-
members = containingType.GetMembers(name);
131-
if (!members.Value.IsDefaultOrEmpty)
132-
{
133-
return false;
134-
}
135-
}
136-
137-
return true;
138-
}
139-
140-
private SyntaxNode GetParentTypeDeclaration(SyntaxToken token)
117+
private static SyntaxNode GetParentTypeDeclaration(SyntaxToken token)
141118
{
142119
SyntaxNode parent = token.Parent;
143120

0 commit comments

Comments
 (0)