提交 34a820cd 编写于 作者: C Cyrus Najmabadi

Limit cascading when finding the set of members to update when switching member to be explicit.

上级 f94a0963
......@@ -4,7 +4,6 @@
#nullable enable
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
......@@ -49,11 +48,18 @@ protected override bool CheckMemberCanBeConverted(ISymbol member)
{
var solution = project.Solution;
// We don't need to cascade in this search, we're only explicitly looking for direct
// calls to our instance member (and not anyone else already calling through the
// interface already).
//
// This can save a lot of extra time spent finding callers, especially for methods with
// high fan-out (like IDisposable.Dispose()).
var findRefsOptions = FindReferencesSearchOptions.Default.WithCascade(false);
var references = await SymbolFinder.FindReferencesAsync(
new SymbolAndProjectId(implMember, project.Id),
solution, cancellationToken).ConfigureAwait(false);
solution, findRefsOptions, cancellationToken).ConfigureAwait(false);
var implReferences = references.FirstOrDefault(r => implMember.Equals(r.Definition));
var implReferences = references.FirstOrDefault();
if (implReferences == null)
return;
......
// 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.
namespace Microsoft.CodeAnalysis.FindSymbols
{
internal class FindReferencesOptions
{
public static readonly FindReferencesOptions Default = new FindReferencesOptions(
cascade: true);
/// <summary>
/// Whether or not we should automatically cascade to members when doing a find-references
/// search. Default to <see langword="true"/>.
/// </summary>
public readonly bool Cascade;
public FindReferencesOptions(bool cascade)
{
Cascade = cascade;
}
}
}
......@@ -2,17 +2,16 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using Microsoft.CodeAnalysis.FindSymbols.Finders;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.FindSymbols
{
internal class FindReferencesSearchOptions
{
public static readonly FindReferencesSearchOptions Default =
new FindReferencesSearchOptions(associatePropertyReferencesWithSpecificAccessor: false);
new FindReferencesSearchOptions(
associatePropertyReferencesWithSpecificAccessor: false,
cascade: true);
/// <summary>
/// When searching for property, associate specific references we find to the relevant
......@@ -28,17 +27,25 @@ internal class FindReferencesSearchOptions
/// </summary>
public bool AssociatePropertyReferencesWithSpecificAccessor { get; }
/// <summary>
/// Whether or not we should cascade from the original search symbol to new symbols as we're
/// doing the find-references search.
/// </summary>
public bool Cascade { get; }
public FindReferencesSearchOptions(
bool associatePropertyReferencesWithSpecificAccessor)
bool associatePropertyReferencesWithSpecificAccessor,
bool cascade)
{
AssociatePropertyReferencesWithSpecificAccessor = associatePropertyReferencesWithSpecificAccessor;
Cascade = cascade;
}
public FindReferencesSearchOptions WithAssociatePropertyReferencesWithSpecificAccessor(
bool associatePropertyReferencesWithSpecificAccessor)
{
return new FindReferencesSearchOptions(associatePropertyReferencesWithSpecificAccessor);
}
public FindReferencesSearchOptions WithAssociatePropertyReferencesWithSpecificAccessor(bool associatePropertyReferencesWithSpecificAccessor)
=> new FindReferencesSearchOptions(associatePropertyReferencesWithSpecificAccessor, Cascade);
public FindReferencesSearchOptions WithCascade(bool cascade)
=> new FindReferencesSearchOptions(AssociatePropertyReferencesWithSpecificAccessor, cascade);
/// <summary>
/// For IDE features, if the user starts searching on an accessor, then we want to give
......@@ -46,8 +53,6 @@ internal class FindReferencesSearchOptions
/// then associate everything with the property.
/// </summary>
public static FindReferencesSearchOptions GetFeatureOptionsForStartingSymbol(ISymbol symbol)
=> symbol.IsPropertyAccessor()
? new FindReferencesSearchOptions(associatePropertyReferencesWithSpecificAccessor: true)
: FindReferencesSearchOptions.Default;
=> Default.WithAssociatePropertyReferencesWithSpecificAccessor(symbol.IsPropertyAccessor());
}
}
......@@ -825,12 +825,15 @@ public override Task<ImmutableArray<Project>> DetermineProjectsToSearchAsync(ISy
SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet<Project> projects,
FindReferencesSearchOptions options, CancellationToken cancellationToken)
{
var symbol = symbolAndProjectId.Symbol;
if (symbol is TSymbol typedSymbol && CanFind(typedSymbol))
if (options.Cascade)
{
return DetermineCascadedSymbolsAsync(
symbolAndProjectId.WithSymbol(typedSymbol),
solution, projects, options, cancellationToken);
var symbol = symbolAndProjectId.Symbol;
if (symbol is TSymbol typedSymbol && CanFind(typedSymbol))
{
return DetermineCascadedSymbolsAsync(
symbolAndProjectId.WithSymbol(typedSymbol),
solution, projects, options, cancellationToken);
}
}
return SpecializedTasks.EmptyImmutableArray<SymbolAndProjectId>();
......
......@@ -30,17 +30,19 @@ public static partial class SymbolFinder
return FindReferencesAsync(new SymbolAndProjectId(symbol, projectId: null), solution, cancellationToken);
}
internal static Task<IEnumerable<ReferencedSymbol>> FindReferencesAsync(SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken)
=> FindReferencesAsync(symbolAndProjectId, solution, FindReferencesSearchOptions.Default, cancellationToken);
internal static async Task<IEnumerable<ReferencedSymbol>> FindReferencesAsync(
SymbolAndProjectId symbolAndProjectId,
Solution solution,
CancellationToken cancellationToken = default)
FindReferencesSearchOptions options,
CancellationToken cancellationToken)
{
var progressCollector = new StreamingProgressCollector(StreamingFindReferencesProgress.Instance);
await FindReferencesAsync(
symbolAndProjectId,
solution, progress: progressCollector, documents: null,
options: FindReferencesSearchOptions.Default,
cancellationToken: cancellationToken).ConfigureAwait(false);
symbolAndProjectId, solution, progressCollector,
documents: null, options, cancellationToken).ConfigureAwait(false);
return progressCollector.GetReferencedSymbols();
}
......
......@@ -19,18 +19,22 @@ namespace Microsoft.CodeAnalysis.Remote
internal class SerializableFindReferencesSearchOptions
{
public bool AssociatePropertyReferencesWithSpecificAccessor;
public bool Cascade;
public static SerializableFindReferencesSearchOptions Dehydrate(FindReferencesSearchOptions options)
{
return new SerializableFindReferencesSearchOptions
{
AssociatePropertyReferencesWithSpecificAccessor = options.AssociatePropertyReferencesWithSpecificAccessor
AssociatePropertyReferencesWithSpecificAccessor = options.AssociatePropertyReferencesWithSpecificAccessor,
Cascade = options.Cascade,
};
}
public FindReferencesSearchOptions Rehydrate()
{
return new FindReferencesSearchOptions(AssociatePropertyReferencesWithSpecificAccessor);
return new FindReferencesSearchOptions(
associatePropertyReferencesWithSpecificAccessor: AssociatePropertyReferencesWithSpecificAccessor,
cascade: Cascade);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册