public static Task <IEnumerable <INamedTypeSymbol> > FindImplementingTypesAsync( this INamedTypeSymbol type, Solution solution, IImmutableSet <Project> projects, CancellationToken cancellationToken) { return(DependentTypeFinder.FindImplementingTypesAsync(type, solution, projects, cancellationToken)); }
public override ITypeSymbol VisitTypeParameter(ITypeParameterSymbol symbol) { if (_availableTypeParameterNames.Contains(symbol.Name)) { return(symbol); } switch (symbol.ConstraintTypes.Length) { case 0: // If there are no constraint then there is no replacement required // Just return the symbol return(symbol); case 1: // If there is one constraint which is a INamedTypeSymbol then return the INamedTypeSymbol // because the TypeParameter is expected to be of that type // else return the original symbol return(symbol.ConstraintTypes.ElementAt(0) as INamedTypeSymbol ?? (ITypeSymbol)symbol); // More than one default: if (symbol.ConstraintTypes.All(t => t is INamedTypeSymbol)) { var immutableProjects = _solution.Projects.ToImmutableHashSet(); var derivedImplementedTypesOfEachConstraintType = symbol.ConstraintTypes.Select(ct => { var derivedAndImplementedTypes = new List <INamedTypeSymbol>(); return(SymbolFinder.FindDerivedClassesAsync((INamedTypeSymbol)ct, _solution, immutableProjects, _cancellationToken).WaitAndGetResult(_cancellationToken) .Concat(DependentTypeFinder.FindImplementingTypesAsync((INamedTypeSymbol)ct, _solution, immutableProjects, _cancellationToken).WaitAndGetResult(_cancellationToken)) .ToList()); }); var intersectingTypes = derivedImplementedTypesOfEachConstraintType.Aggregate((x, y) => x.Intersect(y).ToList()); // If there was any intersecting derived type among the constraint types then pick the first of the lot. if (intersectingTypes.Any()) { var resultantIntersectingType = intersectingTypes.First(); // If the resultant intersecting type contains any Type arguments that could be replaced // using the type constraints then recursively update the type until all constraints are appropriately handled var typeConstraintConvertedType = resultantIntersectingType.Accept(this); var knownSimilarTypesInCompilation = SymbolFinder.FindSimilarSymbols(typeConstraintConvertedType, _compilation, _cancellationToken); if (knownSimilarTypesInCompilation.Any()) { return(knownSimilarTypesInCompilation.First()); } var resultantSimilarKnownTypes = SymbolFinder.FindSimilarSymbols(resultantIntersectingType, _compilation, _cancellationToken); return(resultantSimilarKnownTypes.FirstOrDefault() ?? (ITypeSymbol)symbol); } } return(symbol); } }
public Task <ImmutableArray <SerializableSymbolAndProjectId> > FindImplementingTypesAsync( PinnedSolutionInfo solutionInfo, SerializableSymbolAndProjectId typeAndProjectId, ProjectId[] projectIds, bool transitive, CancellationToken cancellationToken) { return(FindTypesAsync( solutionInfo, typeAndProjectId, projectIds, (nt, s, ps) => DependentTypeFinder.FindImplementingTypesAsync(nt, s, ps, transitive, cancellationToken), cancellationToken)); }