Skip to content

Commit 8628943

Browse files
Compare symbols by metadata name when searching for eqivalent symbols in FAR engine (#78656)
2 parents 533fde8 + ff5f154 commit 8628943

File tree

4 files changed

+65
-23
lines changed

4 files changed

+65
-23
lines changed

src/EditorFeatures/CSharpTest/CodeLens/CSharpCodeLensTests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,54 @@ internal partial class Program
402402
""";
403403
await RunMethodReferenceTest(input);
404404
}
405+
406+
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64592")]
407+
public async Task TestFileScopedTypes()
408+
{
409+
const string input = """
410+
<Workspace>
411+
<Project Language="C#" CommonReferences="true" AssemblyName="Proj1">
412+
<Document FilePath="File1.cs"><![CDATA[
413+
namespace TestNamespace
414+
{
415+
{|1:file class C|}
416+
{
417+
public C ()
418+
{
419+
}
420+
421+
void M()
422+
{
423+
var t1 = new T();
424+
var t2 = new T();
425+
}
426+
}
427+
428+
{|2:file class T|}
429+
{
430+
}
431+
}]]>
432+
</Document>
433+
<Document FilePath="File2.cs"><![CDATA[
434+
namespace TestNamespace
435+
{
436+
{|0:file class C|}
437+
{
438+
void M()
439+
{
440+
var t1 = new T();
441+
var t2 = new T();
442+
}
443+
}
444+
445+
{|2:file class T|}
446+
{
447+
}
448+
}]]>
449+
</Document>
450+
</Project>
451+
</Workspace>
452+
""";
453+
await RunReferenceTest(input);
454+
}
405455
}

src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Helpers.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,6 @@ internal static bool OriginalSymbolsMatch(
3737
if (searchSymbol == null || symbolToMatch == null)
3838
return false;
3939

40-
// Avoid the expensive checks if we can fast path when the compiler just says these are equal. Also, for the
41-
// purposes of symbol finding nullability of symbols doesn't affect things, so just use the default
42-
// comparison.
43-
if (searchSymbol.Equals(symbolToMatch))
44-
return true;
45-
4640
if (OriginalSymbolsMatchCore(solution, searchSymbol, symbolToMatch))
4741
return true;
4842

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/SymbolEquivalenceComparer.EquivalenceVisitor.cs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using System.Diagnostics;
1111
using System.Linq;
1212
using Microsoft.CodeAnalysis.Shared.Extensions;
13-
using Roslyn.Utilities;
1413

1514
namespace Microsoft.CodeAnalysis.Shared.Utilities;
1615

@@ -153,15 +152,15 @@ private bool AssembliesAreEquivalent(IAssemblySymbol x, IAssemblySymbol y)
153152
private bool FieldsAreEquivalent(IFieldSymbol x, IFieldSymbol y, Dictionary<INamedTypeSymbol, INamedTypeSymbol>? equivalentTypesWithDifferingAssemblies)
154153
{
155154
return
156-
x.Name == y.Name &&
155+
x.MetadataName == y.MetadataName &&
157156
AreEquivalent(x.CustomModifiers, y.CustomModifiers, equivalentTypesWithDifferingAssemblies) &&
158157
AreEquivalent(x.ContainingSymbol, y.ContainingSymbol, equivalentTypesWithDifferingAssemblies);
159158
}
160159

161160
private static bool LabelsAreEquivalent(ILabelSymbol x, ILabelSymbol y)
162161
{
163162
return
164-
x.Name == y.Name &&
163+
x.MetadataName == y.MetadataName &&
165164
HaveSameLocation(x, y);
166165
}
167166

@@ -208,7 +207,7 @@ private bool MethodsAreEquivalent(IMethodSymbol x, IMethodSymbol y, Dictionary<I
208207
IsConstructedFromSelf(x) != IsConstructedFromSelf(y) ||
209208
x.Arity != y.Arity ||
210209
x.Parameters.Length != y.Parameters.Length ||
211-
x.Name != y.Name)
210+
x.MetadataName != y.MetadataName)
212211
{
213212
return false;
214213
}
@@ -277,7 +276,7 @@ private static bool HaveSameLocation(ISymbol x, ISymbol y)
277276
}
278277

279278
private bool ModulesAreEquivalent(IModuleSymbol x, IModuleSymbol y)
280-
=> AssembliesAreEquivalent(x.ContainingAssembly, y.ContainingAssembly) && x.Name == y.Name;
279+
=> AssembliesAreEquivalent(x.ContainingAssembly, y.ContainingAssembly) && x.MetadataName == y.MetadataName;
281280

282281
private bool NamedTypesAreEquivalent(INamedTypeSymbol x, INamedTypeSymbol y, Dictionary<INamedTypeSymbol, INamedTypeSymbol>? equivalentTypesWithDifferingAssemblies)
283282
{
@@ -357,8 +356,7 @@ private bool HandleNamedTypesWorker(INamedTypeSymbol x, INamedTypeSymbol y, Dict
357356
return true;
358357

359358
if (IsConstructedFromSelf(x) != IsConstructedFromSelf(y) ||
360-
x.Arity != y.Arity ||
361-
x.Name != y.Name ||
359+
x.MetadataName != y.MetadataName ||
362360
x.IsAnonymousType != y.IsAnonymousType ||
363361
x.IsUnboundGenericType != y.IsUnboundGenericType ||
364362
!NullableAnnotationsEquivalent(x, y))
@@ -375,12 +373,12 @@ x.ContainingSymbol is INamespaceSymbol xNamespace &&
375373
// For error types, we just ensure that the containing namespaces are equivalent up to the root.
376374
while (true)
377375
{
378-
if (xNamespace.Name != yNamespace.Name)
376+
if (xNamespace.MetadataName != yNamespace.MetadataName)
379377
return false;
380378

381379
// Error namespaces don't set the IsGlobalNamespace bit unfortunately. So we just do the
382380
// nominal check to see if we've actually hit the root.
383-
if (xNamespace.Name == "")
381+
if (xNamespace.MetadataName == "")
384382
break;
385383

386384
xNamespace = xNamespace.ContainingNamespace;
@@ -398,7 +396,7 @@ x.ContainingSymbol is INamespaceSymbol xNamespace &&
398396
if (equivalentTypesWithDifferingAssemblies != null &&
399397
x.ContainingType == null &&
400398
x.ContainingAssembly != null &&
401-
!AssemblyIdentityComparer.SimpleNameComparer.Equals(x.ContainingAssembly.Name, y.ContainingAssembly.Name) &&
399+
!AssemblyIdentityComparer.SimpleNameComparer.Equals(x.ContainingAssembly.MetadataName, y.ContainingAssembly.MetadataName) &&
402400
!equivalentTypesWithDifferingAssemblies.ContainsKey(x))
403401
{
404402
equivalentTypesWithDifferingAssemblies.Add(x, y);
@@ -434,7 +432,7 @@ private bool HandleTupleTypes(INamedTypeSymbol x, INamedTypeSymbol y, Dictionary
434432
{
435433
var xElement = xElements[i];
436434
var yElement = yElements[i];
437-
if (xElement.Name != yElement.Name)
435+
if (xElement.MetadataName != yElement.MetadataName)
438436
return false;
439437
}
440438
}
@@ -534,7 +532,7 @@ private bool HandleAnonymousTypes(INamedTypeSymbol x, INamedTypeSymbol y, Dictio
534532
var p1 = xMembersEnumerator.Current;
535533
var p2 = yMembersEnumerator.Current;
536534

537-
if (p1.Name != p2.Name ||
535+
if (p1.MetadataName != p2.MetadataName ||
538536
p1.IsReadOnly != p2.IsReadOnly ||
539537
!AreEquivalent(p1.Type, p2.Type, equivalentTypesWithDifferingAssemblies))
540538
{
@@ -549,7 +547,7 @@ private bool HandleAnonymousTypes(INamedTypeSymbol x, INamedTypeSymbol y, Dictio
549547
private bool NamespacesAreEquivalent(INamespaceSymbol x, INamespaceSymbol y, Dictionary<INamedTypeSymbol, INamedTypeSymbol>? equivalentTypesWithDifferingAssemblies)
550548
{
551549
if (x.IsGlobalNamespace != y.IsGlobalNamespace ||
552-
x.Name != y.Name)
550+
x.MetadataName != y.MetadataName)
553551
{
554552
return false;
555553
}
@@ -567,7 +565,7 @@ private bool ParametersAreEquivalent(IParameterSymbol x, IParameterSymbol y, Dic
567565
{
568566
return
569567
x.IsRefOrOut() == y.IsRefOrOut() &&
570-
x.Name == y.Name &&
568+
x.MetadataName == y.MetadataName &&
571569
AreEquivalent(x.CustomModifiers, y.CustomModifiers, equivalentTypesWithDifferingAssemblies) &&
572570
AreEquivalent(x.Type, y.Type, equivalentTypesWithDifferingAssemblies) &&
573571
AreEquivalent(x.ContainingSymbol, y.ContainingSymbol, equivalentTypesWithDifferingAssemblies);
@@ -610,7 +608,7 @@ private bool PropertiesAreEquivalent(IPropertySymbol x, IPropertySymbol y, Dicti
610608
private bool EventsAreEquivalent(IEventSymbol x, IEventSymbol y, Dictionary<INamedTypeSymbol, INamedTypeSymbol>? equivalentTypesWithDifferingAssemblies)
611609
{
612610
return
613-
x.Name == y.Name &&
611+
x.MetadataName == y.MetadataName &&
614612
IsPartialEventDefinitionPart(x) == IsPartialEventDefinitionPart(y) &&
615613
IsPartialEventImplementationPart(x) == IsPartialEventImplementationPart(y) &&
616614
AreEquivalent(x.ContainingSymbol, y.ContainingSymbol, equivalentTypesWithDifferingAssemblies);
@@ -660,6 +658,6 @@ private static bool RangeVariablesAreEquivalent(IRangeVariableSymbol x, IRangeVa
660658
=> HaveSameLocation(x, y);
661659

662660
private static bool PreprocessingSymbolsAreEquivalent(IPreprocessingSymbol x, IPreprocessingSymbol y)
663-
=> x.Name == y.Name;
661+
=> x.MetadataName == y.MetadataName;
664662
}
665663
}

src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/SymbolEquivalenceComparer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.Shared.Utilities;
2020
/// equivalent.
2121
/// <list type="number">
2222
/// <item>The kinds of the two symbols must match.</item>
23-
/// <item>The names of the two symbols must match.</item>
23+
/// <item>The metadata names of the two symbols must match.</item>
2424
/// <item>The arity of the two symbols must match.</item>
2525
/// <item>If the symbols are methods or parameterized properties, then the signatures of the two
2626
/// symbols must match.</item>

0 commit comments

Comments
 (0)