diff --git a/src/EditorFeatures/CSharpTest/SymbolId/SymbolKeyCompilationsTests.cs b/src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyCompilationsTests.cs similarity index 100% rename from src/EditorFeatures/CSharpTest/SymbolId/SymbolKeyCompilationsTests.cs rename to src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyCompilationsTests.cs diff --git a/src/EditorFeatures/CSharpTest/SymbolId/SymbolKeyMetadataVsSourceTests.cs b/src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyMetadataVsSourceTests.cs similarity index 100% rename from src/EditorFeatures/CSharpTest/SymbolId/SymbolKeyMetadataVsSourceTests.cs rename to src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyMetadataVsSourceTests.cs diff --git a/src/EditorFeatures/CSharpTest/SymbolId/SymbolKeyTestBase.cs b/src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyTestBase.cs similarity index 100% rename from src/EditorFeatures/CSharpTest/SymbolId/SymbolKeyTestBase.cs rename to src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyTestBase.cs diff --git a/src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyTests.cs b/src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..9e1d36a8548c0a19578d8e622a02053d3dd58ae2 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/SymbolKey/SymbolKeyTests.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SymbolId +{ + [UseExportProvider] + public class SymbolKeyTests + { + [Fact, WorkItem(45437, "https://github.com/dotnet/roslyn/issues/45437")] + public async Task TestGenericsAndNullability() + { + var typeSource = @" +#nullable enable + + public sealed class ConditionalWeakTableTest /*: IEnumerable>, IEnumerable*/ + where TKey : class + where TValue : class + { + public ConditionalWeakTable() { } + public void Add(TKey key, TValue value) { } + public void AddOrUpdate(TKey key, TValue value) { } + public void Clear() { } + public TValue GetOrCreateValue(TKey key) => default; + public TValue GetValue(TKey key, ConditionalWeakTableTest.CreateValueCallback createValueCallback) => default; + public bool Remove(TKey key) => false; + + public delegate TValue CreateValueCallback(TKey key); + }".Replace("<", "<").Replace(">", ">"); + + var workspaceXml = @$" + + + + +{typeSource} + + + +"; + using var workspace = TestWorkspace.Create(workspaceXml); + + var solution = workspace.CurrentSolution; + var project = solution.Projects.Single(); + + var compilation = await project.GetCompilationAsync(); + + var type = compilation.GetTypeByMetadataName("ConditionalWeakTableTest`2"); + var method = type.GetMembers("GetValue").OfType().Single(); + var callbackParamater = method.Parameters[1]; + var parameterType = callbackParamater.Type; + Assert.Equal("global::ConditionalWeakTableTest.CreateValueCallback!", parameterType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNotNullableReferenceTypeModifier))); + + var symbolKey = SymbolKey.Create(method); + var resolved = symbolKey.Resolve(compilation).Symbol; + + Assert.Equal(method, resolved); + } + } +} diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs index 6284b5d8235b2d5ff49874754a14fec440d267fb..62da434bb1c310a73d45afac5d814991e0e4b067 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs @@ -344,8 +344,7 @@ private bool HandleNamedTypesWorker(INamedTypeSymbol x, INamedTypeSymbol y, Dict { Debug.Assert(GetTypeKind(x) == GetTypeKind(y)); - if (x.IsDefinition != y.IsDefinition || - IsConstructedFromSelf(x) != IsConstructedFromSelf(y) || + if (IsConstructedFromSelf(x) != IsConstructedFromSelf(y) || x.Arity != y.Arity || x.Name != y.Name || x.IsAnonymousType != y.IsAnonymousType ||