private static void ValidateAsyncLambdaArgs(Type delegateType, ref Expression body, ReadOnlyCollection <ParameterExpression> parameters)
{
//ContractUtils.RequiresNotNull(delegateType, nameof(delegateType));
//TODO: Verify
//RequiresCanRead(body, nameof(body));
if (!typeof(MulticastDelegate).IsAssignableFrom(delegateType) || delegateType == typeof(MulticastDelegate))
{
throw LinqError.LambdaTypeMustBeDerivedFromSystemDelegate();
}
var count = parameters.Count;
var method = delegateType.GetMethod("Invoke"); // TODO: use cache from LINQ
var parametersCached = method.GetParametersCached();
if (parametersCached.Length != 0)
{
if (parametersCached.Length != count)
{
throw LinqError.IncorrectNumberOfLambdaDeclarationParameters();
}
var set = new Set <ParameterExpression>(count);
for (var i = 0; i < count; i++)
{
var parameter = parameters[i];
ValidateAsyncParameter(parameter);
var parameterType = parametersCached[i].ParameterType;
if (!TypeUtils1.AreReferenceAssignable(parameter.Type, parameterType))
{
throw LinqError.ParameterExpressionNotValidAsDelegate(parameter.Type, parameterType);
}
if (set.Contains(parameter))
{
throw LinqError.DuplicateVariable(parameter);
}
set.Add(parameter);
}
}
else if (count > 0)
{
throw LinqError.IncorrectNumberOfLambdaDeclarationParameters();
}
var returnType = method.ReturnType;
if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>))
{
var resultType = returnType.GetGenericArguments()[0];
if (!TypeUtils1.AreReferenceAssignable(resultType, body.Type) && !TryQuote(resultType, ref body))
{
throw LinqError.ExpressionTypeDoesNotMatchReturn(body.Type, method.ReturnType);
}
}
else if (returnType != typeof(void) && returnType != typeof(Task))
{
throw Error.AsyncLambdaInvalidReturnType(returnType);
}
}