/// <summary> /// Searches for an async counterpart methods within containing and its bases types /// </summary> /// <param name="methodSymbol"></param> /// <param name="invokedFromType"></param> /// <param name="equalParameters"></param> /// <param name="searchInheritedTypes"></param> /// <param name="hasCancellationToken"></param> /// <param name="ignoreReturnType"></param> /// <returns></returns> public static IEnumerable <IMethodSymbol> GetAsyncCounterparts(this IMethodSymbol methodSymbol, ITypeSymbol invokedFromType, bool equalParameters, bool searchInheritedTypes, bool hasCancellationToken, bool ignoreReturnType) { var asyncName = methodSymbol.GetAsyncName(); if (searchInheritedTypes) { // If the method was invoked in an upper type use it as a root type. ITypeSymbol rootType; if (invokedFromType != null && invokedFromType.InheritsFromOrEquals(methodSymbol.ContainingType, true)) { rootType = invokedFromType; } else { rootType = methodSymbol.ContainingType; } // If the containing type is not an interface we don't have to search in interfaces as all interface members // should be defined in one of the types. var types = rootType.TypeKind == TypeKind.Interface ? new[] { rootType }.Concat(rootType.AllInterfaces) : rootType.GetBaseTypesAndThis(); var asyncCounterparts = types .SelectMany(o => o.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.Equals(m))) .OfType <IMethodSymbol>() .Where(o => methodSymbol.IsAsyncCounterpart(invokedFromType, o, equalParameters, hasCancellationToken, ignoreReturnType)); // We have to return only unique async counterparts, skip overriden and hidden methods return(FilterOutHiddenAndOverridenMethods(asyncCounterparts)); } return(methodSymbol.ContainingType.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.Equals(m)) .OfType <IMethodSymbol>() .Where(o => methodSymbol.IsAsyncCounterpart(invokedFromType, o, equalParameters, hasCancellationToken, ignoreReturnType))); }
/// <summary> /// Searches for an async counterpart methods within containing and its bases types /// </summary> /// <param name="methodSymbol"></param> /// <param name="invokedFromType"></param> /// <param name="equalParameters"></param> /// <param name="searchInheritedTypes"></param> /// <param name="hasCancellationToken"></param> /// <param name="ignoreReturnType"></param> /// <returns></returns> public static IEnumerable <IMethodSymbol> GetAsyncCounterparts(this IMethodSymbol methodSymbol, ITypeSymbol invokedFromType, bool equalParameters, bool searchInheritedTypes, bool hasCancellationToken, bool ignoreReturnType) { var asyncName = methodSymbol.GetAsyncName(); if (searchInheritedTypes) { return(methodSymbol.ContainingType.GetBaseTypesAndThis() .SelectMany(o => o.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.Equals(m))) .OfType <IMethodSymbol>() .Where(o => methodSymbol.IsAsyncCounterpart(invokedFromType, o, equalParameters, hasCancellationToken, ignoreReturnType))); } return(methodSymbol.ContainingType.GetMembers().Where(m => asyncName == m.Name || !equalParameters && m.Name == methodSymbol.Name && !methodSymbol.Equals(m)) .OfType <IMethodSymbol>() .Where(o => methodSymbol.IsAsyncCounterpart(invokedFromType, o, equalParameters, hasCancellationToken, ignoreReturnType))); }
public IEnumerable <IMethodSymbol> FindAsyncCounterparts(IMethodSymbol symbol, ITypeSymbol invokedFromType, AsyncCounterpartsSearchOptions options) { if (invokedFromType == null) { yield break; } var asyncName = symbol.GetAsyncName(); foreach (var asyncCandidate in _extensionMethodsLookup[asyncName]) { if (!symbol.IsAsyncCounterpart(invokedFromType, asyncCandidate, true, true, false)) { continue; } yield return(asyncCandidate); yield break; } }