private static void ValidateUserDefinedConditionalLogicOperator(ExpressionType nodeType, Type left, Type right, MethodInfo method)
{
ValidateOperator(method);
ParameterInfo[] pms = method.GetParametersCached();
if (pms.Length != 2)
throw Error.IncorrectNumberOfMethodCallArguments(method, nameof(method));
if (!ParameterIsAssignable(pms[0], left))
{
if (!(left.IsNullableType() && ParameterIsAssignable(pms[0], left.GetNonNullableType())))
throw Error.OperandTypesDoNotMatchParameters(nodeType, method.Name);
}
if (!ParameterIsAssignable(pms[1], right))
{
if (!(right.IsNullableType() && ParameterIsAssignable(pms[1], right.GetNonNullableType())))
throw Error.OperandTypesDoNotMatchParameters(nodeType, method.Name);
}
if (pms[0].ParameterType != pms[1].ParameterType)
{
throw Error.UserDefinedOpMustHaveConsistentTypes(nodeType, method.Name);
}
if (method.ReturnType != pms[0].ParameterType)
{
throw Error.UserDefinedOpMustHaveConsistentTypes(nodeType, method.Name);
}
if (IsValidLiftedConditionalLogicalOperator(left, right, pms))
{
left = left.GetNonNullableType();
}
MethodInfo opTrue = TypeUtils.GetBooleanOperator(method.DeclaringType, "op_True");
MethodInfo opFalse = TypeUtils.GetBooleanOperator(method.DeclaringType, "op_False");
if (opTrue == null || opTrue.ReturnType != typeof(bool) ||
opFalse == null || opFalse.ReturnType != typeof(bool))
{
throw Error.LogicalOperatorMustHaveBooleanOperators(nodeType, method.Name);
}
VerifyOpTrueFalse(nodeType, left, opFalse, nameof(method));
VerifyOpTrueFalse(nodeType, left, opTrue, nameof(method));
}