提交 47b406e5 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #14047 from CyrusNajmabadi/findRefsConstructors

Don't show duplicate FAR results on an object creation expression.
......@@ -68,6 +68,12 @@ public Task OnDefinitionFoundAsync(SymbolAndProjectId definition)
public async Task OnReferenceFoundAsync(SymbolAndProjectId definition, ReferenceLocation location)
{
// Ignore duplicate locations. We don't want to clutter the UI with them.
if (location.IsDuplicateReferenceLocation)
{
return;
}
var referenceItem = location.TryCreateSourceReferenceItem(
GetDefinitionItem(definition));
......
......@@ -14,6 +14,12 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders
{
internal class ConstructorSymbolReferenceFinder : AbstractReferenceFinder<IMethodSymbol>
{
public static readonly ConstructorSymbolReferenceFinder Instance = new ConstructorSymbolReferenceFinder();
private ConstructorSymbolReferenceFinder()
{
}
protected override bool CanFind(IMethodSymbol symbol)
{
return symbol.MethodKind == MethodKind.Constructor;
......@@ -52,7 +58,15 @@ protected override bool CanFind(IMethodSymbol symbol)
predefinedType == actualType;
}
protected override async Task<ImmutableArray<ReferenceLocation>> FindReferencesInDocumentAsync(
protected override Task<ImmutableArray<ReferenceLocation>> FindReferencesInDocumentAsync(
IMethodSymbol methodSymbol,
Document document,
CancellationToken cancellationToken)
{
return FindAllReferencesInDocumentAsync(methodSymbol, document, cancellationToken);
}
internal async Task<ImmutableArray<ReferenceLocation>> FindAllReferencesInDocumentAsync(
IMethodSymbol methodSymbol,
Document document,
CancellationToken cancellationToken)
......
// 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.Collections.Generic;
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
......@@ -85,6 +84,64 @@ protected override bool CanFind(INamedTypeSymbol symbol)
INamedTypeSymbol namedType,
Document document,
CancellationToken cancellationToken)
{
var namedTypereferences = await FindReferencesInDocumentWorker(
namedType, document, cancellationToken).ConfigureAwait(false);
// Mark any references that are also Constructor references. Some callers
// will want to know about these so they won't display duplicates.
return await MarkConstructorReferences(
namedType, document, namedTypereferences, cancellationToken).ConfigureAwait(false);
}
private async Task<ImmutableArray<ReferenceLocation>> MarkConstructorReferences(
INamedTypeSymbol namedType, Document document,
ImmutableArray<ReferenceLocation> namedTypereferences,
CancellationToken cancellationToken)
{
var constructorReferences = ArrayBuilder<ReferenceLocation>.GetInstance();
foreach (var constructor in namedType.Constructors)
{
var references = await ConstructorSymbolReferenceFinder.Instance.FindAllReferencesInDocumentAsync(
constructor, document, cancellationToken).ConfigureAwait(false);
constructorReferences.AddRange(references);
}
var result = ArrayBuilder<ReferenceLocation>.GetInstance();
foreach (var reference in namedTypereferences)
{
if (Contains(constructorReferences, reference))
{
var localReference = reference;
localReference.IsDuplicateReferenceLocation = true;
result.Add(localReference);
}
else
{
result.Add(reference);
}
}
return result.ToImmutableAndFree();
}
private bool Contains(
ArrayBuilder<ReferenceLocation> constructorReferences,
ReferenceLocation reference)
{
foreach (var constructorRef in constructorReferences)
{
if (reference.Location == constructorRef.Location)
{
return true;
}
}
return false;
}
private static async Task<ImmutableArray<ReferenceLocation>> FindReferencesInDocumentWorker(
INamedTypeSymbol namedType, Document document, CancellationToken cancellationToken)
{
var nonAliasReferences = await FindNonAliasReferencesAsync(namedType, document, cancellationToken).ConfigureAwait(false);
var symbolsMatch = GetStandardSymbolsMatchFunction(namedType, null, document.Project.Solution, cancellationToken);
......
......@@ -6,7 +6,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders
{
internal static class ReferenceFinders
{
public static readonly IReferenceFinder Constructor = new ConstructorSymbolReferenceFinder();
public static readonly IReferenceFinder Constructor = ConstructorSymbolReferenceFinder.Instance;
public static readonly IReferenceFinder ConstructorInitializer = new ConstructorInitializerSymbolReferenceFinder();
public static readonly IReferenceFinder Destructor = new DestructorSymbolReferenceFinder();
public static readonly IReferenceFinder ExplicitInterfaceMethod = new ExplicitInterfaceMethodReferenceFinder();
......
......@@ -41,6 +41,13 @@ public struct ReferenceLocation : IComparable<ReferenceLocation>, IEquatable<Ref
/// </summary>
internal bool IsWrittenTo { get; }
/// <summary>
/// Indicates if this location is a duplicate of some another ReferenceLocation.
/// In this case, it's acceptable for a presenter to not show this location and
/// intead prefer the latter.
/// </summary>
internal bool IsDuplicateReferenceLocation;
public CandidateReason CandidateReason { get; }
internal ReferenceLocation(Document document, IAliasSymbol alias, Location location, bool isImplicit, bool isWrittenTo, CandidateReason candidateReason)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册