From e54a8ea4b9a17299ac94942fd8251e336ebcdbcc Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Mon, 29 May 2017 16:41:18 -0700 Subject: [PATCH] Simplify metadata reference searching in Add-Import. --- .../AbstractAddImportCodeFixProvider.cs | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs index a8e0b7d2100..261af7177eb 100644 --- a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CodeFixes.AddImport { internal abstract partial class AbstractAddImportCodeFixProvider - : CodeFixProvider, IEqualityComparer<(ProjectId, PortableExecutableReference)> + : CodeFixProvider, IEqualityComparer where TSimpleNameSyntax : SyntaxNode { private const int MaxResults = 3; @@ -250,8 +250,8 @@ private static bool IsHostOrTestWorkspace(Project project) // Keep track of the references we've seen (so that we don't process them multiple times // across many sibling projects). Prepopulate it with our own metadata references since // we know we don't need to search in that. - var seenReferences = new HashSet<(ProjectId, PortableExecutableReference)>(comparer: this); - seenReferences.AddAll(project.MetadataReferences.OfType().Select(r => (project.Id, r))); + var seenReferences = new HashSet(comparer: this); + seenReferences.AddAll(project.MetadataReferences.OfType()); var newReferences = GetUnreferencedMetadataReferences(project, seenReferences); @@ -288,15 +288,30 @@ private static bool IsHostOrTestWorkspace(Project project) /// for the project we found the pe-reference in. /// private ImmutableArray<(ProjectId, PortableExecutableReference)> GetUnreferencedMetadataReferences( - Project project, HashSet<(ProjectId, PortableExecutableReference)> seenReferences) + Project project, HashSet seenReferences) { + var result = ArrayBuilder<(ProjectId, PortableExecutableReference)>.GetInstance(); + var solution = project.Solution; - return solution.Projects.Where(p => p != project) - .SelectMany(p => p.MetadataReferences.OfType().Select(pe => (p.Id, reference: pe))) - .Distinct(comparer: this) - .Where(t => !seenReferences.Contains(t)) - .Where(t => !IsInPackagesDirectory(t.Item2)) - .ToImmutableArray(); + foreach (var p in solution.Projects) + { + if (p == project) + { + continue; + } + + foreach (var reference in p.MetadataReferences) + { + if (reference is PortableExecutableReference peReference && + !IsInPackagesDirectory(peReference) && + seenReferences.Add(peReference)) + { + result.Add((p.Id, peReference)); + } + } + } + + return result.ToImmutableAndFree(); } private async Task WaitForTasksAsync( @@ -378,18 +393,11 @@ private Compilation CreateCompilation(Project project, PortableExecutableReferen } - bool IEqualityComparer<(ProjectId, PortableExecutableReference)>.Equals( - (ProjectId, PortableExecutableReference) x, (ProjectId, PortableExecutableReference) y) - { - return StringComparer.OrdinalIgnoreCase.Equals( - x.Item2.FilePath ?? x.Item2.Display, - y.Item2.FilePath ?? y.Item2.Display); - } + bool IEqualityComparer.Equals(PortableExecutableReference x, PortableExecutableReference y) + => StringComparer.OrdinalIgnoreCase.Equals(x.FilePath ?? x.Display, y.FilePath ?? y.Display); - int IEqualityComparer<(ProjectId, PortableExecutableReference)>.GetHashCode((ProjectId, PortableExecutableReference) obj) - { - return StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Item2.FilePath ?? obj.Item2.Display); - } + int IEqualityComparer.GetHashCode(PortableExecutableReference obj) + => StringComparer.OrdinalIgnoreCase.GetHashCode(obj.FilePath ?? obj.Display); private static HashSet GetViableUnreferencedProjects(Project project) { -- GitLab