@@ -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