Skip to content

Commit

Permalink
Merge pull request #43513 from CyrusNajmabadi/usagesCleanup
Browse files Browse the repository at this point in the history
Small pieces of find-usages cleanup.
  • Loading branch information
msftbot[bot] authored Apr 20, 2020
2 parents 37efffc + c2b342c commit c7c78a9
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 22 deletions.
23 changes: 9 additions & 14 deletions src/EditorFeatures/Core/FindUsages/FindUsagesHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,45 +62,40 @@ public static string GetDisplayName(ISymbol symbol)
var (symbol, project) = symbolAndProjectOpt.Value;
var symbolAndProjectId = new SymbolAndProjectId(symbol, project.Id);
return await FindSourceImplementationsAsync(
symbolAndProjectId, project.Solution, cancellationToken).ConfigureAwait(false);
project.Solution, symbolAndProjectId, cancellationToken).ConfigureAwait(false);
}

private static async Task<(Solution solution, SymbolAndProjectId symbolAndProjectId, ImmutableArray<SymbolAndProjectId> implementations, string message)?> FindSourceImplementationsAsync(
SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken)
Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken)
{
var builder = new HashSet<SymbolAndProjectId>(SymbolAndProjectIdComparer.SymbolEquivalenceInstance);

// Find the direct implementations first.
builder.AddRange(await FindSourceImplementationsWorkerAsync(
symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false));

// If we're in a linked file, try to find all the symbols this links to, and find all the implementations of
// each of those linked symbols. De-dupe the results so the user only gets unique results.
var linkedSymbols = await SymbolFinder.FindLinkedSymbolsAsync(
symbolAndProjectId.Symbol, solution, cancellationToken).ConfigureAwait(false);
solution, symbolAndProjectId, cancellationToken).ConfigureAwait(false);

foreach (var linkedSymbol in linkedSymbols)
{
builder.AddRange(await FindSourceImplementationsWorkerAsync(
linkedSymbol, solution, cancellationToken).ConfigureAwait((bool)false));
solution, linkedSymbol, cancellationToken).ConfigureAwait((bool)false));
}

var result = builder.ToImmutableArray();
var message = result.IsEmpty ? EditorFeaturesResources.The_symbol_has_no_implementations : null;

return result.Length == 0
? (solution, symbolAndProjectId, result, EditorFeaturesResources.The_symbol_has_no_implementations)
: (solution, symbolAndProjectId, result, null);
return (solution, symbolAndProjectId, result, message);
}

private static async Task<ImmutableArray<SymbolAndProjectId>> FindSourceImplementationsWorkerAsync(
SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken)
Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken)
{
var implementations = await FindSourceAndMetadataImplementationsAsync(symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false);
var implementations = await FindSourceAndMetadataImplementationsAsync(solution, symbolAndProjectId, cancellationToken).ConfigureAwait(false);
return implementations.WhereAsArray(s => s.Symbol.Locations.Any(l => l.IsInSource));
}

private static async Task<ImmutableArray<SymbolAndProjectId>> FindSourceAndMetadataImplementationsAsync(
SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken)
Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken)
{
if (symbolAndProjectId.Symbol.IsInterfaceType() || symbolAndProjectId.Symbol.IsImplementableMember())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public Task<ImmutableArray<SymbolAndProjectId>> DetermineCascadedSymbolsAsync(
SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet<Project> projects,
FindReferencesSearchOptions options, CancellationToken cancellationToken)
{
return SymbolFinder.FindLinkedSymbolsAsync(symbolAndProjectId.Symbol, solution, cancellationToken);
return SymbolFinder.FindLinkedSymbolsAsync(solution, symbolAndProjectId, cancellationToken);
}

public Task<ImmutableArray<Document>> DetermineDocumentsToSearchAsync(
Expand Down
17 changes: 10 additions & 7 deletions src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,19 +236,21 @@ public static IEnumerable<TSymbol> FindSimilarSymbols<TSymbol>(TSymbol symbol, C
}

/// <summary>
/// If <paramref name="symbol"/> is declared in a linked file, then this function returns all the other symbols
/// that are defined by the same symbol's syntax in the other projects that the linked file is referenced from.
/// If <paramref name="symbolAndProjectId"/> is declared in a linked file, then this function returns all the symbols that
/// are defined by the same symbol's syntax in the all projects that the linked file is referenced from.
/// <para/>
/// In order to be returned the other symbols must have the same <see cref="ISymbol.Name"/> and <see
/// cref="ISymbol.Kind"/> as <paramref name="symbol"/>. This matches general user intuition that these are all
/// cref="ISymbol.Kind"/> as <paramref name="symbolAndProjectId"/>. This matches general user intuition that these are all
/// the 'same' symbol, and should be examined, regardless of the project context and <see cref="ISymbol"/> they
/// originally started with.
/// </summary>
internal static async Task<ImmutableArray<SymbolAndProjectId>> FindLinkedSymbolsAsync(
ISymbol symbol, Solution solution, CancellationToken cancellationToken)
Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken)
{
var linkedSymbols = new HashSet<SymbolAndProjectId>();
// Add the original symbol to the result set.
var linkedSymbols = new HashSet<SymbolAndProjectId> { symbolAndProjectId };

var symbol = symbolAndProjectId.Symbol;
foreach (var location in symbol.DeclaringSyntaxReferences)
{
var originalDocument = solution.GetDocument(location.SyntaxTree);
Expand All @@ -269,8 +271,9 @@ internal static async Task<ImmutableArray<SymbolAndProjectId>> FindLinkedSymbols
var semanticModel = await linkedDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var linkedSymbol = semanticModel.GetDeclaredSymbol(linkedNode, cancellationToken);

if (linkedSymbol?.Kind == symbol.Kind &&
linkedSymbol?.Name == symbol.Name)
if (linkedSymbol != null &&
linkedSymbol.Kind == symbol.Kind &&
linkedSymbol.Name == symbol.Name)
{
linkedSymbols.Add(SymbolAndProjectId.Create(linkedSymbol, linkedDocument.Project.Id));
}
Expand Down

0 comments on commit c7c78a9

Please sign in to comment.