Skip to content

Commit 78bcb26

Browse files
committed
Extract helper method RenameHelper.IsValidNewMemberName
This helper is a combination of work on #436 and #437, and offers a more flexible solution for avoiding conflicts during rename operations.
1 parent 27d36be commit 78bcb26

2 files changed

Lines changed: 41 additions & 18 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/Helpers/RenameHelper.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,43 @@ public static async Task<Solution> RenameSymbolAsync(Document document, SyntaxNo
2828
// TODO: return annotatedSolution instead of newSolution if newSolution contains any new errors (for any project)
2929
return newSolution;
3030
}
31+
32+
public static bool IsValidNewMemberName(SemanticModel semanticModel, ISymbol symbol, string name)
33+
{
34+
var members = (symbol as INamedTypeSymbol)?.GetMembers(name);
35+
if (members.HasValue && !members.Value.IsDefaultOrEmpty)
36+
{
37+
return false;
38+
}
39+
40+
var containingSymbol = symbol.ContainingSymbol as INamespaceOrTypeSymbol;
41+
if (containingSymbol == null)
42+
{
43+
return true;
44+
}
45+
46+
if (containingSymbol.Kind == SymbolKind.Namespace)
47+
{
48+
// Make sure to use the compilation namespace so interfaces in referenced assemblies are considered
49+
containingSymbol = semanticModel.Compilation.GetCompilationNamespace((INamespaceSymbol)containingSymbol);
50+
}
51+
else if (containingSymbol.Kind == SymbolKind.NamedType)
52+
{
53+
// The name can't be the same as the name of the containing type
54+
if (containingSymbol.Name == name)
55+
{
56+
return false;
57+
}
58+
}
59+
60+
// The name can't be the same as the name of an other member of the same type
61+
members = containingSymbol.GetMembers(name);
62+
if (!members.Value.IsDefaultOrEmpty)
63+
{
64+
return false;
65+
}
66+
67+
return true;
68+
}
3169
}
3270
}

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

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,10 @@ private static async Task<Solution> CreateChangedSolutionAsync(Document document
5454

5555
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
5656
var declaredSymbol = semanticModel.GetDeclaredSymbol(token.Parent, cancellationToken);
57-
INamedTypeSymbol interfaceType = declaredSymbol as INamedTypeSymbol;
58-
if (interfaceType != null)
57+
while (!RenameHelper.IsValidNewMemberName(semanticModel, declaredSymbol, newName))
5958
{
60-
var containingSymbol = interfaceType.ContainingSymbol as INamespaceOrTypeSymbol;
61-
var containingNamespace = containingSymbol as INamespaceSymbol;
62-
if (containingNamespace != null)
63-
{
64-
// Make sure to use the compilation namespace so interfaces in referenced assemblies are considered
65-
containingSymbol = semanticModel.Compilation.GetCompilationNamespace(containingNamespace);
66-
}
67-
68-
if (containingSymbol != null)
69-
{
70-
while (containingSymbol.GetMembers(newName).Any())
71-
{
72-
index++;
73-
newName = baseName + index;
74-
}
75-
}
59+
index++;
60+
newName = baseName + index;
7661
}
7762

7863
return await RenameHelper.RenameSymbolAsync(document, root, token, newName, cancellationToken).ConfigureAwait(false);

0 commit comments

Comments
 (0)