提交 7f41dad5 编写于 作者: C CyrusNajmabadi

Revert "Cache symbol finding results to help callers who are making many calls into it."

This reverts commit 95a24448.
上级 95a24448
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Roslyn.Utilities;
......@@ -18,8 +15,6 @@ namespace Microsoft.CodeAnalysis.FindSymbols
{
using SymbolAndProjectIdSet = HashSet<SymbolAndProjectId<INamedTypeSymbol>>;
using RelatedTypeCache = ConditionalWeakTable<Solution, ConcurrentDictionary<INamedTypeSymbol, AsyncLazy<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>>>>;
/// <summary>
/// Provides helper methods for finding dependent types (derivations, implementations,
/// etc.) across a solution. The results found are returned in pairs of <see cref="ISymbol"/>s
......@@ -43,44 +38,17 @@ internal static class DependentTypeFinder
private static readonly ObjectPool<SymbolAndProjectIdSet> s_setPool = new ObjectPool<SymbolAndProjectIdSet>(
() => new SymbolAndProjectIdSet(SymbolAndProjectIdComparer<INamedTypeSymbol>.SymbolEquivalenceInstance));
// Caches from a types to their related types (in the context of a specific solution).
// Kept as a cache so that clients who make many calls into us won't end up computing
// the same data over and over again. Will be let go the moment the solution they're
// based off of is no longer alive.
private static readonly RelatedTypeCache s_typeToImmediatelyDerivedClassesMap = new RelatedTypeCache();
private static readonly RelatedTypeCache s_typeToTransitivelyDerivedClassesMap = new RelatedTypeCache();
private static readonly RelatedTypeCache s_typeToTransitivelyImplementingTypesMap = new RelatedTypeCache();
private static readonly RelatedTypeCache s_typeToImmediatelyDerivedAndImplementingTypesMap = new RelatedTypeCache();
public static async Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindTypesFromCacheOrComputeAsync(
INamedTypeSymbol type,
Solution solution,
RelatedTypeCache cache,
Func<CancellationToken, Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>>> findAsync,
CancellationToken cancellationToken)
{
var dictionary = cache.GetOrCreateValue(solution);
var lazy = dictionary.GetOrAdd(type, new AsyncLazy<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>>(
asynchronousComputeFunction: findAsync, cacheResult: true));
return await lazy.GetValueAsync(cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Used for implementing the Inherited-By relation for progression.
/// </summary>
public static Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindImmediatelyDerivedClassesAsync(
internal static Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindImmediatelyDerivedClassesAsync(
INamedTypeSymbol type,
Solution solution,
CancellationToken cancellationToken)
{
return FindTypesFromCacheOrComputeAsync(
type, solution, s_typeToImmediatelyDerivedClassesMap,
c => FindDerivedClassesAsync(
SymbolAndProjectId.Create(type, projectId: null), solution, projects: null,
transitive: false, cancellationToken: c),
cancellationToken);
return FindDerivedClassesAsync(
SymbolAndProjectId.Create(type, projectId: null), solution, projects: null,
transitive: false, cancellationToken: cancellationToken);
}
/// <summary>
......@@ -92,12 +60,9 @@ internal static class DependentTypeFinder
IImmutableSet<Project> projects,
CancellationToken cancellationToken)
{
return FindTypesFromCacheOrComputeAsync(
type, solution, s_typeToTransitivelyDerivedClassesMap,
c => FindDerivedClassesAsync(
SymbolAndProjectId.Create(type, projectId: null), solution, projects,
transitive: true, cancellationToken: c),
cancellationToken);
return FindDerivedClassesAsync(
SymbolAndProjectId.Create(type, projectId: null), solution, projects,
transitive: true, cancellationToken: cancellationToken);
}
private static Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindDerivedClassesAsync(
......@@ -130,19 +95,7 @@ internal static class DependentTypeFinder
/// Implementation of <see cref="SymbolFinder.FindImplementationsAsync(SymbolAndProjectId, Solution, IImmutableSet{Project}, CancellationToken)"/> for
/// <see cref="INamedTypeSymbol"/>s
/// </summary>
public static Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindTransitivelyImplementingTypesAsync(
INamedTypeSymbol type,
Solution solution,
IImmutableSet<Project> projects,
CancellationToken cancellationToken)
{
return FindTypesFromCacheOrComputeAsync(
type, solution, s_typeToTransitivelyImplementingTypesMap,
c => FindTransitivelyImplementingTypesWorkerAsync(type, solution, projects, c),
cancellationToken);
}
private static async Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindTransitivelyImplementingTypesWorkerAsync(
public static async Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindTransitivelyImplementingTypesAsync(
INamedTypeSymbol type,
Solution solution,
IImmutableSet<Project> projects,
......@@ -160,17 +113,14 @@ internal static class DependentTypeFinder
/// <summary>
/// Used for implementing the Inherited-By relation for progression.
/// </summary>
public static Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindImmediatelyDerivedAndImplementingTypesAsync(
internal static Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindImmediatelyDerivedAndImplementingTypesAsync(
INamedTypeSymbol type,
Solution solution,
CancellationToken cancellationToken)
{
return FindTypesFromCacheOrComputeAsync(
type, solution, s_typeToImmediatelyDerivedAndImplementingTypesMap,
c => FindDerivedAndImplementingTypesAsync(
SymbolAndProjectId.Create(type, projectId: null), solution, projects: null,
transitive: false, cancellationToken: c),
cancellationToken);
return FindDerivedAndImplementingTypesAsync(
SymbolAndProjectId.Create(type, projectId: null), solution, projects: null,
transitive: false, cancellationToken: cancellationToken);
}
private static Task<ImmutableArray<SymbolAndProjectId<INamedTypeSymbol>>> FindDerivedAndImplementingTypesAsync(
......@@ -603,8 +553,7 @@ internal static class DependentTypeFinder
var typesToSearchFor = CreateSymbolAndProjectIdSet();
typesToSearchFor.AddAll(sourceAndMetadataTypes);
var caseSensitive = project.LanguageServices.GetService<ISyntaxFactsService>().IsCaseSensitive;
var inheritanceQuery = new InheritanceQuery(sourceAndMetadataTypes, caseSensitive);
var inheritanceQuery = new InheritanceQuery(sourceAndMetadataTypes);
// As long as there are new types to search for, keep looping.
while (typesToSearchFor.Count > 0)
......@@ -613,10 +562,10 @@ internal static class DependentTypeFinder
inheritanceQuery.TypeNames.AddRange(typesToSearchFor.Select(c => c.Symbol.Name));
// Search all the documents of this project in parallel.
var tasks = project.Documents.Select(d => Task.Run(() => FindImmediatelyInheritingTypesInDocumentAsync(
var tasks = project.Documents.Select(d => FindImmediatelyInheritingTypesInDocumentAsync(
d, typesToSearchFor, inheritanceQuery,
cachedModels, cachedInfos,
sourceTypeImmediatelyMatches, cancellationToken), cancellationToken)).ToArray();
sourceTypeImmediatelyMatches, cancellationToken)).ToArray();
await Task.WhenAll(tasks).ConfigureAwait(false);
......@@ -771,13 +720,13 @@ private class InheritanceQuery
public readonly HashSet<string> TypeNames;
public InheritanceQuery(SymbolAndProjectIdSet sourceAndMetadataTypes, bool caseSensitive)
public InheritanceQuery(SymbolAndProjectIdSet sourceAndMetadataTypes)
{
DerivesFromSystemObject = sourceAndMetadataTypes.Any(t => t.Symbol.SpecialType == SpecialType.System_Object);
DerivesFromSystemValueType = sourceAndMetadataTypes.Any(t => t.Symbol.SpecialType == SpecialType.System_ValueType);
DerivesFromSystemEnum = sourceAndMetadataTypes.Any(t => t.Symbol.SpecialType == SpecialType.System_Enum);
DerivesFromSystemMulticastDelegate = sourceAndMetadataTypes.Any(t => t.Symbol.SpecialType == SpecialType.System_MulticastDelegate);
TypeNames = caseSensitive ? new HashSet<string>() : new HashSet<string>(StringComparer.OrdinalIgnoreCase);
TypeNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册