Skip to content

Commit

Permalink
Extract helper method RenameHelper.IsValidNewMemberName
Browse files Browse the repository at this point in the history
This helper is a combination of work on DotNetAnalyzers#436 and DotNetAnalyzers#437, and offers a more
flexible solution for avoiding conflicts during rename operations.
  • Loading branch information
sharwell committed Nov 27, 2015
1 parent 27d36be commit 78bcb26
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,43 @@ public static async Task<Solution> RenameSymbolAsync(Document document, SyntaxNo
// TODO: return annotatedSolution instead of newSolution if newSolution contains any new errors (for any project)
return newSolution;
}

public static bool IsValidNewMemberName(SemanticModel semanticModel, ISymbol symbol, string name)
{
var members = (symbol as INamedTypeSymbol)?.GetMembers(name);
if (members.HasValue && !members.Value.IsDefaultOrEmpty)
{
return false;
}

var containingSymbol = symbol.ContainingSymbol as INamespaceOrTypeSymbol;
if (containingSymbol == null)
{
return true;
}

if (containingSymbol.Kind == SymbolKind.Namespace)
{
// Make sure to use the compilation namespace so interfaces in referenced assemblies are considered
containingSymbol = semanticModel.Compilation.GetCompilationNamespace((INamespaceSymbol)containingSymbol);
}
else if (containingSymbol.Kind == SymbolKind.NamedType)
{
// The name can't be the same as the name of the containing type
if (containingSymbol.Name == name)
{
return false;
}
}

// The name can't be the same as the name of an other member of the same type
members = containingSymbol.GetMembers(name);
if (!members.Value.IsDefaultOrEmpty)
{
return false;
}

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,10 @@ private static async Task<Solution> CreateChangedSolutionAsync(Document document

var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var declaredSymbol = semanticModel.GetDeclaredSymbol(token.Parent, cancellationToken);
INamedTypeSymbol interfaceType = declaredSymbol as INamedTypeSymbol;
if (interfaceType != null)
while (!RenameHelper.IsValidNewMemberName(semanticModel, declaredSymbol, newName))
{
var containingSymbol = interfaceType.ContainingSymbol as INamespaceOrTypeSymbol;
var containingNamespace = containingSymbol as INamespaceSymbol;
if (containingNamespace != null)
{
// Make sure to use the compilation namespace so interfaces in referenced assemblies are considered
containingSymbol = semanticModel.Compilation.GetCompilationNamespace(containingNamespace);
}

if (containingSymbol != null)
{
while (containingSymbol.GetMembers(newName).Any())
{
index++;
newName = baseName + index;
}
}
index++;
newName = baseName + index;
}

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

0 comments on commit 78bcb26

Please sign in to comment.