internal Type ResultType(Type left, Type right, bool lc, bool rc, int op)
{
if ((left == typeof(System.Guid)) && (right == typeof(System.Guid)) && Operators.IsRelational(op))
{
return(left);
}
if ((left == typeof(System.String)) && (right == typeof(System.Guid)) && Operators.IsRelational(op))
{
return(left);
}
if ((left == typeof(System.Guid)) && (right == typeof(System.String)) && Operators.IsRelational(op))
{
return(right);
}
int leftPrecedence = (int)GetPrecedence(left);
if (leftPrecedence == (int)DataTypePrecedence.Error)
{
return(null);
}
int rightPrecedence = (int)GetPrecedence(right);
if (rightPrecedence == (int)DataTypePrecedence.Error)
{
return(null);
}
if (Operators.IsLogical(op))
{
if (left == typeof(Boolean) && right == typeof(Boolean))
{
return(typeof(Boolean));
}
else
{
return(null);
}
}
if ((op == Operators.Plus) && ((left == typeof(String)) || (right == typeof(String))))
{
return(typeof(string));
}
DataTypePrecedence higherPrec = (DataTypePrecedence)Math.Max(leftPrecedence, rightPrecedence);
Type result = GetType(higherPrec);
if (Operators.IsArithmetical(op))
{
if (result != typeof(string) && result != typeof(char))
{
if (!IsNumeric(left))
{
return(null);
}
if (!IsNumeric(right))
{
return(null);
}
}
}
// if the operation is a division the result should be at least a double
if ((op == Operators.Divide) && IsInteger(result))
{
return(typeof(double));
}
if (IsMixed(left, right))
{
// we are dealing with one signed and one unsigned type so
// try to see if one of them is a ConstNode
if (lc && (!rc))
{
return(right);
}
else if ((!lc) && rc)
{
return(left);
}
if (IsUnsigned(result))
{
if (higherPrec < DataTypePrecedence.UInt64)
{
// left and right are mixed integers but with the same length
// so promote to the next signed type
result = GetType(higherPrec + 1);
}
else
{
throw ExprException.AmbiguousBinop(op, left, right);
}
}
}
return(result);
}