提交 a5d41834 编写于 作者: C CyrusNajmabadi

Reduce temporary array allocations while finding types.

上级 8f062669
......@@ -244,45 +244,63 @@ internal static class DependentTypeFinder
// This is only necessary if we started with a metadata type.
if (searchInMetadata)
{
var foundMetadataTypes = await FindAllMatchingMetadataTypesInProjectAsync(
currentMetadataTypes, project, metadataTypeMatches,
var foundMetadataTypes = CreateSymbolAndProjectIdSet();
try
{
await AddAllMatchingMetadataTypesInProjectAsync(
currentMetadataTypes, project, metadataTypeMatches,
foundMetadataTypes, cancellationToken).ConfigureAwait(false);
foreach (var foundTypeAndProjectId in foundMetadataTypes)
{
var foundType = foundTypeAndProjectId.Symbol;
Debug.Assert(foundType.Locations.Any(s_isInMetadata));
// Add to the result list.
result.Add(foundTypeAndProjectId);
if (transitive && shouldContinueSearching(foundType))
{
currentMetadataTypes.Add(foundTypeAndProjectId);
currentSourceAndMetadataTypes.Add(foundTypeAndProjectId);
}
}
}
finally
{
s_setPool.ClearAndFree(foundMetadataTypes);
}
}
// Now search the project and see what source types we can find.
var foundSourceTypes = CreateSymbolAndProjectIdSet();
try
{
await AddSourceTypesInProjectAsync(
currentSourceAndMetadataTypes, project,
sourceTypeImmediatelyMatches,
shouldContinueSearching,
transitive, foundSourceTypes,
cancellationToken).ConfigureAwait(false);
foreach (var foundTypeAndProjectId in foundMetadataTypes)
foreach (var foundTypeAndProjectId in foundSourceTypes)
{
var foundType = foundTypeAndProjectId.Symbol;
Debug.Assert(foundType.Locations.Any(s_isInMetadata));
Debug.Assert(foundType.Locations.All(s_isInSource));
// Add to the result list.
result.Add(foundTypeAndProjectId);
if (transitive && shouldContinueSearching(foundType))
{
currentMetadataTypes.Add(foundTypeAndProjectId);
currentSourceAndMetadataTypes.Add(foundTypeAndProjectId);
}
}
}
// Now search the project and see what source types we can find.
var foundSourceTypes = await FindSourceTypesInProjectAsync(
currentSourceAndMetadataTypes, project,
sourceTypeImmediatelyMatches,
shouldContinueSearching,
transitive, cancellationToken).ConfigureAwait(false);
foreach (var foundTypeAndProjectId in foundSourceTypes)
finally
{
var foundType = foundTypeAndProjectId.Symbol;
Debug.Assert(foundType.Locations.All(s_isInSource));
// Add to the result list.
result.Add(foundTypeAndProjectId);
if (transitive && shouldContinueSearching(foundType))
{
currentSourceAndMetadataTypes.Add(foundTypeAndProjectId);
}
s_setPool.ClearAndFree(foundSourceTypes);
}
}
......@@ -400,19 +418,19 @@ internal static class DependentTypeFinder
.ToList();
}
private static async Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindAllMatchingMetadataTypesInProjectAsync(
private static async Task AddAllMatchingMetadataTypesInProjectAsync(
SymbolAndProjectIdSet metadataTypes,
Project project,
Func<SymbolAndProjectIdSet, INamedTypeSymbol, bool> metadataTypeMatches,
SymbolAndProjectIdSet result,
CancellationToken cancellationToken)
{
if (metadataTypes.Count == 0)
{
return ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>.Empty;
return;
}
var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var result = CreateSymbolAndProjectIdSet();
// Seed the current set of types we're searching for with the types we were given.
var currentTypes = metadataTypes;
......@@ -435,8 +453,6 @@ internal static class DependentTypeFinder
// Now keep looping, using the set we found to spawn the next set of searches.
currentTypes = immediateDerivedTypes;
}
return ToImmutableAndFree(result);
}
private static async Task FindImmediateMatchingMetadataTypesInMetadataReferenceAsync(
......@@ -521,12 +537,13 @@ internal static class DependentTypeFinder
return false;
}
private static async Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindSourceTypesInProjectAsync(
private static async Task AddSourceTypesInProjectAsync(
SymbolAndProjectIdSet sourceAndMetadataTypes,
Project project,
Func<SymbolAndProjectIdSet, INamedTypeSymbol, bool> sourceTypeImmediatelyMatches,
Func<INamedTypeSymbol, bool> shouldContinueSearching,
bool transitive,
SymbolAndProjectIdSet finalResult,
CancellationToken cancellationToken)
{
// We're going to be sweeping over this project over and over until we reach a
......@@ -536,8 +553,6 @@ internal static class DependentTypeFinder
var cachedModels = new ConcurrentSet<SemanticModel>();
var cachedInfos = new ConcurrentSet<SyntaxTreeIndex>();
var finalResult = CreateSymbolAndProjectIdSet();
var typesToSearchFor = CreateSymbolAndProjectIdSet();
typesToSearchFor.AddAll(sourceAndMetadataTypes);
......@@ -581,8 +596,6 @@ internal static class DependentTypeFinder
}
}
}
return ToImmutableAndFree(finalResult);
}
private static bool ImmediatelyDerivesOrImplementsFrom(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册