internal static async Task <ImmutableArray <SymbolAndProjectId> > FindImplementationsAsync( SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default) { // A symbol can only have implementations if it's an interface or a // method/property/event from an interface. var symbol = symbolAndProjectId.Symbol; if (symbol is INamedTypeSymbol namedTypeSymbol) { var implementingTypes = await DependentTypeFinder.FindTransitivelyImplementingTypesAsync(namedTypeSymbol, solution, projects, cancellationToken).ConfigureAwait(false); return(implementingTypes.Select(s => (SymbolAndProjectId)s) .Where(IsAccessible) .ToImmutableArray()); } else if (symbol.IsImplementableMember()) { var containingType = symbol.ContainingType.OriginalDefinition; var allTypes = await DependentTypeFinder.FindTransitivelyImplementingTypesAsync(containingType, solution, projects, cancellationToken).ConfigureAwait(false); ImmutableArray <SymbolAndProjectId> .Builder results = null; foreach (var t in allTypes.Convert <INamedTypeSymbol, ITypeSymbol>()) { var implementations = await t.FindImplementationsForInterfaceMemberAsync(symbolAndProjectId.Symbol, solution, cancellationToken).ConfigureAwait(false); foreach (var implementation in implementations) { var sourceDef = await FindSourceDefinitionAsync(implementation, solution, cancellationToken).ConfigureAwait(false); var bestDef = sourceDef.Symbol != null ? sourceDef : implementation; if (IsAccessible(bestDef)) { results = results ?? ImmutableArray.CreateBuilder <SymbolAndProjectId>(); results.Add(bestDef.WithSymbol(bestDef.Symbol.OriginalDefinition)); } } } if (results != null) { return(results.Distinct(SymbolAndProjectIdComparer.SymbolEquivalenceInstance) .ToImmutableArray()); } } return(ImmutableArray <SymbolAndProjectId> .Empty); }
internal static async Task <IEnumerable <SymbolAndProjectId> > FindImplementationsAsync( SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default(CancellationToken)) { // A symbol can only have implementations if it's an interface or a // method/property/event from an interface. var symbol = symbolAndProjectId.Symbol; if (symbol is INamedTypeSymbol) { var namedTypeSymbol = (INamedTypeSymbol)symbol; var implementingTypes = await DependentTypeFinder.FindTransitivelyImplementingTypesAsync(namedTypeSymbol, solution, projects, cancellationToken).ConfigureAwait(false); return(implementingTypes.Select(s => (SymbolAndProjectId)s) .Where(IsAccessible) .ToList()); } else if (symbol.IsImplementableMember()) { var containingType = symbol.ContainingType.OriginalDefinition; var allTypes = await DependentTypeFinder.FindTransitivelyImplementingTypesAsync(containingType, solution, projects, cancellationToken).ConfigureAwait(false); List <SymbolAndProjectId> results = null; foreach (var t in allTypes.Convert <INamedTypeSymbol, ITypeSymbol>()) { foreach (var m in t.FindImplementationsForInterfaceMember(symbol, solution.Workspace, cancellationToken)) { var sourceDef = await FindSourceDefinitionAsync(m, solution, cancellationToken).ConfigureAwait(false); var bestDef = sourceDef.Symbol != null ? sourceDef : m; if (IsAccessible(bestDef)) { results = results ?? new List <SymbolAndProjectId>(); results.Add(bestDef.WithSymbol(bestDef.Symbol.OriginalDefinition)); } } } if (results != null) { return(results.Distinct(SymbolAndProjectIdComparer.SymbolEquivalenceInstance)); } } return(SpecializedCollections.EmptyEnumerable <SymbolAndProjectId>()); }
/// <summary> /// Finds the symbols that implement an interface or interface member. /// </summary> public static async Task <IEnumerable <ISymbol> > FindImplementationsAsync( ISymbol symbol, Solution solution, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default(CancellationToken)) { // A symbol can only have implementations if it's an interface or a // method/property/event from an interface. if (symbol is INamedTypeSymbol) { var namedTypeSymbol = (INamedTypeSymbol)symbol; var implementingTypes = await DependentTypeFinder.FindTransitivelyImplementingTypesAsync(namedTypeSymbol, solution, projects, cancellationToken).ConfigureAwait(false); return(implementingTypes.Where(IsAccessible)); } else if (symbol.IsImplementableMember()) { var containingType = symbol.ContainingType.OriginalDefinition; var allTypes = await DependentTypeFinder.FindTransitivelyImplementingTypesAsync(containingType, solution, projects, cancellationToken).ConfigureAwait(false); List <ISymbol> results = null; foreach (var t in allTypes) { foreach (var m in t.FindImplementationsForInterfaceMember(symbol, solution.Workspace, cancellationToken)) { var s = await FindSourceDefinitionAsync(m, solution, cancellationToken).ConfigureAwait(false) ?? m; if (IsAccessible(s)) { results = results ?? new List <ISymbol>(); results.Add(s.OriginalDefinition); } } } if (results != null) { return(results.Distinct(SymbolEquivalenceComparer.Instance)); } } return(SpecializedCollections.EmptyEnumerable <ISymbol>()); }