Merge pull request #498 from Unroll-Me/master
[mono.git] / mcs / class / System.Core / System.Linq.Expressions / Expression.cs
index 520c1cb49491237c204ff4430ce7081ff6ab3181..bfe939a5cb0901bb47395d82de7a18de15840b68 100644 (file)
@@ -242,7 +242,7 @@ namespace System.Linq.Expressions {
 
                                // 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){
@@ -265,6 +265,9 @@ namespace System.Linq.Expressions {
                                        if (!ltype.IsValueType && !rtype.IsValueType)
                                                return null;
 
+                                       if (ltype == rtype && ultype.IsEnum)
+                                               return null;
+
                                        if (ltype == rtype && ultype == typeof (bool))
                                                return null;
                                }
@@ -868,6 +871,8 @@ namespace System.Linq.Expressions {
                                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:
@@ -1040,7 +1045,7 @@ namespace System.Linq.Expressions {
                        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)
@@ -1080,15 +1085,25 @@ namespace System.Linq.Expressions {
                                        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)
@@ -1096,7 +1111,7 @@ namespace System.Linq.Expressions {
                                                  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)
@@ -1168,7 +1183,7 @@ namespace System.Linq.Expressions {
                static bool IsConvertiblePrimitive (Type type)
                {
                        var t = type.GetNotNullableType ();
-
+       
                        if (t == typeof (bool))
                                return false;
 
@@ -1206,6 +1221,9 @@ namespace System.Linq.Expressions {
                        if (type.IsInterface || target.IsInterface)
                                return true;
 
+                       if (type.IsEnum && target == typeof (Enum))
+                               return true;
+
                        if (type.IsValueType || target.IsValueType)
                                return false;
 
@@ -2084,8 +2102,12 @@ namespace System.Linq.Expressions {
                                        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)
@@ -2221,7 +2243,7 @@ namespace System.Linq.Expressions {
                        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)
@@ -2246,9 +2268,11 @@ namespace System.Linq.Expressions {
                // 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
        }
 }