Skip to content

Commit d5dfe95

Browse files
Merge pull request #74932 from CyrusNajmabadi/simplifyEquivalence
2 parents edadee5 + 842e645 commit d5dfe95

4 files changed

+28
-43
lines changed

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs

+10-14
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,33 @@ namespace Microsoft.CodeAnalysis.Shared.Utilities;
1313

1414
internal partial class SymbolEquivalenceComparer
1515
{
16-
private class EquivalenceVisitor(
16+
private sealed class EquivalenceVisitor(
1717
SymbolEquivalenceComparer symbolEquivalenceComparer,
18-
bool compareMethodTypeParametersByIndex,
19-
bool objectAndDynamicCompareEqually)
18+
bool compareMethodTypeParametersByIndex)
2019
{
21-
2220
public bool AreEquivalent(ISymbol? x, ISymbol? y, Dictionary<INamedTypeSymbol, INamedTypeSymbol>? equivalentTypesWithDifferingAssemblies)
2321
{
2422
if (ReferenceEquals(x, y))
25-
{
2623
return true;
27-
}
2824

2925
if (x == null || y == null)
30-
{
3126
return false;
32-
}
3327

3428
var xKind = GetKindAndUnwrapAlias(ref x);
3529
var yKind = GetKindAndUnwrapAlias(ref y);
3630

3731
// Normally, if they're different types, then they're not the same.
3832
if (xKind != yKind)
3933
{
40-
// Special case. If we're comparing signatures then we want to compare 'object'
41-
// and 'dynamic' as the same. However, since they're different types, we don't
42-
// want to bail out using the above check.
43-
if (objectAndDynamicCompareEqually)
34+
// Special case. If we're comparing signatures then we want to compare 'object' and 'dynamic' as the
35+
// same. However, since they're different types, we don't want to bail out using the above check.
36+
if (symbolEquivalenceComparer._objectAndDynamicCompareEqually)
4437
{
45-
return (xKind == SymbolKind.DynamicType && IsObjectType(y)) ||
46-
(yKind == SymbolKind.DynamicType && IsObjectType(x));
38+
if ((xKind == SymbolKind.DynamicType && IsObjectType(y)) ||
39+
(yKind == SymbolKind.DynamicType && IsObjectType(x)))
40+
{
41+
return true;
42+
}
4743
}
4844

4945
return false;

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.GetHashCodeVisitor.cs

+3-6
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,19 @@ namespace Microsoft.CodeAnalysis.Shared.Utilities;
1313

1414
internal partial class SymbolEquivalenceComparer
1515
{
16-
private class GetHashCodeVisitor
16+
private sealed class GetHashCodeVisitor
1717
{
1818
private readonly SymbolEquivalenceComparer _symbolEquivalenceComparer;
1919
private readonly bool _compareMethodTypeParametersByIndex;
20-
private readonly bool _objectAndDynamicCompareEqually;
2120
private readonly Func<int, IParameterSymbol, int> _parameterAggregator;
2221
private readonly Func<int, ISymbol, int> _symbolAggregator;
2322

2423
public GetHashCodeVisitor(
2524
SymbolEquivalenceComparer symbolEquivalenceComparer,
26-
bool compareMethodTypeParametersByIndex,
27-
bool objectAndDynamicCompareEqually)
25+
bool compareMethodTypeParametersByIndex)
2826
{
2927
_symbolEquivalenceComparer = symbolEquivalenceComparer;
3028
_compareMethodTypeParametersByIndex = compareMethodTypeParametersByIndex;
31-
_objectAndDynamicCompareEqually = objectAndDynamicCompareEqually;
3229
_parameterAggregator = (acc, sym) => Hash.Combine(symbolEquivalenceComparer.ParameterEquivalenceComparer.GetHashCode(sym), acc);
3330
_symbolAggregator = (acc, sym) => GetHashCode(sym, acc);
3431
}
@@ -45,7 +42,7 @@ public int GetHashCode(ISymbol? x, int currentHash)
4542
// want to bail out using the above check.
4643

4744
if (x.Kind == SymbolKind.DynamicType ||
48-
(_objectAndDynamicCompareEqually && IsObjectType(x)))
45+
(_symbolEquivalenceComparer._objectAndDynamicCompareEqually && IsObjectType(x)))
4946
{
5047
return Hash.Combine(GetNullableAnnotationsHashCode((ITypeSymbol)x), Hash.Combine(typeof(IDynamicTypeSymbol), currentHash));
5148
}

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.SignatureTypeSymbolEquivalenceComparer.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ namespace Microsoft.CodeAnalysis.Shared.Utilities;
88

99
internal partial class SymbolEquivalenceComparer
1010
{
11-
internal class SignatureTypeSymbolEquivalenceComparer(SymbolEquivalenceComparer symbolEquivalenceComparer) : IEqualityComparer<ITypeSymbol?>
11+
internal sealed class SignatureTypeSymbolEquivalenceComparer(SymbolEquivalenceComparer symbolEquivalenceComparer) : IEqualityComparer<ITypeSymbol?>
1212
{
1313
public bool Equals(ITypeSymbol? x, ITypeSymbol? y)
1414
=> this.Equals(x, y, null);
1515

1616
public bool Equals(ITypeSymbol? x, ITypeSymbol? y, Dictionary<INamedTypeSymbol, INamedTypeSymbol>? equivalentTypesWithDifferingAssemblies)
17-
=> symbolEquivalenceComparer.GetEquivalenceVisitor(compareMethodTypeParametersByIndex: true, symbolEquivalenceComparer._objectAndDynamicCompareEqually).AreEquivalent(x, y, equivalentTypesWithDifferingAssemblies);
17+
=> symbolEquivalenceComparer.GetEquivalenceVisitor(compareMethodTypeParametersByIndex: true).AreEquivalent(x, y, equivalentTypesWithDifferingAssemblies);
1818

1919
public int GetHashCode(ITypeSymbol? x)
20-
=> symbolEquivalenceComparer.GetGetHashCodeVisitor(compareMethodTypeParametersByIndex: true, symbolEquivalenceComparer._objectAndDynamicCompareEqually).GetHashCode(x, currentHash: 0);
20+
=> symbolEquivalenceComparer.GetGetHashCodeVisitor(compareMethodTypeParametersByIndex: true).GetHashCode(x, currentHash: 0);
2121
}
2222
}

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.cs

+12-20
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,18 @@ public SymbolEquivalenceComparer(
7373
using var equivalenceVisitors = TemporaryArray<EquivalenceVisitor>.Empty;
7474
using var getHashCodeVisitors = TemporaryArray<GetHashCodeVisitor>.Empty;
7575

76-
AddVisitors(compareMethodTypeParametersByIndex: true, objectAndDynamicCompareEqually: true);
77-
AddVisitors(compareMethodTypeParametersByIndex: true, objectAndDynamicCompareEqually: false);
78-
AddVisitors(compareMethodTypeParametersByIndex: false, objectAndDynamicCompareEqually: true);
79-
AddVisitors(compareMethodTypeParametersByIndex: false, objectAndDynamicCompareEqually: false);
76+
AddVisitors(compareMethodTypeParametersByIndex: true);
77+
AddVisitors(compareMethodTypeParametersByIndex: false);
8078

8179
_equivalenceVisitors = equivalenceVisitors.ToImmutableAndClear();
8280
_getHashCodeVisitors = getHashCodeVisitors.ToImmutableAndClear();
8381

8482
return;
8583

86-
void AddVisitors(bool compareMethodTypeParametersByIndex, bool objectAndDynamicCompareEqually)
84+
void AddVisitors(bool compareMethodTypeParametersByIndex)
8785
{
88-
equivalenceVisitors.Add(new(this, compareMethodTypeParametersByIndex, objectAndDynamicCompareEqually));
89-
getHashCodeVisitors.Add(new(this, compareMethodTypeParametersByIndex, objectAndDynamicCompareEqually));
86+
equivalenceVisitors.Add(new(this, compareMethodTypeParametersByIndex));
87+
getHashCodeVisitors.Add(new(this, compareMethodTypeParametersByIndex));
9088
}
9189
}
9290

@@ -107,27 +105,21 @@ public static SymbolEquivalenceComparer Create(
107105
// here. So, instead, when asking if parameters are equal, we pass an appropriate flag so
108106
// that method type parameters are just compared by index and nothing else.
109107
private EquivalenceVisitor GetEquivalenceVisitor(
110-
bool compareMethodTypeParametersByIndex = false, bool objectAndDynamicCompareEqually = false)
108+
bool compareMethodTypeParametersByIndex = false)
111109
{
112-
var visitorIndex = GetVisitorIndex(compareMethodTypeParametersByIndex, objectAndDynamicCompareEqually);
110+
var visitorIndex = GetVisitorIndex(compareMethodTypeParametersByIndex);
113111
return _equivalenceVisitors[visitorIndex];
114112
}
115113

116114
private GetHashCodeVisitor GetGetHashCodeVisitor(
117-
bool compareMethodTypeParametersByIndex, bool objectAndDynamicCompareEqually)
115+
bool compareMethodTypeParametersByIndex)
118116
{
119-
var visitorIndex = GetVisitorIndex(compareMethodTypeParametersByIndex, objectAndDynamicCompareEqually);
117+
var visitorIndex = GetVisitorIndex(compareMethodTypeParametersByIndex);
120118
return _getHashCodeVisitors[visitorIndex];
121119
}
122120

123-
private static int GetVisitorIndex(bool compareMethodTypeParametersByIndex, bool objectAndDynamicCompareEqually)
124-
=> (compareMethodTypeParametersByIndex, objectAndDynamicCompareEqually) switch
125-
{
126-
(true, true) => 0,
127-
(true, false) => 1,
128-
(false, true) => 2,
129-
(false, false) => 3,
130-
};
121+
private static int GetVisitorIndex(bool compareMethodTypeParametersByIndex)
122+
=> compareMethodTypeParametersByIndex ? 0 : 1;
131123

132124
public bool ReturnTypeEquals(IMethodSymbol x, IMethodSymbol y, Dictionary<INamedTypeSymbol, INamedTypeSymbol>? equivalentTypesWithDifferingAssemblies = null)
133125
=> GetEquivalenceVisitor().ReturnTypesAreEquivalent(x, y, equivalentTypesWithDifferingAssemblies);
@@ -154,7 +146,7 @@ private bool EqualsCore(ISymbol? x, ISymbol? y, Dictionary<INamedTypeSymbol, INa
154146
=> GetEquivalenceVisitor().AreEquivalent(x, y, equivalentTypesWithDifferingAssemblies);
155147

156148
public int GetHashCode(ISymbol? x)
157-
=> GetGetHashCodeVisitor(compareMethodTypeParametersByIndex: false, objectAndDynamicCompareEqually: false).GetHashCode(x, currentHash: 0);
149+
=> GetGetHashCodeVisitor(compareMethodTypeParametersByIndex: false).GetHashCode(x, currentHash: 0);
158150

159151
private static ISymbol UnwrapAlias(ISymbol symbol)
160152
=> symbol.IsKind(SymbolKind.Alias, out IAliasSymbol? alias) ? alias.Target : symbol;

0 commit comments

Comments
 (0)