/// <inheritdoc cref="FindImplementationsAsync(INamedTypeSymbol, Solution, bool, IImmutableSet{Project}, CancellationToken)"/> /// <remarks> Use this overload to avoid boxing the result into an <see cref="IEnumerable{T}"/>.</remarks> internal static async Task <ImmutableArray <INamedTypeSymbol> > FindImplementationsArrayAsync( INamedTypeSymbol type, Solution solution, bool transitive, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default) { var types = await DependentTypeFinder.FindTypesAsync( type, solution, projects, transitive, DependentTypesKind.ImplementingTypes, cancellationToken).ConfigureAwait(false); return(types.WhereAsArray(t => IsAccessible(t))); }
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.FindTransitivelyImplementingStructuresAndClassesAsync( symbolAndProjectId.WithSymbol(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.FindTransitivelyImplementingStructuresClassesAndInterfacesAsync( symbolAndProjectId.WithSymbol(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, 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 ??= ImmutableArray.CreateBuilder <SymbolAndProjectId>(); results.Add(bestDef.WithSymbol(bestDef.Symbol.OriginalDefinition)); } } } if (results != null) { return(results.Distinct(SymbolAndProjectIdComparer.SymbolEquivalenceInstance) .ToImmutableArray()); } } return(ImmutableArray <SymbolAndProjectId> .Empty); }
/// <summary> /// Finds the derived classes of the given type. Implementations of an interface are not considered "derived", but can be found /// with <see cref="FindImplementationsAsync"/>. /// </summary> /// <param name="type">The symbol to find derived types of.</param> /// <param name="solution">The solution to search in.</param> /// <param name="projects">The projects to search. Can be null to search the entire solution.</param> /// <param name="cancellationToken"></param> /// <returns>The derived types of the symbol. The symbol passed in is not included in this list.</returns> public static Task <IEnumerable <INamedTypeSymbol> > FindDerivedClassesAsync( INamedTypeSymbol type, Solution solution, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default(CancellationToken)) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (solution == null) { throw new ArgumentNullException(nameof(solution)); } return(DependentTypeFinder.FindDerivedClassesAsync(type, solution, projects, cancellationToken)); }
internal static Task <ImmutableArray <SymbolAndProjectId <INamedTypeSymbol> > > FindDerivedClassesAsync( SymbolAndProjectId <INamedTypeSymbol> typeAndProjectId, Solution solution, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default) { var type = typeAndProjectId.Symbol; if (type == null) { throw new ArgumentNullException(nameof(type)); } if (solution == null) { throw new ArgumentNullException(nameof(solution)); } return(DependentTypeFinder.FindTransitivelyDerivedClassesAsync(type, solution, projects, cancellationToken)); }
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 derived classes of the given type. Implementations of an interface are not considered "derived", but can be found /// with <see cref="FindImplementationsAsync(ISymbol, Solution, IImmutableSet{Project}, CancellationToken)"/>. /// </summary> /// <param name="type">The symbol to find derived types of.</param> /// <param name="solution">The solution to search in.</param> /// <param name="projects">The projects to search. Can be null to search the entire solution.</param> /// <param name="cancellationToken"></param> /// <returns>The derived types of the symbol. The symbol passed in is not included in this list.</returns> public static async Task <IEnumerable <INamedTypeSymbol> > FindDerivedClassesAsync( INamedTypeSymbol type, Solution solution, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (solution == null) { throw new ArgumentNullException(nameof(solution)); } if (solution.GetOriginatingProjectId(type) == null) { throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(type)); } return(await DependentTypeFinder.FindTransitivelyDerivedClassesAsync( type, solution, projects, cancellationToken).ConfigureAwait(false)); }
> FindDerivedInterfacesArrayAsync( INamedTypeSymbol type, Solution solution, bool transitive, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default ) { var types = await DependentTypeFinder .FindTypesAsync( type, solution, projects, transitive, DependentTypesKind.DerivedInterfaces, cancellationToken ) .ConfigureAwait(false); return(types.WhereAsArray(t => IsAccessible(t))); }
/// <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.FindImplementingTypesAsync(namedTypeSymbol, solution, projects, cancellationToken).ConfigureAwait(false); return(implementingTypes.Where(IsAccessible)); } else if (symbol.IsImplementableMember()) { var containingType = symbol.ContainingType.OriginalDefinition; var allTypes = await DependentTypeFinder.FindImplementingTypesAsync(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>()); }
/// <summary> /// Find symbols for members that override the specified member symbol. /// </summary> public static async Task <IEnumerable <ISymbol> > FindOverridesAsync( ISymbol symbol, Solution solution, IImmutableSet <Project> projects = null, CancellationToken cancellationToken = default(CancellationToken)) { // Method can only have overrides if its a virtual, abstract or override and is not // sealed. if (symbol.IsOverridable()) { // To find the overrides, we need to walk down the type hierarchy and check all // derived types. TODO(cyrusn): This seems extremely costly. Is there any way to // speed this up? var containingType = symbol.ContainingType.OriginalDefinition; var derivedTypes = await FindDerivedClassesAsync(containingType, solution, projects, cancellationToken).ConfigureAwait(false); List <ISymbol> results = null; foreach (var type in derivedTypes) { foreach (var m in type.GetMembers(symbol.Name)) { var member = await FindSourceDefinitionAsync(m, solution, cancellationToken).ConfigureAwait(false) ?? m; if (member != null && member.IsOverride && member.OverriddenMember() != null && DependentTypeFinder.OriginalSymbolsMatch(member.OverriddenMember().OriginalDefinition, symbol.OriginalDefinition, solution, cancellationToken)) { results = results ?? new List <ISymbol>(); results.Add(member); } } } if (results != null) { return(results); } } return(SpecializedCollections.EmptyEnumerable <ISymbol>()); }