// Use IsNumber to avoid expensive reflection.
if (IsNumber (ultype)) {
- if (ultype == urtype && ltype == rtype && ultype != typeof (decimal))
+ if (ultype == urtype && ltype == rtype)
return null;
if (oper_name != null){
if (!ltype.IsValueType && !rtype.IsValueType)
return null;
+ if (ltype == rtype && ultype.IsEnum)
+ return null;
+
if (ltype == rtype && ultype == typeof (bool))
return null;
}
return AddChecked (left, right, method);
case ExpressionType.AndAlso:
return AndAlso (left, right);
+ case ExpressionType.ArrayIndex:
+ return ArrayIndex (left, right);
case ExpressionType.Coalesce:
return Coalesce (left, right, conversion);
case ExpressionType.Divide:
if (method == null)
return null;
- if (!method.IsGenericMethod && args == null)
+ if (!method.IsGenericMethod && (args == null || args.Length == 0))
return method;
if (args.Length == method.GetGenericArguments ().Length)
return false;
return MethodMatch (closed, name, parameterTypes, argumentTypes);
- }
+ } else if (!method.IsGenericMethod && (argumentTypes != null && argumentTypes.Length > 0))
+ return false;
- for (int i = 0; i < parameters.Length; i++)
- if (!IsAssignableToParameterType (parameterTypes [i], parameters [i]))
+ for (int i = 0; i < parameters.Length; i++) {
+ var type = parameterTypes [i];
+ var parameter = parameters [i];
+ if (!IsAssignableToParameterType (type, parameter)
+ && !IsExpressionOfParameter (type, parameter.ParameterType))
return false;
+ }
return true;
}
+ static bool IsExpressionOfParameter (Type type, Type ptype)
+ {
+ return ptype.IsGenericInstanceOf (typeof (Expression<>)) && ptype.GetFirstGenericArgument () == type;
+ }
+
static MethodInfo TryGetMethod (Type type, string methodName, BindingFlags flags, Type [] parameterTypes, Type [] argumentTypes)
{
var methods = from meth in type.GetMethods (flags)
select meth;
if (methods.Count () > 1)
- throw new InvalidOperationException ("Too much method candidates");
+ throw new InvalidOperationException ("Too many method candidates");
var method = TryMakeGeneric (methods.FirstOrDefault (), argumentTypes);
if (method != null)
static bool IsConvertiblePrimitive (Type type)
{
var t = type.GetNotNullableType ();
-
+
if (t == typeof (bool))
return false;
if (type.IsInterface || target.IsInterface)
return true;
+ if (type.IsEnum && target == typeof (Enum))
+ return true;
+
if (type.IsValueType || target.IsValueType)
return false;
throw new ArgumentNullException ("expression");
if (!expression.Type.IsAssignableTo (propertyAccessor.DeclaringType))
throw new ArgumentException ("expression");
- } else if (expression != null)
- throw new ArgumentException ("expression");
+ }
+ //
+ // .NET does not mandate that if the property is static, that the expression must be null
+ // fixes a bug exposed by Orchard's ContentItemRecordAlteration.Alteration
+ // else if (expression != null)
+ // throw new ArgumentException ("expression");
var prop = GetAssociatedProperty (propertyAccessor);
if (prop == null)
if (IsInt (t))
return true;
- return t == typeof (float) || t == typeof (double) || t == typeof (decimal);
+ return t == typeof (float) || t == typeof (double);
}
static bool IsSignedNumber (Type t)
// This method must be overwritten by derived classes to
// compile the expression
//
+#if !FULL_AOT_RUNTIME
internal virtual void Emit (EmitContext ec)
{
throw new NotImplementedException (String.Format ("Emit method is not implemented in expression type {0}", GetType ()));
}
+#endif
}
}