diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjects/DefinitionProject.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjects/DefinitionProject.cs
deleted file mode 100644
index 086ecb38d85cfd5d5c4f6d77932bb2255b7caa4b..0000000000000000000000000000000000000000
--- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjects/DefinitionProject.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.
-
-#nullable enable
-
-using System;
-using System.Collections.Generic;
-using Roslyn.Utilities;
-
-namespace Microsoft.CodeAnalysis.FindSymbols.DependentProjects
-{
- ///
- /// The name of the assembly, and optionally also the project, that a symbol came from. Used in the to quickly find which set of projects in a solution should searched when
- /// looking at symbols from that same location.
- ///
- internal readonly struct DefinitionProject : IEquatable
- {
- private readonly ProjectId? _sourceProjectId;
- private readonly string _assemblyName;
-
- public DefinitionProject(ProjectId? sourceProjectId, string assemblyName)
- {
- _sourceProjectId = sourceProjectId;
- _assemblyName = assemblyName;
- }
-
- public override bool Equals(object? obj)
- => obj is DefinitionProject project && Equals(project);
-
- public bool Equals(DefinitionProject other)
- => EqualityComparer.Default.Equals(_sourceProjectId, other._sourceProjectId) &&
- _assemblyName == other._assemblyName;
-
- public override int GetHashCode()
- => Hash.Combine(_sourceProjectId, _assemblyName.GetHashCode());
- }
-}
diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjects/DependentProject.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjects/DependentProject.cs
deleted file mode 100644
index 8c98d3f3f0d4050a13c8838edbfd849df673001f..0000000000000000000000000000000000000000
--- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjects/DependentProject.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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.
-
-#nullable enable
-
-using System;
-using Roslyn.Utilities;
-
-namespace Microsoft.CodeAnalysis.FindSymbols.DependentProjects
-{
- ///
- /// Represents a project that depends on some assembly, and if that project can see the internal symbols of that
- /// assembly or not.
- ///
- internal readonly struct DependentProject : IEquatable
- {
- public readonly ProjectId ProjectId;
- public readonly bool HasInternalsAccess;
-
- public DependentProject(ProjectId dependentProjectId, bool hasInternalsAccess)
- {
- this.ProjectId = dependentProjectId;
- this.HasInternalsAccess = hasInternalsAccess;
- }
-
- public override bool Equals(object? obj)
- => obj is DependentProject project && this.Equals(project);
-
- public override int GetHashCode()
- => Hash.Combine(HasInternalsAccess, ProjectId.GetHashCode());
-
- public bool Equals(DependentProject other)
- => HasInternalsAccess == other.HasInternalsAccess && ProjectId.Equals(other.ProjectId);
- }
-}
diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs
index 89b2336a7ae647fd10c66a42490a6d575d1ab827..917c5dc1aa103a54ef430cc32f3ee91390a7270d 100644
--- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs
+++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs
@@ -5,7 +5,6 @@
#nullable enable
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
@@ -13,29 +12,17 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.FindSymbols.DependentProjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.FindSymbols
{
- using DependentProjectMap = ConcurrentDictionary>>;
-
///
/// Provides helper methods for finding dependent projects across a solution that a given symbol can be referenced within.
///
internal static partial class DependentProjectsFinder
{
- ///
- /// Dependent projects cache.
- /// For a given solution, maps from an assembly (source-project or metadata-assembly) to the set of projects referencing it.
- /// Key: DefinitionProject, which contains the project-id for a source-project-assembly, or assembly-name for a metadata-assembly.
- /// Value: List of DependentProjects, where each DependentProject contains a dependent project ID and a flag indicating whether the dependent project has internals access to definition project.
- ///
- private static readonly ConditionalWeakTable s_dependentProjectsCache =
- new ConditionalWeakTable();
-
public static async Task> GetDependentProjectsAsync(
Solution solution, ISymbol symbol, IImmutableSet? projects, CancellationToken cancellationToken)
{
@@ -79,32 +66,17 @@ internal static partial class DependentProjectsFinder
return ImmutableArray.Empty;
// 1) Compute all the dependent projects (submission + non-submission) and their InternalsVisibleTo semantics to the definition project.
-
- var visibility = symbol.GetResultantVisibility();
- if (visibility == SymbolVisibility.Private)
- {
- // For private symbols, we only need the current project (and related submissions). No need to cache
- // that, just simply compute and return the result.
- return GetProjects(solution, await ComputeDependentProjectsAsync(solution, symbolOrigination, visibility, cancellationToken).ConfigureAwait(false));
- }
-
- // Otherwise, for non-private symbols, we cache the dependent projects for non-private symbols to speed up
- // future calls.
- var dependentProjectsMap = s_dependentProjectsCache.GetValue(solution, _ => new DependentProjectMap());
-
- var asyncLazy = dependentProjectsMap.GetOrAdd(
- new DefinitionProject(symbolOrigination.sourceProject?.Id, symbolOrigination.assembly.Name.ToLower()),
- _ => AsyncLazy.Create(c => ComputeDependentProjectsAsync(solution, symbolOrigination, visibility, c), cacheResult: true));
- var dependentProjects = await asyncLazy.GetValueAsync(cancellationToken).ConfigureAwait(false);
+ var symbolVisibility = symbol.GetResultantVisibility();
+ var dependentProjects = await ComputeDependentProjectsAsync(
+ solution, symbolOrigination, symbolVisibility, cancellationToken).ConfigureAwait(false);
// 2) Filter the above computed dependent projects based on symbol visibility.
- return GetProjects(solution, visibility == SymbolVisibility.Internal
- ? dependentProjects.WhereAsArray(dp => dp.HasInternalsAccess)
- : dependentProjects);
- }
+ var filteredProjects = symbolVisibility == SymbolVisibility.Internal
+ ? dependentProjects.WhereAsArray(dp => dp.hasInternalsAccess)
+ : dependentProjects;
- private static ImmutableArray GetProjects(Solution solution, ImmutableArray dependentProjects)
- => dependentProjects.SelectAsArray(dp => solution.GetRequiredProject(dp.ProjectId));
+ return filteredProjects.SelectAsArray(t => t.project);
+ }
///
/// Returns a pair of data bout where originates from. It's GetProjects(Solution solution, ImmutableA
return assembly == null ? default : (assembly, solution.GetProject(assembly, cancellationToken));
}
- private static async Task> ComputeDependentProjectsAsync(
+ private static async Task> ComputeDependentProjectsAsync(
Solution solution,
(IAssemblySymbol assembly, Project? sourceProject) symbolOrigination,
SymbolVisibility visibility,
@@ -126,12 +98,12 @@ private static ImmutableArray GetProjects(Solution solution, ImmutableA
{
cancellationToken.ThrowIfCancellationRequested();
- var dependentProjects = new HashSet();
+ var dependentProjects = new HashSet<(Project, bool hasInternalsAccess)>();
// If a symbol was defined in source, then it is always visible to the project it
// was defined in.
if (symbolOrigination.sourceProject != null)
- dependentProjects.Add(new DependentProject(symbolOrigination.sourceProject.Id, hasInternalsAccess: true));
+ dependentProjects.Add((symbolOrigination.sourceProject, hasInternalsAccess: true));
// If it's not private, then we need to find possible references.
if (visibility != SymbolVisibility.Private)
@@ -145,7 +117,7 @@ private static ImmutableArray GetProjects(Solution solution, ImmutableA
}
private static async Task AddSubmissionDependentProjectsAsync(
- Solution solution, Project? sourceProject, HashSet dependentProjects, CancellationToken cancellationToken)
+ Solution solution, Project? sourceProject, HashSet<(Project project, bool hasInternalsAccess)> dependentProjects, CancellationToken cancellationToken)
{
if (sourceProject?.IsSubmission != true)
return;
@@ -187,7 +159,7 @@ private static ImmutableArray GetProjects(Solution solution, ImmutableA
// and 2, even though 2 doesn't have a direct reference to 1. Hence we need to take
// our current set of projects and find the transitive closure over backwards
// submission previous references.
- var projectIdsToProcess = new Stack(dependentProjects.Select(dp => dp.ProjectId));
+ var projectIdsToProcess = new Stack(dependentProjects.Select(dp => dp.project.Id));
while (projectIdsToProcess.Count > 0)
{
@@ -197,9 +169,9 @@ private static ImmutableArray GetProjects(Solution solution, ImmutableA
{
foreach (var pId in submissionIds)
{
- if (!dependentProjects.Any(dp => dp.ProjectId == pId))
+ if (!dependentProjects.Any(dp => dp.project.Id == pId))
{
- dependentProjects.Add(new DependentProject(pId, hasInternalsAccess: true));
+ dependentProjects.Add((solution.GetRequiredProject(pId), hasInternalsAccess: true));
projectIdsToProcess.Push(pId);
}
}
@@ -220,7 +192,7 @@ private static bool IsInternalsVisibleToAttribute(AttributeData attr)
private static void AddNonSubmissionDependentProjects(
Solution solution,
(IAssemblySymbol assembly, Project? sourceProject) symbolOrigination,
- HashSet dependentProjects,
+ HashSet<(Project project, bool hasInternalsAccess)> dependentProjects,
CancellationToken cancellationToken)
{
if (symbolOrigination.sourceProject?.IsSubmission == true)
@@ -239,8 +211,8 @@ private static bool IsInternalsVisibleToAttribute(AttributeData attr)
// Ok, we have some project that at least references this assembly. Add it to the result, keeping track
// if it can see internals or not as well.
internalsVisibleToSet ??= GetInternalsVisibleToSet(symbolOrigination.assembly);
- var internalsVisibleTo = internalsVisibleToSet.Contains(project.AssemblyName);
- dependentProjects.Add(new DependentProject(project.Id, internalsVisibleTo));
+ var hasInternalsAccess = internalsVisibleToSet.Contains(project.AssemblyName);
+ dependentProjects.Add((project, hasInternalsAccess));
}
}