| File: Shared\Extensions\IFindReferencesResultExtensions.cs | Web Access |
| Project: src\roslyn\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces) |
// 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. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Utilities; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Shared.Extensions; internal static partial class IFindReferencesResultExtensions { public static IEnumerable<Location> GetDefinitionLocationsToShow( this ISymbol definition) { return definition.IsKind(SymbolKind.Namespace) ? [definition.Locations.First()] : definition.Locations; } public static ImmutableArray<ReferencedSymbol> FilterToItemsToShow( this ImmutableArray<ReferencedSymbol> result, FindReferencesSearchOptions options) { return result.WhereAsArray(r => ShouldShow(r, options)); } public static bool ShouldShow( this ReferencedSymbol referencedSymbol, FindReferencesSearchOptions options) { // If the reference has any locations then we will present it. if (referencedSymbol.Locations.Any()) { return true; } return referencedSymbol.Definition.ShouldShowWithNoReferenceLocations( options, showMetadataSymbolsWithoutReferences: true); } public static bool ShouldShowWithNoReferenceLocations( this ISymbol definition, FindReferencesSearchOptions options, bool showMetadataSymbolsWithoutReferences) { if (options.DisplayAllDefinitions) { return true; } // If the definition is implicit and we have no references, then we don't want to // clutter the UI with it. if (definition.IsImplicitlyDeclared) { return false; } // If we're associating property references with an accessor, then we don't want to show // a property if it is has no references. Similarly, if we're associated associating // everything with the property, then we don't want to include accessors if there are no // references to them. if (options.AssociatePropertyReferencesWithSpecificAccessor) { if (definition.Kind == SymbolKind.Property) { return false; } } else { if (definition.IsPropertyAccessor()) { return false; } } // Otherwise we still show the item even if there are no references to it. // And it's at least a source definition. if (definition.Locations.Any(static loc => loc.IsInSource)) { return true; } if (showMetadataSymbolsWithoutReferences && definition.Locations.Any(static loc => loc.IsInMetadata)) { return true; } return false; } public static ImmutableArray<ReferencedSymbol> FilterToAliasMatches( this ImmutableArray<ReferencedSymbol> result, IAliasSymbol? aliasSymbol) { if (aliasSymbol == null) { return result; } var q = from r in result let aliasLocations = r.Locations.WhereAsArray(loc => SymbolEquivalenceComparer.Instance.Equals(loc.Alias, aliasSymbol)) where aliasLocations.Any() select new ReferencedSymbol(r.Definition, aliasLocations); return [.. q]; } public static ImmutableArray<ReferencedSymbol> FilterNonMatchingMethodNames( this ImmutableArray<ReferencedSymbol> result, Solution solution, ISymbol symbol) { return symbol.IsOrdinaryMethod() ? FilterNonMatchingMethodNamesWorker(result, solution, symbol) : result; } private static ImmutableArray<ReferencedSymbol> FilterNonMatchingMethodNamesWorker( ImmutableArray<ReferencedSymbol> references, Solution solution, ISymbol symbol) { using var _ = ArrayBuilder<ReferencedSymbol>.GetInstance(out var result); foreach (var reference in references) { var isCaseSensitive = solution.Services.GetLanguageServices(reference.Definition.Language).GetRequiredService<ISyntaxFactsService>().IsCaseSensitive; var comparer = isCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; if (reference.Definition.IsOrdinaryMethod() && !comparer.Equals(reference.Definition.Name, symbol.Name)) { continue; } result.Add(reference); } return result.ToImmutableAndClear(); } }