static private ImplicitConvert ( |
||
expression | ||
expectedType | ||
return |
internal static Expression ImplicitConvert(Expression expression, Type expectedType)
{
if (expectedType == null)
{
return expression;
}
if (expectedType.IsGenericParameter)
{
if (!expectedType.IsAppropriate(expression.Type))
{
return null;
}
}
else
{
if ((expectedType.IsAppropriate(expression.Type) && expression.Type.IsValueType && !expectedType.IsValueType)
|| expectedType.GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static, null, new [] { expression.Type, }, null) != null
)
{
return Convert(expression, expectedType);
}
if (!expectedType.IsAppropriate(expression.Type))
{
if (Nullable.GetUnderlyingType(expectedType).Let(t => t != null && t == expression.Type))
{
return Convert(expression, typeof(Nullable<>).MakeGenericType(expression.Type));
}
else if (Nullable.GetUnderlyingType(expression.Type).Let(t => t != null && t == expectedType))
{
return Convert(expression, Nullable.GetUnderlyingType(expression.Type));
}
return ConvertNumericType(expression.Type, expectedType)
.Null(t => Convert(expression, t));
}
}
return expression;
}
/// <summary> /// Reduces this node to a simpler expression, with (if possible) additional symbol tables. /// </summary> /// <param name="expression">The reducing expression.</param> /// <param name="symbols">The additional symbol table for reducing. If <paramref name="expression"/> is not <see cref="YacqExpression"/>, this parameter is ignored.</param> /// <param name="expectedType">The type which is expected as the type of reduced expression.</param> /// <returns>The reduced expression.</returns> public static Expression Reduce(this Expression expression, SymbolTable symbols, Type expectedType = null) { return(expression != null ? expression is YacqExpression ? ((YacqExpression)expression).Reduce(symbols, expectedType) : YacqExpression.ImplicitConvert(expression, expectedType) : null); }