private IEnumerable<IMethodSymbol> Resolve(Compilation compilation, INamedTypeSymbol container, bool ignoreAssemblyKey, CancellationToken cancellationToken)
{
var comparisonOptions = new ComparisonOptions(compilation.IsCaseSensitive, ignoreAssemblyKey, compareMethodTypeParametersByName: true);
ITypeSymbol[] typeArguments = null;
if (_typeArgumentKeysOpt != null)
{
typeArguments = _typeArgumentKeysOpt.Select(a => a.Resolve(compilation, cancellationToken: cancellationToken).Symbol as ITypeSymbol).ToArray();
if (typeArguments.Any(a => a == null))
{
yield break;
}
}
foreach (var method in container.GetMembers().OfType<IMethodSymbol>())
{
// Quick checks first
if (method.MetadataName != _metadataName || method.Arity != _arity || method.Parameters.Length != _originalParameterTypeKeys.Length)
{
continue;
}
// Is this a conversion operator? If so, we must also compare the return type.
if (_returnType != null)
{
if (!_returnType.Equals(SymbolKey.Create(method.ReturnType, compilation, cancellationToken), comparisonOptions))
{
continue;
}
}
if (!ParametersMatch(comparisonOptions, compilation, method.OriginalDefinition.Parameters, _refKinds, _originalParameterTypeKeys, cancellationToken))
{
continue;
}
// It matches, so let's return it, but we might have to do some construction first
var methodToReturn = method;
if (_isPartialMethodImplementationPart)
{
methodToReturn = methodToReturn.PartialImplementationPart ?? methodToReturn;
}
if (typeArguments != null)
{
methodToReturn = methodToReturn.Construct(typeArguments);
}
yield return methodToReturn;
}
}