提交 49c929da 编写于 作者: J JieCarolHu

Fixing false unresolvedConflict when renaming overloaded VB properties

上级 bf97306c
......@@ -40,7 +40,7 @@ internal static partial class ConflictResolver
/// <param name="originalText">The original name of the identifier.</param>
/// <param name="replacementText">The new name of the identifier</param>
/// <param name="optionSet">The option for rename</param>
/// <param name="hasConflict">Called after renaming references. Can be used by callers to
/// <param name="hasConflict">Called after renaming references. Can be used by callers to
/// indicate if the new symbols that the reference binds to should be considered to be ok or
/// are in conflict. 'true' means they are conflicts. 'false' means they are not conflicts.
/// 'null' means that the default conflict check should be used.</param>
......@@ -185,10 +185,24 @@ private static bool IsRenameValid(ConflictResolution conflictResolution, ISymbol
{
var otherThingsNamedTheSame = renamedSymbol.ContainingType.GetMembers(renamedSymbol.Name)
.Where(s => !s.Equals(renamedSymbol) &&
string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal) &&
(s.Kind != SymbolKind.Method || renamedSymbol.Kind != SymbolKind.Method));
string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal));
AddConflictingSymbolLocations(otherThingsNamedTheSame, conflictResolution, reverseMappedLocations);
// excluded Method or Property(only for VB) here, as they may have the same name but different parameters
IEnumerable<ISymbol> otherThingsNamedTheSameExcludeMethodAndParameterizedProperty;
if (renamedSymbol.Language == LanguageNames.VisualBasic)
{
// Only VB allows Parameterized Properties
otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame
.Where(s=> (s.Kind != SymbolKind.Method && s.Kind != SymbolKind.Property) ||
(renamedSymbol.Kind != SymbolKind.Method && renamedSymbol.Kind != SymbolKind.Property));
}
else
{
otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame
.Where(s => s.Kind != SymbolKind.Method || renamedSymbol.Kind != SymbolKind.Method);
}
AddConflictingSymbolLocations(otherThingsNamedTheSameExcludeMethodAndParameterizedProperty, conflictResolution, reverseMappedLocations);
}
......
......@@ -44,6 +44,36 @@ public static ImmutableArray<Location> GetMembersWithConflictingSignatures(IMeth
return builder.ToImmutableAndFree();
}
public static ImmutableArray<Location> GetMembersWithConflictingSignatures(IPropertySymbol renamedProperty, bool trimOptionalParameters)
{
var potentiallyConfictingProperties =
renamedProperty.ContainingType.GetMembers(renamedProperty.Name)
.OfType<IPropertySymbol>()
.Where(m => !m.Equals(renamedProperty) && m.Parameters.Count() == renamedProperty.Parameters.Count());
var signatureToConflictingMember = new Dictionary<ImmutableArray<ITypeSymbol>, IPropertySymbol>(ConflictingSignatureComparer.Instance);
foreach (var property in potentiallyConfictingProperties)
{
foreach (var signature in GetAllSignatures(property, trimOptionalParameters))
{
signatureToConflictingMember[signature] = property;
}
}
var builder = ArrayBuilder<Location>.GetInstance();
foreach (var signature in GetAllSignatures(renamedProperty, trimOptionalParameters))
{
if (signatureToConflictingMember.TryGetValue(signature, out var conflictingSymbol))
{
builder.AddRange(conflictingSymbol.Locations);
}
}
return builder.ToImmutableAndFree();
}
private sealed class ConflictingSignatureComparer : IEqualityComparer<ImmutableArray<ITypeSymbol>>
{
public static readonly ConflictingSignatureComparer Instance = new ConflictingSignatureComparer();
......@@ -57,9 +87,9 @@ public bool Equals(ImmutableArray<ITypeSymbol> x, ImmutableArray<ITypeSymbol> y)
public int GetHashCode(ImmutableArray<ITypeSymbol> obj)
{
// This is a very simple GetHashCode implementation. Doing something "fancier" here
// isn't really worth it, since to compute a proper hash we'd end up walking all the
// ITypeSymbols anyways.
// This is a very simple GetHashCode implementation. Doing something "fancier" here
// isn't really worth it, since to compute a proper hash we'd end up walking all the
// ITypeSymbols anyways.
return obj.Length;
}
}
......@@ -91,5 +121,28 @@ private static ImmutableArray<ImmutableArray<ITypeSymbol>> GetAllSignatures(IMet
resultBuilder.Add(signatureBuilder.ToImmutableAndFree());
return resultBuilder.ToImmutableAndFree();
}
private static ImmutableArray<ImmutableArray<ITypeSymbol>> GetAllSignatures(IPropertySymbol method, bool trimOptionalParameters)
{
var resultBuilder = ArrayBuilder<ImmutableArray<ITypeSymbol>>.GetInstance();
var signatureBuilder = ArrayBuilder<ITypeSymbol>.GetInstance();
foreach (var parameter in method.Parameters)
{
// In VB, a method effectively creates multiple signatures which are produced by
// chopping off each of the optional parameters on the end, last to first, per 4.1.1 of
// the spec.
if (trimOptionalParameters && parameter.IsOptional)
{
resultBuilder.Add(signatureBuilder.ToImmutable());
}
signatureBuilder.Add(parameter.Type);
}
resultBuilder.Add(signatureBuilder.ToImmutableAndFree());
return resultBuilder.ToImmutableAndFree();
}
}
}
......@@ -731,6 +731,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Rename
.Select(Function(loc) reverseMappedLocations(loc)))
ElseIf renamedSymbol.Kind = SymbolKind.Property Then
conflicts.AddRange(
DeclarationConflictHelpers.GetMembersWithConflictingSignatures(DirectCast(renamedSymbol, IPropertySymbol), trimOptionalParameters:=True) _
.Select(Function(loc) reverseMappedLocations(loc)))
ConflictResolver.AddConflictingParametersOfProperties(
referencedSymbols.Select(Function(s) s.Symbol).Concat(renameSymbol).Where(Function(sym) sym.Kind = SymbolKind.Property),
renamedSymbol.Name,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册