提交 5bafb169 编写于 作者: C CyrusNajmabadi

Use immutable arrays in more places.

上级 10db28d2
......@@ -67,23 +67,24 @@ public bool Equals(DependentProject other)
/// Key: DefinitionProject, which contains the assembly name and a flag indicating whether assembly is source or 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.
/// </summary>
private static readonly ConditionalWeakTable<Solution, ConcurrentDictionary<DefinitionProject, IEnumerable<DependentProject>>> s_dependentProjectsCache =
new ConditionalWeakTable<Solution, ConcurrentDictionary<DefinitionProject, IEnumerable<DependentProject>>>();
private static readonly ConditionalWeakTable<Solution, ConcurrentDictionary<DefinitionProject, ImmutableArray<DependentProject>>> s_dependentProjectsCache =
new ConditionalWeakTable<Solution, ConcurrentDictionary<DefinitionProject, ImmutableArray<DependentProject>>>();
/// <summary>
/// Used to create a new concurrent dependent projects map for a given assembly when needed.
/// </summary>
private static readonly ConditionalWeakTable<Solution, ConcurrentDictionary<DefinitionProject, IEnumerable<DependentProject>>>.CreateValueCallback s_createDependentProjectsMapCallback =
_ => new ConcurrentDictionary<DefinitionProject, IEnumerable<DependentProject>>(concurrencyLevel: 2, capacity: 20);
private static readonly ConditionalWeakTable<Solution, ConcurrentDictionary<DefinitionProject, ImmutableArray<DependentProject>>>.CreateValueCallback s_createDependentProjectsMapCallback =
_ => new ConcurrentDictionary<DefinitionProject, ImmutableArray<DependentProject>>(concurrencyLevel: 2, capacity: 20);
public static async Task<IEnumerable<Project>> GetDependentProjectsAsync(ISymbol symbol, Solution solution, IImmutableSet<Project> projects, CancellationToken cancellationToken)
public static async Task<ImmutableArray<Project>> GetDependentProjectsAsync(
ISymbol symbol, Solution solution, IImmutableSet<Project> projects, CancellationToken cancellationToken)
{
if (symbol.Kind == SymbolKind.Namespace)
{
// namespaces are visible in all projects.
if (projects != null)
{
return projects;
return projects.ToImmutableArray();
}
return GetAllProjects(solution);
......@@ -93,22 +94,18 @@ public static async Task<IEnumerable<Project>> GetDependentProjectsAsync(ISymbol
var dependentProjects = await GetDependentProjectsWorkerAsync(symbol, solution, cancellationToken).ConfigureAwait(false);
if (projects != null)
{
return dependentProjects.Where(projects.Contains);
return dependentProjects.WhereAsArray(projects.Contains);
}
return dependentProjects;
}
}
private static IEnumerable<Project> GetAllProjects(Solution solution)
{
return solution.Projects;
}
private static ImmutableArray<Project> GetAllProjects(Solution solution)
=> solution.Projects.ToImmutableArray();
private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<ProjectId> projectIds)
{
return projectIds.Select(id => solution.GetProject(id));
}
private static ImmutableArray<Project> GetProjects(Solution solution, ImmutableArray<ProjectId> projectIds)
=> projectIds.SelectAsArray(id => solution.GetProject(id));
/// <summary>
/// This method computes the dependent projects that need to be searched for references of the given <paramref name="symbol"/>.
......@@ -122,7 +119,7 @@ private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<P
/// 2) Filter the above computed dependent projects based on symbol visibility.
/// Dependent projects computed in stage (1) are cached to avoid recomputation.
/// </summary>
private static async Task<IEnumerable<Project>> GetDependentProjectsWorkerAsync(
private static async Task<ImmutableArray<Project>> GetDependentProjectsWorkerAsync(
this ISymbol symbol,
Solution solution,
CancellationToken cancellationToken)
......@@ -136,7 +133,7 @@ private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<P
if (containingAssembly == null)
{
// currently we don't support finding references for a symbol that doesn't have containing assembly symbol
return SpecializedCollections.EmptyEnumerable<Project>();
return ImmutableArray<Project>.Empty;
}
// Find the projects that reference this assembly.
......@@ -145,7 +142,7 @@ private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<P
cancellationToken.ThrowIfCancellationRequested();
// 1) Compute all the dependent projects (submission + non-submission) and their InternalsVisibleTo semantics to the definition project.
IEnumerable<DependentProject> dependentProjects;
ImmutableArray<DependentProject> dependentProjects;
var visibility = symbol.GetResultantVisibility();
if (visibility == SymbolVisibility.Private)
......@@ -155,7 +152,7 @@ private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<P
else
{
// We cache the dependent projects for non-private symbols, check in the cache first.
ConcurrentDictionary<DefinitionProject, IEnumerable<DependentProject>> dependentProjectsMap = s_dependentProjectsCache.GetValue(solution, s_createDependentProjectsMapCallback);
var dependentProjectsMap = s_dependentProjectsCache.GetValue(solution, s_createDependentProjectsMapCallback);
var key = new DefinitionProject(sourceProjectId: sourceProject?.Id, assemblyName: containingAssembly.Name.ToLower());
if (!dependentProjectsMap.TryGetValue(key, out dependentProjects))
......@@ -169,7 +166,7 @@ private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<P
return FilterDependentProjectsByVisibility(solution, dependentProjects, visibility);
}
private static async Task<IEnumerable<DependentProject>> GetDependentProjectsCoreAsync(
private static async Task<ImmutableArray<DependentProject>> GetDependentProjectsCoreAsync(
ISymbol symbol,
Solution solution,
Project sourceProject,
......@@ -197,12 +194,12 @@ private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<P
// is private, but further submissions can bind to them.
await AddSubmissionDependentProjectsAsync(solution, sourceProject, dependentProjects, cancellationToken).ConfigureAwait(false);
return dependentProjects;
return dependentProjects.ToImmutableArray();
}
private static IEnumerable<Project> FilterDependentProjectsByVisibility(
private static ImmutableArray<Project> FilterDependentProjectsByVisibility(
Solution solution,
IEnumerable<DependentProject> dependentProjects,
ImmutableArray<DependentProject> dependentProjects,
SymbolVisibility visibility)
{
// Filter out dependent projects based on symbol visibility.
......@@ -210,11 +207,11 @@ private static IEnumerable<Project> GetProjects(Solution solution, IEnumerable<P
{
case SymbolVisibility.Internal:
// Retain dependent projects that have internals access.
dependentProjects = dependentProjects.Where(dp => dp.HasInternalsAccess);
dependentProjects = dependentProjects.WhereAsArray(dp => dp.HasInternalsAccess);
break;
}
var projectIds = dependentProjects.Select(dp => dp.ProjectId);
var projectIds = dependentProjects.SelectAsArray(dp => dp.ProjectId);
return GetProjects(solution, projectIds);
}
......
......@@ -58,12 +58,11 @@ public Task<ImmutableArray<Document>> DetermineDocumentsToSearchAsync(ISymbol sy
return SpecializedTasks.EmptyImmutableArray<SymbolAndProjectId>();
}
protected virtual async Task<ImmutableArray<Project>> DetermineProjectsToSearchAsync(
protected virtual Task<ImmutableArray<Project>> DetermineProjectsToSearchAsync(
TSymbol symbol, Solution solution, IImmutableSet<Project> projects, CancellationToken cancellationToken)
{
var result = await DependentProjectsFinder.GetDependentProjectsAsync(
symbol, solution, projects, cancellationToken).ConfigureAwait(false);
return result.ToImmutableArray();
return DependentProjectsFinder.GetDependentProjectsAsync(
symbol, solution, projects, cancellationToken);
}
protected virtual Task<ImmutableArray<SymbolAndProjectId>> DetermineCascadedSymbolsAsync(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册