[corlib] Binder from reference sources
authorMarek Safar <marek.safar@gmail.com>
Fri, 27 Feb 2015 11:06:17 +0000 (12:06 +0100)
committerMarek Safar <marek.safar@gmail.com>
Fri, 27 Feb 2015 11:06:17 +0000 (12:06 +0100)
14 files changed:
external/referencesource
mcs/class/corlib/ReferenceSources/DefaultBinder.cs [new file with mode: 0644]
mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs
mcs/class/corlib/System.Reflection/Binder.cs [deleted file]
mcs/class/corlib/System.Reflection/MethodBase.cs
mcs/class/corlib/System.Reflection/MonoField.cs
mcs/class/corlib/System.Reflection/MonoMethod.cs
mcs/class/corlib/System/Activator.cs
mcs/class/corlib/System/MonoType.cs
mcs/class/corlib/System/Type.cs
mcs/class/corlib/Test/System.Reflection/BinderTests.cs
mcs/class/corlib/Test/System/ActivatorTest.cs
mcs/class/corlib/Test/System/TypeTest.cs
mcs/class/corlib/corlib.dll.sources

index c0a529a421cb47145a32078770205e42545e7021..bc0c91fe2c1d08e0a900f9dc908e705dbcf03fd6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c0a529a421cb47145a32078770205e42545e7021
+Subproject commit bc0c91fe2c1d08e0a900f9dc908e705dbcf03fd6
diff --git a/mcs/class/corlib/ReferenceSources/DefaultBinder.cs b/mcs/class/corlib/ReferenceSources/DefaultBinder.cs
new file mode 100644 (file)
index 0000000..0b1febc
--- /dev/null
@@ -0,0 +1,145 @@
+//
+// DefaultBinder.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2015 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace System
+{
+       partial class DefaultBinder
+       {
+               static bool CanConvertPrimitive (RuntimeType source, RuntimeType target)
+               {
+                       if (source.IsEnum)
+                               return false;
+
+                       var from = Type.GetTypeCode (source);
+                       switch (Type.GetTypeCode (target)) {
+                       case TypeCode.Char:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.UInt16:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.Int16:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.SByte:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.UInt16:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.Char:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.Int32:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.SByte:
+                               case TypeCode.Char:
+                               case TypeCode.Int16:
+                               case TypeCode.UInt16:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.UInt32:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.Char:
+                               case TypeCode.UInt16:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.Int64:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.SByte:
+                               case TypeCode.Int16:
+                               case TypeCode.Char:
+                               case TypeCode.UInt16:
+                               case TypeCode.Int32:
+                               case TypeCode.UInt32:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.UInt64:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.Char:
+                               case TypeCode.UInt16:
+                               case TypeCode.UInt32:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.Single:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.SByte:
+                               case TypeCode.Int16:
+                               case TypeCode.Char:
+                               case TypeCode.UInt16:
+                               case TypeCode.Int32:
+                               case TypeCode.UInt32:
+                               case TypeCode.Int64:
+                               case TypeCode.UInt64:
+                                       return true;
+                               }
+                               return false;
+                       case TypeCode.Double:
+                               switch (from) {
+                               case TypeCode.Byte:
+                               case TypeCode.SByte:
+                               case TypeCode.Char:
+                               case TypeCode.Int16:
+                               case TypeCode.UInt16:
+                               case TypeCode.Int32:
+                               case TypeCode.UInt32:
+                               case TypeCode.Int64:
+                               case TypeCode.UInt64:
+                               case TypeCode.Single:
+                                       return true;
+                               }
+                               return false;
+                       }
+
+                       if (target == typeof (IntPtr))
+                               return source == target;
+
+                       if (target == typeof (UIntPtr))
+                               return source == target;
+
+                       return false;
+               }
+
+               static bool CanConvertPrimitiveObjectToType (Object source, RuntimeType type)
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
\ No newline at end of file
index 5621065d8039a5fe20b1aa7c39892a419624a047..9a3404a271fae2a65d532a388bb9164e49808a41 100644 (file)
@@ -353,7 +353,7 @@ namespace System.Reflection.Emit
                                        }
                                }
                                if (binder == null)
-                                       binder = Binder.DefaultBinder;
+                                       binder = DefaultBinder;
                                return (ConstructorInfo) binder.SelectMethod (bindingAttr, match,
                                                                                                                          types, modifiers);
                        }
@@ -1192,46 +1192,10 @@ namespace System.Reflection.Emit
                {
                        check_created ();
 
-                       bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
-                       MethodInfo[] methods = GetMethodsByName (name, bindingAttr, ignoreCase, this);
-                       MethodInfo found = null;
-                       MethodBase[] match;
-                       int typesLen = (types != null) ? types.Length : 0;
-                       int count = 0;
-                       
-                       foreach (MethodInfo m in methods) {
-                               // Under MS.NET, Standard|HasThis matches Standard...
-                               if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
-                                       continue;
-                               found = m;
-                               count++;
-                       }
+                       if (types == null)
+                               return created.GetMethod (name, bindingAttr);
 
-                       if (count == 0)
-                               return null;
-                       
-                       if (count == 1 && typesLen == 0) 
-                               return found;
-
-                       match = new MethodBase [count];
-                       if (count == 1)
-                               match [0] = found;
-                       else {
-                               count = 0;
-                               foreach (MethodInfo m in methods) {
-                                       if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
-                                               continue;
-                                       match [count++] = m;
-                               }
-                       }
-                       
-                       if (types == null) 
-                               return (MethodInfo) Binder.FindMostDerivedMatch (match);
-
-                       if (binder == null)
-                               binder = Binder.DefaultBinder;
-                       
-                       return (MethodInfo)binder.SelectMethod (bindingAttr, match, types, modifiers);
+                       return created.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers);
                }
 
                public override Type GetNestedType (string name, BindingFlags bindingAttr)
diff --git a/mcs/class/corlib/System.Reflection/Binder.cs b/mcs/class/corlib/System.Reflection/Binder.cs
deleted file mode 100644 (file)
index 7c0f829..0000000
+++ /dev/null
@@ -1,1018 +0,0 @@
-// System.Reflection.Binder
-//
-// Authors:
-//     Sean MacIsaac (macisaac@ximian.com)
-//     Paolo Molaro (lupus@ximian.com)
-//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//     Marek Safar (marek.safar@gmail.com)
-//
-// (C) Ximian, Inc. 2001 - 2003
-// (c) Copyright 2004 Novell, Inc. (http://www.novell.com)
-// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Collections.Generic;
-
-namespace System.Reflection
-{
-       [ComVisible (true)]
-       [Serializable]
-       [ClassInterface(ClassInterfaceType.AutoDual)]
-       public abstract class Binder
-       {
-               protected Binder () {}
-
-               public abstract FieldInfo BindToField (BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture);
-               public abstract MethodBase BindToMethod (BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state);
-               public abstract object ChangeType (object value, Type type, CultureInfo culture);
-               public abstract void ReorderArgumentArray( ref object[] args, object state);
-               public abstract MethodBase SelectMethod (BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers);
-               public abstract PropertyInfo SelectProperty( BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers);
-
-               static readonly Binder default_binder = new Default ();
-
-               internal static Binder DefaultBinder {
-                       get {
-                               return default_binder;
-                       }
-               }
-               
-               internal void ConvertValues (object[] args, ParameterInfo[] pinfo, CultureInfo culture, bool exactMatch)
-               {
-                       if (args == null) {
-                               if (pinfo.Length == 0)
-                                       return;
-                               
-                               throw new TargetParameterCountException ();
-                       }
-
-                       if (pinfo.Length != args.Length)
-                               throw new TargetParameterCountException ();
-                       
-                       for (int i = 0; i < args.Length; ++i) {
-                               var arg = args [i];
-                               var pi = pinfo [i];
-                               if (arg == Type.Missing) {
-                                       args [i] = pi.DefaultValue;
-                                       continue;
-                               }
-
-                               args [i] = ConvertValue (arg, pi.ParameterType, culture, exactMatch);
-                       }
-               }
-
-               internal object ConvertValue (object value, Type type, CultureInfo culture, bool exactMatch)
-               {
-                       bool failed = false;
-                       var res = TryConvertToType (value, type, ref failed);
-                       if (!failed)
-                               return res;
-
-                       if (exactMatch || this == default_binder)
-                               throw new ArgumentException ("Object type " + value.GetType() + " cannot be converted to target type: " + type.FullName);
-
-                       return ChangeType (value, type, culture);
-               }
-
-               object TryConvertToType (object value, Type type, ref bool failed)
-               {
-                       if (type.IsInstanceOfType (value)) {
-                               return value;
-                       }
-
-                       if (type.IsByRef) {
-                       var elementType = type.GetElementType ();
-                       if (value == null || elementType.IsInstanceOfType (value)) {
-                                       return value;
-                               }
-                       }
-
-                       if (value == null)
-                               return value;
-
-                       if (type.IsEnum) {
-                               type = Enum.GetUnderlyingType (type);
-                               if (type == value.GetType ())
-                                       return value;
-                       }
-
-                       if (type.IsPrimitive) {
-                               var res = IsConvertibleToPrimitiveType (value, type);
-                               if (res != null)
-                                       return res;
-                       } else if (type.IsPointer) {
-                               var vtype = value.GetType ();
-                               if (vtype == typeof (IntPtr) || vtype == typeof (UIntPtr))
-                                       return value;
-                       }
-
-                       failed = true;
-                       return null;
-               }
-
-               // Binder uses some incompatible conversion rules. For example
-               // int value cannot be used with decimal parameter but in other
-               // ways it's more flexible than normal convertor, for example
-               // long value can be used with int based enum
-               static object IsConvertibleToPrimitiveType (object value, Type targetType)              
-               {
-                       var type = value.GetType ();
-                       if (type.IsEnum) {
-                               type = Enum.GetUnderlyingType (type);
-                               if (type == targetType)
-                                       return value;
-                       }
-
-                       var from = Type.GetTypeCode (type);
-                       var to = Type.GetTypeCode (targetType);
-
-                       switch (to) {
-                               case TypeCode.Char:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (Char) (Byte) value;
-                                               case TypeCode.UInt16:
-                                                       return value;
-                                       }
-                                       break;
-                               case TypeCode.Int16:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (Int16) (Byte) value;
-                                               case TypeCode.SByte:
-                                                       return (Int16) (SByte) value;                                           
-                                       }
-                                       break;
-                               case TypeCode.UInt16:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (UInt16) (Byte) value;
-                                               case TypeCode.Char:
-                                                       return value;
-                                       }
-                                       break;
-                               case TypeCode.Int32:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (Int32) (Byte) value;
-                                               case TypeCode.SByte:
-                                                       return (Int32) (SByte) value;
-                                               case TypeCode.Char:
-                                                       return (Int32) (Char) value;
-                                               case TypeCode.Int16:
-                                                       return (Int32) (Int16) value;
-                                               case TypeCode.UInt16:
-                                                       return (Int32) (UInt16) value;
-                                       }
-                                       break;
-                               case TypeCode.UInt32:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (UInt32) (Byte) value;
-                                               case TypeCode.Char:
-                                                       return (UInt32) (Char) value;
-                                               case TypeCode.UInt16:
-                                                       return (UInt32) (UInt16) value;
-                                       }
-                                       break;
-                               case TypeCode.Int64:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (Int64) (Byte) value;
-                                               case TypeCode.SByte:
-                                                       return (Int64) (SByte) value;                                                   
-                                               case TypeCode.Int16:
-                                                       return (Int64) (Int16) value;
-                                               case TypeCode.Char:
-                                                       return (Int64) (Char) value;
-                                               case TypeCode.UInt16:
-                                                       return (Int64) (UInt16) value;
-                                               case TypeCode.Int32:
-                                                       return (Int64) (Int32) value;
-                                               case TypeCode.UInt32:
-                                                       return (Int64) (UInt32) value;
-                                       }
-                                       break;
-                               case TypeCode.UInt64:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (UInt64) (Byte) value;
-                                               case TypeCode.Char:
-                                                       return (UInt64) (Char) value;
-                                               case TypeCode.UInt16:
-                                                       return (UInt64) (UInt16) value;
-                                               case TypeCode.UInt32:
-                                                       return (UInt64) (UInt32) value;
-                                       }
-                                       break;
-                               case TypeCode.Single:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (Single) (Byte) value;
-                                               case TypeCode.SByte:
-                                                       return (Single) (SByte) value;
-                                               case TypeCode.Int16:
-                                                       return (Single) (Int16) value;
-                                               case TypeCode.Char:
-                                                       return (Single) (Char) value;
-                                               case TypeCode.UInt16:
-                                                       return (Single) (UInt16) value;
-                                               case TypeCode.Int32:
-                                                       return (Single) (Int32) value;
-                                               case TypeCode.UInt32:
-                                                       return (Single) (UInt32) value;
-                                               case TypeCode.Int64:
-                                                       return (Single) (Int64) value;
-                                               case TypeCode.UInt64:
-                                                       return (Single) (UInt64) value;
-                                       }
-                                       break;
-                               case TypeCode.Double:
-                                       switch (from) {
-                                               case TypeCode.Byte:
-                                                       return (Double) (Byte) value;
-                                               case TypeCode.SByte:
-                                                       return (Double) (SByte) value;
-                                               case TypeCode.Char:
-                                                       return (Double) (Char) value;
-                                               case TypeCode.Int16:
-                                                       return (Double) (Int16) value;
-                                               case TypeCode.UInt16:
-                                                       return (Double) (UInt16) value;
-                                               case TypeCode.Int32:
-                                                       return (Double) (Int32) value;
-                                               case TypeCode.UInt32:
-                                                       return (Double) (UInt32) value;
-                                               case TypeCode.Int64:
-                                                       return (Double) (Int64) value;
-                                               case TypeCode.UInt64:
-                                                       return (Double) (UInt64) value;
-                                               case TypeCode.Single:
-                                                       return (Double) (Single) value;
-                                       }
-                                       break;
-                       }
-
-                       // Everything else is rejected
-                       return null;
-               }
-
-               internal static int GetDerivedLevel (Type type) 
-               {
-                       Type searchType = type;
-                       int level = 1;
-
-                       while (searchType.BaseType != null) 
-                       {
-                               level++;
-                               searchType = searchType.BaseType;
-                       }
-
-                       return level;
-               }
-
-               internal static MethodBase FindMostDerivedMatch (MethodBase [] match) 
-               {
-                       int highLevel = 0;
-                       int matchId = -1;
-                       int count = match.Length;
-
-                       for (int current = 0; current < count; current++) 
-                       {
-                               MethodBase m = match [current];
-                               int level = GetDerivedLevel (m.DeclaringType);
-                               if (level == highLevel)
-                                       throw new AmbiguousMatchException ();
-                               // If the argument types differ we
-                               // have an ambigous match, as well
-                               if (matchId >= 0) {
-                                       ParameterInfo[] p1 = m.GetParametersInternal ();
-                                       ParameterInfo[] p2 = match [matchId].GetParametersInternal ();
-                                       bool equal = true;
-
-                                       if (p1.Length != p2.Length)
-                                               equal = false;
-                                       else {
-                                               int i;
-
-                                               for (i = 0; i < p1.Length; ++i) {
-                                                       if (p1 [i].ParameterType != p2 [i].ParameterType) {
-                                                               equal = false;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-
-                                       if (!equal)
-                                               throw new AmbiguousMatchException ();
-                               }
-
-                               if (level > highLevel) 
-                               {
-                                       highLevel = level;
-                                       matchId = current;
-                               }
-                       }
-
-                       return match[matchId];
-               }
-
-               internal sealed class Default : Binder {
-                       public override FieldInfo BindToField (BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture) 
-                       {
-                               if (match == null)
-                                       throw new ArgumentNullException ("match");
-                               foreach (FieldInfo f in match) {
-                                       if (check_type (value.GetType (), f.FieldType))
-                                               return f;
-                               }
-                               return null;
-                       }
-
-                       public override MethodBase BindToMethod (BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state)
-                       {
-                               Type[] types;
-                               if (args == null)
-                                       types = Type.EmptyTypes;
-                               else {
-                                       types = new Type [args.Length];
-                                       for (int i = 0; i < args.Length; ++i) {
-                                               if (args [i] != null)
-                                                       types [i] = args [i].GetType ();
-                                       }
-                               }
-
-                               MethodBase selected = null;
-                               if (names != null) {
-                                       foreach (var m in match) {
-                                               var parameters = m.GetParametersInternal ();
-                                               int i;
-
-                                               /*
-                                                * Find the corresponding parameter for each parameter name,
-                                                * reorder types/modifiers array during the search.
-                                                */
-                                               Type[] newTypes = new Type [types.Length];
-                                               Array.FastCopy (types, 0, newTypes, 0, types.Length);
-
-                                               ParameterModifier[] newModifiers = null;
-                                               if (modifiers != null) {
-                                                       newModifiers = new ParameterModifier [modifiers.Length];
-                                                       Array.FastCopy (modifiers, 0, newModifiers, 0, modifiers.Length);
-                                               }
-
-                                               for (i = 0; i < names.Length; ++i) {
-                                                       /* Find the corresponding parameter */
-                                                       int nindex = -1;
-                                                       for (int j = 0; j < parameters.Length; ++j) {
-                                                               if (parameters [j].Name == names [i]) {
-                                                                       nindex = j;
-                                                                       break;
-                                                               }
-                                                       }
-                                                       if (nindex == -1)
-                                                               break;
-                                                       if (i < newTypes.Length && nindex < types.Length)
-                                                               newTypes [i] = types [nindex];
-                                                       if (modifiers != null && i < newModifiers.Length && nindex < modifiers.Length)
-                                                               newModifiers [i] = modifiers [nindex];
-                                               }
-                                               if (i < names.Length)
-                                                       continue;
-
-                                               selected = SelectMethod (bindingAttr, new MethodBase [] { m }, newTypes, newModifiers, true, ref args);
-                                               if (selected != null)
-                                                       break;
-                                       }
-                               } else {
-                                       selected = SelectMethod (bindingAttr, match, types, modifiers, true, ref args);
-                               }
-
-                               state = null;
-                               if (selected != null && names != null)
-                                       ReorderParameters (names, ref args, selected);
-
-                               if (selected != null) {
-                                       if (args == null)
-                                               args = EmptyArray<object>.Value;
-       
-                                       AdjustArguments (selected, ref args);
-                               }
-
-                               return selected;
-                       }
-
-                       // probably belongs in ReorderArgumentArray
-                       static void AdjustArguments (MethodBase selected, ref object [] args)
-                       {
-                               var parameters = selected.GetParametersInternal ();
-                               var parameters_length = parameters.Length;
-                               if (parameters_length == 0)
-                                       return;
-
-                               var last_parameter = parameters [parameters.Length - 1];
-                               Type last_parameter_type = last_parameter.ParameterType;
-                               if (!Attribute.IsDefined (last_parameter, typeof (ParamArrayAttribute)))
-                                       return;
-
-                               var args_length = args.Length;
-                               var param_args_count = args_length + 1 - parameters_length;
-                               var first_vararg_index = args_length - param_args_count;
-                               if (first_vararg_index < args_length) {
-                                       var first_vararg = args [first_vararg_index];
-                                       if (first_vararg != null && first_vararg.GetType () == last_parameter_type)
-                                               return;
-                               }
-                               
-                               var params_args = Array.CreateInstance (last_parameter_type.GetElementType (), param_args_count);
-                               for (int i = 0; i < param_args_count; i++)
-                                       params_args.SetValue (args [first_vararg_index + i], i);
-
-                               var adjusted = new object [parameters_length];
-                               Array.Copy (args, adjusted, parameters_length - 1);
-                               
-                               adjusted [adjusted.Length - 1] = params_args;
-                               args = adjusted;
-                       }
-
-                       void ReorderParameters (string [] names, ref object [] args, MethodBase selected)
-                       {
-                               object [] newArgs = new object [args.Length];
-                               Array.Copy (args, newArgs, args.Length);
-                               ParameterInfo [] plist = selected.GetParametersInternal ();
-                               for (int n = 0; n < names.Length; n++)
-                                       for (int p = 0; p < plist.Length; p++) {
-                                               if (names [n] == plist [p].Name) {
-                                                       newArgs [p] = args [n];
-                                                       break;
-                                               }
-                                       }
-                               Array.Copy (newArgs, args, args.Length);
-                       }
-                       
-                       public override object ChangeType (object value, Type type, CultureInfo culture)
-                       {
-                               throw new NotSupportedException ();
-                       }
-
-                       [MonoTODO ("This method does not do anything in Mono")]
-                       public override void ReorderArgumentArray (ref object[] args, object state)
-                       {
-                               //do nothing until we support named arguments
-                               //throw new NotImplementedException ();
-                       }
-
-                       private static bool check_type (Type from, Type to) {
-                               if (from == to)
-                                       return true;
-
-                               if (from == null)
-                                       return true;
-
-                               if (to.IsByRef != from.IsByRef)
-                                       return false;
-
-                               if (to.IsInterface)
-                                       return to.IsAssignableFrom (from);
-
-                               if (to.IsEnum) {
-                                       to = Enum.GetUnderlyingType (to);
-                                       if (from == to)
-                                               return true;
-                               }
-
-                               if (to.IsGenericType && to.GetGenericTypeDefinition () == typeof (Nullable<>) && to.GetGenericArguments ()[0] == from)
-                                       return true;
-
-                               TypeCode fromt = Type.GetTypeCode (from);
-                               TypeCode tot = Type.GetTypeCode (to);
-
-                               switch (fromt) {
-                               case TypeCode.Char:
-                                       switch (tot) {
-                                       case TypeCode.UInt16:
-                                       case TypeCode.UInt32:
-                                       case TypeCode.Int32:
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object);
-                               case TypeCode.Byte:
-                                       switch (tot) {
-                                       case TypeCode.Char:
-                                       case TypeCode.UInt16:
-                                       case TypeCode.Int16:
-                                       case TypeCode.UInt32:
-                                       case TypeCode.Int32:
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
-                               case TypeCode.SByte:
-                                       switch (tot) {
-                                       case TypeCode.Int16:
-                                       case TypeCode.Int32:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
-                               case TypeCode.UInt16:
-                                       switch (tot) {
-                                       case TypeCode.UInt32:
-                                       case TypeCode.Int32:
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
-                               case TypeCode.Int16:
-                                       switch (tot) {
-                                       case TypeCode.Int32:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
-                               case TypeCode.UInt32:
-                                       switch (tot) {
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
-                               case TypeCode.Int32:
-                                       switch (tot) {
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
-                               case TypeCode.UInt64:
-                               case TypeCode.Int64:
-                                       switch (tot) {
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return true;
-                                       }
-                                       return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
-                               case TypeCode.Single:
-                                       return tot == TypeCode.Double || to == typeof (object);
-                               default:
-                                       /* TODO: handle valuetype -> byref */
-                                       if (to == typeof (object) && from.IsValueType)
-                                               return true;
-                                       if (to.IsPointer && from == typeof (IntPtr))
-                                               return true;
-
-                                       return to.IsAssignableFrom (from);
-                               }
-                       }
-
-                       private static bool check_arguments (Type[] types, ParameterInfo[] args, bool allowByRefMatch) {
-                               for (int i = 0; i < types.Length; ++i) {
-                                       bool match = check_type (types [i], args [i].ParameterType);
-                                       if (!match && allowByRefMatch) {
-                                               Type param_type = args [i].ParameterType;
-                                               if (param_type.IsByRef)
-                                                       match = check_type (types [i], param_type.GetElementType ());
-                                       }
-                                       if (!match)
-                                               return false;
-                               }
-                               return true;
-                       }
-
-                       public override MethodBase SelectMethod (BindingFlags bindingAttr, MethodBase [] match, Type [] types, ParameterModifier [] modifiers)
-                       {
-                               object[] args = null;
-                               return SelectMethod (bindingAttr, match, types, modifiers, false, ref args);
-                       }
-
-                       MethodBase SelectMethod (BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers, bool allowByRefMatch, ref object[] arguments)
-                       {
-                               MethodBase m;
-                               int i, j;
-
-                               if (match == null)
-                                       throw new ArgumentNullException ("match");
-
-                               /* first look for an exact match... */
-                               MethodBase exact_match = null;
-                               for (i = 0; i < match.Length; ++i) {
-                                       m = match [i];
-                                       if (m.GetParametersCount () != types.Length)
-                                               continue;
-
-                                       ParameterInfo[] args = m.GetParametersInternal ();
-                                       for (j = 0; j < types.Length; ++j) {
-                                               if (types [j] != args [j].ParameterType)
-                                                       break;
-                                       }
-                                       if (j == types.Length) {
-                                               if (exact_match != null) {
-                                                       exact_match = null;
-                                                       break;
-                                               } else {
-                                                       exact_match = m;
-                                               }
-                                       }
-                               }
-                               if (exact_match != null)
-                                       return exact_match;
-
-                               /* Try methods with ParamArray attribute */
-                               if (arguments != null) {
-                                       for (i = 0; i < match.Length; ++i) {
-                                               m = match [i];
-
-                                               var count = m.GetParametersCount ();
-                                               if (count == 0 || count > types.Length + 1)
-                                                       continue;
-
-                                               var pi = m.GetParametersInternal ();
-                                               if (!Attribute.IsDefined (pi [pi.Length - 1], typeof (ParamArrayAttribute)))
-                                                       continue;
-
-                                               var elementType = pi [pi.Length - 1].ParameterType.GetElementType ();
-                                               for (j = 0; j < types.Length; ++j) {
-                                                       if (j < (pi.Length - 1) && types [j] != pi [j].ParameterType)
-                                                               break;
-                                                       
-                                                       if (j >= (pi.Length - 1) && types [j] != elementType) 
-                                                               break;
-                                               }
-
-                                               if (j == types.Length)
-                                                       return m;
-                                       }
-                               }
-
-                               if ((bindingAttr & BindingFlags.ExactBinding) != 0)
-                                       return null;
-
-                               MethodBase result = null;
-                               ParameterInfo[] result_pi = null;
-                               for (i = 0; i < match.Length; ++i) {
-                                       m = match [i];
-                                       var pi = m.GetParametersInternal ();
-                                       var full_pi = pi;
-                                       if (pi.Length != types.Length) {
-                                               if ((bindingAttr & BindingFlags.OptionalParamBinding) == 0)
-                                                       continue;
-
-                                               List<ParameterInfo> pi_reduced = null;
-                                               for (var ii = pi.Length - 1; ii >= 0; --ii) {
-                                                       if ((pi [ii].Attributes & ParameterAttributes.HasDefault) == 0)
-                                                               break;
-
-                                                       if (pi_reduced == null) {
-                                                               pi_reduced = new List<ParameterInfo> (pi);
-                                                       }
-
-                                                       pi_reduced.RemoveAt (ii);
-                                               }
-
-                                               if (pi_reduced == null || pi_reduced.Count != types.Length)
-                                                       continue;
-
-                                               pi = pi_reduced.ToArray ();
-                                       }
-
-                                       if (!check_arguments (types, pi, allowByRefMatch))
-                                               continue;
-
-                                       if (result != null) {
-                                               result = GetBetterMethod (result, m, types);
-                                               if (result != m)
-                                                       continue;
-                                       }
-
-                                       result = m;
-                                       result_pi = full_pi;
-                               }
-
-                               if (result != null) {
-                                       i = arguments == null ? 0 : arguments.Length;
-                                       Array.Resize (ref arguments, result_pi.Length);
-                                       for (; i < arguments.Length; ++i)
-                                               arguments [i] = result_pi [i].DefaultValue;
-
-                                       return result;
-                               }
-
-                               if (arguments == null || types.Length != arguments.Length)
-                                       return null;
-
-                               // Xamarin-5278: try with parameters that are COM objects
-                               // REVIEW: do we also need to implement best method match?
-                               for (i = 0; i < match.Length; ++i) {
-                                       m = match [i];
-                                       ParameterInfo[] methodArgs = m.GetParametersInternal ();
-                                       if (methodArgs.Length != types.Length)
-                                               continue;
-                                       for (j = 0; j < types.Length; ++j) {
-                                               var requiredType = methodArgs [j].ParameterType;
-                                               if (types [j] == requiredType)
-                                                       continue;
-#if !MOBILE
-                                               if (types [j] == typeof (__ComObject) && requiredType.IsInterface) {
-                                                       var iface = Marshal.GetComInterfaceForObject (arguments [j], requiredType);
-                                                       if (iface != IntPtr.Zero) {
-                                                               // the COM object implements the desired interface
-                                                               Marshal.Release (iface);
-                                                               continue;
-                                                       }
-                                               }
-#endif
-                                               break;
-                                       }
-
-                                       if (j == types.Length)
-                                               return m;
-                               }
-                               return null;
-                       }
-
-                       MethodBase GetBetterMethod (MethodBase m1, MethodBase m2, Type [] types)
-                       {
-                               ParameterInfo [] pl1 = m1.GetParametersInternal ();
-                               ParameterInfo [] pl2 = m2.GetParametersInternal ();
-                               int prev = 0;
-                               for (int i = 0; i < pl1.Length; i++) {
-                                       int cmp = CompareCloserType (pl1 [i].ParameterType, pl2 [i].ParameterType);
-                                       if (cmp != 0 && prev != 0 && prev != cmp)
-                                               throw new AmbiguousMatchException ();
-                                       if (cmp != 0)
-                                               prev = cmp;
-                               }
-                               if (prev != 0)
-                                       return prev > 0 ? m2 : m1;
-
-                               Type dt1 = m1.DeclaringType;
-                               Type dt2 = m2.DeclaringType;
-                               if (dt1 != dt2) {
-                                       if (dt1.IsSubclassOf(dt2))
-                                               return m1;
-                                       if (dt2.IsSubclassOf(dt1))
-                                               return m2;
-                               }
-
-                               bool va1 = (m1.CallingConvention & CallingConventions.VarArgs) != 0;
-                               bool va2 = (m2.CallingConvention & CallingConventions.VarArgs) != 0;
-                               if (va1 && !va2)
-                                       return m2;
-                               if (va2 && !va1)
-                                       return m1;
-
-                               throw new AmbiguousMatchException ();
-                       }
-
-                       int CompareCloserType (Type t1, Type t2)
-                       {
-                               if (t1 == t2)
-                                       return 0;
-                               if (t1.IsGenericParameter && !t2.IsGenericParameter)
-                                       return 1; // t2
-                               if (!t1.IsGenericParameter && t2.IsGenericParameter)
-                                       return -1; // t1
-                               if (t1.HasElementType && t2.HasElementType)
-                                       return CompareCloserType (
-                                               t1.GetElementType (),
-                                               t2.GetElementType ());
-
-                               if (t1.IsSubclassOf (t2))
-                                       return -1; // t1
-                               if (t2.IsSubclassOf (t1))
-                                       return 1; // t2
-
-                               if (t1.IsInterface && Array.IndexOf (t2.GetInterfaces (), t1) >= 0)
-                                       return 1; // t2
-                               if (t2.IsInterface && Array.IndexOf (t1.GetInterfaces (), t2) >= 0)
-                                       return -1; // t1
-
-                               // What kind of cases could reach here?
-                               return 0;
-                       }
-
-                       public override PropertyInfo SelectProperty (BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers)
-                       {
-                               if (match == null || match.Length == 0)
-                                       throw new ArgumentException ("No properties provided", "match");
-
-                               bool haveRet = (returnType != null);
-                               int idxlen = (indexes != null) ? indexes.Length : -1;
-                               PropertyInfo result = null;
-                               int i;
-                               int best_score = Int32.MaxValue - 1;
-                               int fail_score = Int32.MaxValue;
-                               int level = 0;
-                               
-                               for (i = match.Length - 1; i >= 0; i--) {
-                                       PropertyInfo p = match [i];
-                                       ParameterInfo[] args = p.GetIndexParameters ();
-                                       if (idxlen >= 0 && idxlen != args.Length)
-                                               continue;
-
-                                       if (haveRet && p.PropertyType != returnType)
-                                               continue;
-
-                                       int score = Int32.MaxValue - 1;
-                                       if (idxlen > 0) {
-                                               score = check_arguments_with_score (indexes, args);
-                                               if (score == -1)
-                                                       continue;
-                                       }
-
-                                       int new_level = GetDerivedLevel (p.DeclaringType);
-                                       if (result != null) {
-                                               if (best_score < score)
-                                                       continue;
-
-                                               if (best_score == score) {
-                                                       if (level == new_level) {
-                                                               // Keep searching. May be there's something
-                                                               // better for us.
-                                                               fail_score = score;
-                                                               continue;
-                                                       }
-
-                                                       if (level > new_level)
-                                                               continue;
-                                               }
-                                       }
-
-                                       result = p;
-                                       best_score = score;
-                                       level = new_level;
-                               }
-
-                               if (fail_score <= best_score)
-                                       throw new AmbiguousMatchException ();
-
-                               return result;
-                       }
-
-                       static int check_arguments_with_score (Type [] types, ParameterInfo [] args)
-                       {
-                               int worst = -1;
-
-                               for (int i = 0; i < types.Length; ++i) {
-                                       int res = check_type_with_score (types [i], args [i].ParameterType);
-                                       if (res == -1)
-                                               return -1;
-
-                                       if (worst < res)
-                                               worst = res;
-                               }
-
-                               return worst;
-                       }
-
-                       // 0 -> same type or null and !valuetype
-                       // 1 -> to == Enum
-                       // 2 -> value type that don't lose data
-                       // 3 -> to == IsAssignableFrom
-                       // 4 -> to == object
-                       static int check_type_with_score (Type from, Type to)
-                       {
-                               if (from == null)
-                                       return to.IsValueType ? -1 : 0;
-
-                               if (from == to)
-                                       return 0;
-
-                               if (to == typeof (object))
-                                       return 4;
-
-                               TypeCode fromt = Type.GetTypeCode (from);
-                               TypeCode tot = Type.GetTypeCode (to);
-
-                               switch (fromt) {
-                               case TypeCode.Char:
-                                       switch (tot) {
-                                       case TypeCode.UInt16:
-                                               return 0;
-
-                                       case TypeCode.UInt32:
-                                       case TypeCode.Int32:
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return -1;
-                               case TypeCode.Byte:
-                                       switch (tot) {
-                                       case TypeCode.Char:
-                                       case TypeCode.UInt16:
-                                       case TypeCode.Int16:
-                                       case TypeCode.UInt32:
-                                       case TypeCode.Int32:
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return (from.IsEnum && to == typeof (Enum)) ? 1 : -1;
-                               case TypeCode.SByte:
-                                       switch (tot) {
-                                       case TypeCode.Int16:
-                                       case TypeCode.Int32:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return (from.IsEnum && to == typeof (Enum)) ? 1 : -1;
-                               case TypeCode.UInt16:
-                                       switch (tot) {
-                                       case TypeCode.UInt32:
-                                       case TypeCode.Int32:
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return (from.IsEnum && to == typeof (Enum)) ? 1 : -1;
-                               case TypeCode.Int16:
-                                       switch (tot) {
-                                       case TypeCode.Int32:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return (from.IsEnum && to == typeof (Enum)) ? 1 : -1;
-                               case TypeCode.UInt32:
-                                       switch (tot) {
-                                       case TypeCode.UInt64:
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return (from.IsEnum && to == typeof (Enum)) ? 1 : -1;
-                               case TypeCode.Int32:
-                                       switch (tot) {
-                                       case TypeCode.Int64:
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return (from.IsEnum && to == typeof (Enum)) ? 1 : -1;
-                               case TypeCode.UInt64:
-                               case TypeCode.Int64:
-                                       switch (tot) {
-                                       case TypeCode.Single:
-                                       case TypeCode.Double:
-                                               return 2;
-                                       }
-                                       return (from.IsEnum && to == typeof (Enum)) ? 1 : -1;
-                               case TypeCode.Single:
-                                       return tot == TypeCode.Double ? 2 : -1;
-                               default:
-                                       return (to.IsAssignableFrom (from)) ? 3 : -1;
-                               }
-                       }
-               }
-       }
-}
-
index c91c4be203f28c1b95d38b42d98606e533ba8ae9..ff04255d41671430ed36ec602c5a23bf6f77ad54 100644 (file)
@@ -98,6 +98,11 @@ namespace System.Reflection {
                        return GetParameters ();
                }
 
+               internal ParameterInfo[] GetParametersNoCopy ()
+               {
+                       return GetParametersInternal ();
+               }
+
                internal virtual int GetParametersCount ()
                {
                        // Override me
index e374e5176621d48595264ef32eb58ca28504d5e9..d02cdcdc19efa68e7410902f45b131f4a423bc70 100644 (file)
@@ -146,10 +146,11 @@ namespace System.Reflection {
                        if (IsLiteral)
                                throw new FieldAccessException ("Cannot set a constant field");
                        if (binder == null)
-                               binder = Binder.DefaultBinder;
+                               binder = Type.DefaultBinder;
                        CheckGeneric ();
                        if (val != null) {
-                               val = binder.ConvertValue (val, FieldType, culture, (invokeAttr & BindingFlags.ExactBinding) != 0);
+                               RuntimeType fieldType = (RuntimeType) FieldType;
+                               val = fieldType.CheckValue (val, binder, culture, invokeAttr);
                        }
                        SetValueInternal (this, obj, val);
                }
index 7ee415bec324966320f960b8e761673dc7ec4af7..eae75db951b9f46f069c0ee4e486b8dfb620569e 100644 (file)
@@ -202,11 +202,11 @@ namespace System.Reflection {
                public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
                {
                        if (binder == null)
-                               binder = Binder.DefaultBinder;
+                               binder = Type.DefaultBinder;
 
                        /*Avoid allocating an array every time*/
                        ParameterInfo[] pinfo = GetParametersInternal ();
-                       binder.ConvertValues (parameters, pinfo, culture, (invokeAttr & BindingFlags.ExactBinding) != 0);
+                       ConvertValues (binder, parameters, pinfo, culture, invokeAttr);
 
 #if !NET_2_1
                        if (SecurityManager.SecurityEnabled) {
@@ -243,6 +243,31 @@ namespace System.Reflection {
                        return o;
                }
 
+               internal static void ConvertValues (Binder binder, object[] args, ParameterInfo[] pinfo, CultureInfo culture, BindingFlags invokeAttr)
+               {
+                       if (args == null) {
+                               if (pinfo.Length == 0)
+                                       return;
+
+                               throw new TargetParameterCountException ();
+                       }
+
+                       if (pinfo.Length != args.Length)
+                               throw new TargetParameterCountException ();
+
+                       for (int i = 0; i < args.Length; ++i) {
+                               var arg = args [i];
+                               var pi = pinfo [i];
+                               if (arg == Type.Missing) {
+                                       args [i] = pi.DefaultValue;
+                                       continue;
+                               }
+
+                               var rt = (RuntimeType) pi.ParameterType;
+                               args [i] = rt.CheckValue (arg, binder, culture, invokeAttr);
+                       }
+               }
+
                public override RuntimeMethodHandle MethodHandle { 
                        get {
                                return new RuntimeMethodHandle (mhandle);
@@ -501,11 +526,11 @@ namespace System.Reflection {
                object DoInvoke (object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) 
                {
                        if (binder == null)
-                               binder = Binder.DefaultBinder;
+                               binder = Type.DefaultBinder;
 
                        ParameterInfo[] pinfo = MonoMethodInfo.GetParametersInfo (mhandle, this);
 
-                       binder.ConvertValues (parameters, pinfo, culture, (invokeAttr & BindingFlags.ExactBinding) != 0);
+                       MonoMethod.ConvertValues (binder, parameters, pinfo, culture, invokeAttr);
 
 #if !NET_2_1
                        if (SecurityManager.SecurityEnabled) {
index 1e6d26c92fc389e93b824987c148cde8c77e3253..89506851b42d4e3755ce2b9a49979582ece64a23 100644 (file)
@@ -221,7 +221,7 @@ namespace System
 
                public static object CreateInstance (Type type, object [] args, object [] activationAttributes)
                {
-                       return CreateInstance (type, BindingFlags.Default, Binder.DefaultBinder, args, null, activationAttributes);
+                       return CreateInstance (type, BindingFlags.Default, Type.DefaultBinder, args, null, activationAttributes);
                }
 
                public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
@@ -243,18 +243,24 @@ namespace System
                        if ((bindingAttr & _accessFlags) == 0)
                                bindingAttr |= BindingFlags.Public | BindingFlags.Instance;
 
+                       if (args == null)
+                               args = EmptyArray<object>.Value;
+
+                       if (args.Length == 0 && (bindingAttr & (BindingFlags.Public | BindingFlags.Instance)) == (BindingFlags.Public | BindingFlags.Instance) && type.IsValueType) {
+                               return CreateInstanceInternal (type);
+                       }
+
+                       var methods = type.GetConstructors (bindingAttr);
+                       if (methods.Length == 0)
+                               throw new MissingMethodException (Environment.GetResourceString("MissingConstructor_Name", type.FullName));
+
                        if (binder == null)
-                               binder = Binder.DefaultBinder;
+                               binder = Type.DefaultBinder;
 
                        object state;
-                       ConstructorInfo ctor = (ConstructorInfo) binder.BindToMethod (bindingAttr, type.GetConstructors (bindingAttr), ref args, null, null, null, out state);
+                       ConstructorInfo ctor = (ConstructorInfo) binder.BindToMethod (bindingAttr, methods, ref args, null, null, null, out state);
 
                        if (ctor == null) {
-                               // Not sure about this
-                               if (type.IsValueType && (args == null || args.Length == 0)) {
-                                       return CreateInstanceInternal (type);
-                               }
-
                                var sb = new StringBuilder ();
                                if (args != null) {
                                        for (int i = 0; i < args.Length; i++) {
index d415645f5e2039d2016bef7d664b39f53a4ed2d3..fb50b4b26cb69cfd4b10048b84a27a69e799e1a5 100644 (file)
@@ -39,6 +39,7 @@ using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
 using System.Runtime.Serialization;
 using System.Security;
+using System.Diagnostics.Contracts;
 
 namespace System
 {
@@ -61,6 +62,448 @@ namespace System
                                return IsArrayImpl () && GetArrayRank () == 1;
                        }
                }
+
+               internal Object CheckValue (Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
+               {
+                       bool failed = false;
+                       var res = TryConvertToType (value, ref failed);
+                       if (!failed)
+                               return res;
+
+                       if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
+                               throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
+
+                       if (binder != null && binder != Type.DefaultBinder)
+                               return binder.ChangeType (value, this, culture);
+
+                       throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
+               }
+
+               object TryConvertToType (object value, ref bool failed)
+               {
+                       if (IsInstanceOfType (value)) {
+                               return value;
+                       }
+
+                       if (IsByRef) {
+                               var elementType = GetElementType ();
+                               if (value == null || elementType.IsInstanceOfType (value)) {
+                                       return value;
+                               }
+                       }
+
+                       if (value == null)
+                               return value;
+
+                       if (IsEnum) {
+                               var type = Enum.GetUnderlyingType (this);
+                               if (type == value.GetType ())
+                                       return value;
+                               var res = IsConvertibleToPrimitiveType (value, this);
+                               if (res != null)
+                                       return res;
+                       } else if (IsPrimitive) {
+                               var res = IsConvertibleToPrimitiveType (value, this);
+                               if (res != null)
+                                       return res;
+                       } else if (IsPointer) {
+                               var vtype = value.GetType ();
+                               if (vtype == typeof (IntPtr) || vtype == typeof (UIntPtr))
+                                       return value;
+                       }
+
+                       failed = true;
+                       return null;
+               }
+
+               // Binder uses some incompatible conversion rules. For example
+               // int value cannot be used with decimal parameter but in other
+               // ways it's more flexible than normal convertor, for example
+               // long value can be used with int based enum
+               static object IsConvertibleToPrimitiveType (object value, Type targetType)
+               {
+                       var type = value.GetType ();
+                       if (type.IsEnum) {
+                               type = Enum.GetUnderlyingType (type);
+                               if (type == targetType)
+                                       return value;
+                       }
+
+                       var from = Type.GetTypeCode (type);
+                       var to = Type.GetTypeCode (targetType);
+
+                       switch (to) {
+                               case TypeCode.Char:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (Char) (Byte) value;
+                                               case TypeCode.UInt16:
+                                                       return value;
+                                       }
+                                       break;
+                               case TypeCode.Int16:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (Int16) (Byte) value;
+                                               case TypeCode.SByte:
+                                                       return (Int16) (SByte) value;
+                                       }
+                                       break;
+                               case TypeCode.UInt16:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (UInt16) (Byte) value;
+                                               case TypeCode.Char:
+                                                       return value;
+                                       }
+                                       break;
+                               case TypeCode.Int32:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (Int32) (Byte) value;
+                                               case TypeCode.SByte:
+                                                       return (Int32) (SByte) value;
+                                               case TypeCode.Char:
+                                                       return (Int32) (Char) value;
+                                               case TypeCode.Int16:
+                                                       return (Int32) (Int16) value;
+                                               case TypeCode.UInt16:
+                                                       return (Int32) (UInt16) value;
+                                       }
+                                       break;
+                               case TypeCode.UInt32:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (UInt32) (Byte) value;
+                                               case TypeCode.Char:
+                                                       return (UInt32) (Char) value;
+                                               case TypeCode.UInt16:
+                                                       return (UInt32) (UInt16) value;
+                                       }
+                                       break;
+                               case TypeCode.Int64:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (Int64) (Byte) value;
+                                               case TypeCode.SByte:
+                                                       return (Int64) (SByte) value;
+                                               case TypeCode.Int16:
+                                                       return (Int64) (Int16) value;
+                                               case TypeCode.Char:
+                                                       return (Int64) (Char) value;
+                                               case TypeCode.UInt16:
+                                                       return (Int64) (UInt16) value;
+                                               case TypeCode.Int32:
+                                                       return (Int64) (Int32) value;
+                                               case TypeCode.UInt32:
+                                                       return (Int64) (UInt32) value;
+                                       }
+                                       break;
+                               case TypeCode.UInt64:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (UInt64) (Byte) value;
+                                               case TypeCode.Char:
+                                                       return (UInt64) (Char) value;
+                                               case TypeCode.UInt16:
+                                                       return (UInt64) (UInt16) value;
+                                               case TypeCode.UInt32:
+                                                       return (UInt64) (UInt32) value;
+                                       }
+                                       break;
+                               case TypeCode.Single:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (Single) (Byte) value;
+                                               case TypeCode.SByte:
+                                                       return (Single) (SByte) value;
+                                               case TypeCode.Int16:
+                                                       return (Single) (Int16) value;
+                                               case TypeCode.Char:
+                                                       return (Single) (Char) value;
+                                               case TypeCode.UInt16:
+                                                       return (Single) (UInt16) value;
+                                               case TypeCode.Int32:
+                                                       return (Single) (Int32) value;
+                                               case TypeCode.UInt32:
+                                                       return (Single) (UInt32) value;
+                                               case TypeCode.Int64:
+                                                       return (Single) (Int64) value;
+                                               case TypeCode.UInt64:
+                                                       return (Single) (UInt64) value;
+                                       }
+                                       break;
+                               case TypeCode.Double:
+                                       switch (from) {
+                                               case TypeCode.Byte:
+                                                       return (Double) (Byte) value;
+                                               case TypeCode.SByte:
+                                                       return (Double) (SByte) value;
+                                               case TypeCode.Char:
+                                                       return (Double) (Char) value;
+                                               case TypeCode.Int16:
+                                                       return (Double) (Int16) value;
+                                               case TypeCode.UInt16:
+                                                       return (Double) (UInt16) value;
+                                               case TypeCode.Int32:
+                                                       return (Double) (Int32) value;
+                                               case TypeCode.UInt32:
+                                                       return (Double) (UInt32) value;
+                                               case TypeCode.Int64:
+                                                       return (Double) (Int64) value;
+                                               case TypeCode.UInt64:
+                                                       return (Double) (UInt64) value;
+                                               case TypeCode.Single:
+                                                       return (Double) (Single) value;
+                                       }
+                                       break;
+                       }
+
+                       // Everything else is rejected
+                       return null;
+               }
+
+        protected ListBuilder<MethodInfo> GetMethodCandidates (MethodInfo[] cache, BindingFlags bindingAttr, CallingConventions callConv, Type[] types)
+        {
+               var candidates = new ListBuilder<MethodInfo> ();
+
+            for (int i = 0; i < cache.Length; i++) {
+                               var methodInfo = cache[i];
+                               if (FilterApplyMethodBase(methodInfo, /*methodInfo.BindingFlags,*/ bindingAttr, callConv, types)) {
+                                       candidates.Add (methodInfo);
+                               }
+                       }
+
+                       return candidates;
+               }
+
+        private static bool FilterApplyMethodBase(
+            MethodBase methodBase, /*BindingFlags methodFlags,*/ BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
+        {
+            Contract.Requires(methodBase != null);
+
+            bindingFlags ^= BindingFlags.DeclaredOnly;
+/*
+            #region Apply Base Filter
+            if ((bindingFlags & methodFlags) != methodFlags)
+                return false;
+            #endregion
+*/
+            #region Check CallingConvention
+            if ((callConv & CallingConventions.Any) == 0)
+            {
+                if ((callConv & CallingConventions.VarArgs) != 0 && 
+                    (methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
+                    return false;
+
+                if ((callConv & CallingConventions.Standard) != 0 && 
+                    (methodBase.CallingConvention & CallingConventions.Standard) == 0)
+                    return false;
+            }
+            #endregion
+
+            #region If argumentTypes supplied
+            if (argumentTypes != null)
+            {
+                ParameterInfo[] parameterInfos = methodBase.GetParametersNoCopy();
+
+                if (argumentTypes.Length != parameterInfos.Length)
+                {
+                    #region Invoke Member, Get\Set & Create Instance specific case
+                    // If the number of supplied arguments differs than the number in the signature AND
+                    // we are not filtering for a dynamic call -- InvokeMethod or CreateInstance -- filter out the method.
+                    if ((bindingFlags & 
+                        (BindingFlags.InvokeMethod | BindingFlags.CreateInstance | BindingFlags.GetProperty | BindingFlags.SetProperty)) == 0)
+                        return false;
+                    
+                    bool testForParamArray = false;
+                    bool excessSuppliedArguments = argumentTypes.Length > parameterInfos.Length;
+
+                    if (excessSuppliedArguments) 
+                    { // more supplied arguments than parameters, additional arguments could be vararg
+                        #region Varargs
+                        // If method is not vararg, additional arguments can not be passed as vararg
+                        if ((methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
+                        {
+                            testForParamArray = true;
+                        }
+                        else 
+                        {
+                            // If Binding flags did not include varargs we would have filtered this vararg method.
+                            // This Invariant established during callConv check.
+                            Contract.Assert((callConv & CallingConventions.VarArgs) != 0);
+                        }
+                        #endregion
+                    }
+                    else 
+                    {// fewer supplied arguments than parameters, missing arguments could be optional
+                        #region OptionalParamBinding
+                        if ((bindingFlags & BindingFlags.OptionalParamBinding) == 0)
+                        {
+                            testForParamArray = true;
+                        }
+                        else
+                        {
+                            // From our existing code, our policy here is that if a parameterInfo 
+                            // is optional then all subsequent parameterInfos shall be optional. 
+
+                            // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate.
+                            if (!parameterInfos[argumentTypes.Length].IsOptional)
+                                testForParamArray = true;
+                        }
+                        #endregion
+                    }
+
+                    #region ParamArray
+                    if (testForParamArray)
+                    {
+                        if  (parameterInfos.Length == 0)
+                            return false;
+
+                        // The last argument of the signature could be a param array. 
+                        bool shortByMoreThanOneSuppliedArgument = argumentTypes.Length < parameterInfos.Length - 1;
+
+                        if (shortByMoreThanOneSuppliedArgument)
+                            return false;
+
+                        ParameterInfo lastParameter = parameterInfos[parameterInfos.Length - 1];
+
+                        if (!lastParameter.ParameterType.IsArray)
+                            return false;
+
+                        if (!lastParameter.IsDefined(typeof(ParamArrayAttribute), false))
+                            return false;
+                    }
+                    #endregion
+
+                    #endregion
+                }
+                else
+                {
+                    #region Exact Binding
+                    if ((bindingFlags & BindingFlags.ExactBinding) != 0)
+                    {
+                        // Legacy behavior is to ignore ExactBinding when InvokeMember is specified.
+                        // Why filter by InvokeMember? If the answer is we leave this to the binder then why not leave
+                        // all the rest of this  to the binder too? Further, what other semanitc would the binder
+                        // use for BindingFlags.ExactBinding besides this one? Further, why not include CreateInstance 
+                        // in this if statement? That's just InvokeMethod with a constructor, right?
+                        if ((bindingFlags & (BindingFlags.InvokeMethod)) == 0)
+                        {
+                            for(int i = 0; i < parameterInfos.Length; i ++)
+                            {
+                                // a null argument type implies a null arg which is always a perfect match
+                                if ((object)argumentTypes[i] != null && !Object.ReferenceEquals(parameterInfos[i].ParameterType, argumentTypes[i]))
+                                    return false;
+                            }
+                        }
+                    }
+                    #endregion
+                }
+            }
+            #endregion
+        
+            return true;
+        }
+
+        // Helper to build lists of MemberInfos. Special cased to avoid allocations for lists of one element.
+        protected struct ListBuilder<T> where T : class
+        {
+            T[] _items;
+            T _item;
+            int _count;
+            int _capacity;
+
+            public ListBuilder(int capacity)
+            {
+                _items = null;
+                _item = null;
+                _count = 0;
+                _capacity = capacity;
+            }
+
+            public T this[int index]
+            {
+                get
+                {
+                    Contract.Requires(index < Count);
+                    return (_items != null) ? _items[index] : _item;
+                }
+#if FEATURE_LEGACYNETCF
+                // added for Dev11 466969 quirk
+                set
+                {
+                    Contract.Requires(index < Count);
+                    if (_items != null)
+                        _items[index] = value;
+                    else
+                        _item = value;
+                }
+#endif
+            }
+
+            public T[] ToArray()
+            {
+                if (_count == 0)
+                    return EmptyArray<T>.Value;
+                if (_count == 1)
+                    return new T[1] { _item };
+
+                Array.Resize(ref _items, _count);
+                _capacity = _count;
+                return _items;
+            }
+
+            public void CopyTo(Object[] array, int index)
+            {
+                if (_count == 0)
+                    return;
+
+                if (_count == 1)
+                {
+                    array[index] = _item;
+                    return;
+                }
+
+                Array.Copy(_items, 0, array, index, _count);
+            }
+
+            public int Count
+            {
+                get
+                {
+                    return _count;
+                }
+            }
+
+            public void Add(T item)
+            {
+                if (_count == 0)
+                {
+                    _item = item;
+                }
+                else                
+                {
+                    if (_count == 1)
+                    {
+                        if (_capacity < 2)
+                            _capacity = 4;
+                        _items = new T[_capacity];
+                        _items[0] = _item;
+                    }
+                    else
+                    if (_capacity == _count)
+                    {
+                        int newCapacity = 2 * _capacity;
+                        Array.Resize(ref _items, newCapacity);
+                        _capacity = newCapacity;
+                    }
+
+                    _items[_count] = item;
+                }
+                _count++;
+            }
+        }
        }
 
        [Serializable]
@@ -118,50 +561,25 @@ namespace System
                                                                       Type[] types,
                                                                       ParameterModifier[] modifiers)
                {
-                       ConstructorInfo[] methods = GetConstructors (bindingAttr);
-                       return GetConstructorImpl (methods, bindingAttr, binder, callConvention, types, modifiers);
-               }
+                       ConstructorInfo[] candidates = GetConstructors (bindingAttr);
 
-               internal static ConstructorInfo GetConstructorImpl (ConstructorInfo[] methods, BindingFlags bindingAttr,
-                                                                      Binder binder,
-                                                                      CallingConventions callConvention,
-                                                                      Type[] types,
-                                                                      ParameterModifier[] modifiers)
-               {
-                       if (bindingAttr == BindingFlags.Default)
-                               bindingAttr = BindingFlags.Public | BindingFlags.Instance;
-
-                       ConstructorInfo found = null;
-                       MethodBase[] match;
-                       int count = 0;
-                       foreach (ConstructorInfo m in methods) {
-                               // Under MS.NET, Standard|HasThis matches Standard...
-                               if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
-                                       continue;
-                               found = m;
-                               count++;
-                       }
-                       if (count == 0)
+                       if (candidates.Length == 0)
                                return null;
-                       if (types == null) {
-                               if (count > 1)
-                                       throw new AmbiguousMatchException ();
-                               return (ConstructorInfo) CheckMethodSecurity (found);
-                       }
-                       match = new MethodBase [count];
-                       if (count == 1)
-                               match [0] = found;
-                       else {
-                               count = 0;
-                               foreach (ConstructorInfo m in methods) {
-                                       if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
-                                               continue;
-                                       match [count++] = m;
-                               }
+
+                       if (types.Length == 0 && candidates.Length == 1) {
+                               ConstructorInfo firstCandidate = candidates [0];
+                               var parameters = firstCandidate.GetParametersNoCopy ();
+                               if (parameters == null || parameters.Length == 0)
+                                       return firstCandidate;
                        }
-                       if (binder == null)
-                               binder = Binder.DefaultBinder;
-                       return (ConstructorInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
+
+                       if ((bindingAttr & BindingFlags.ExactBinding) != 0)
+                               return (ConstructorInfo) System.DefaultBinder.ExactBinding (candidates, types, modifiers);
+
+                       if (binder == null)
+                               binder = DefaultBinder;
+
+                       return (ConstructorInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, candidates, types, modifiers));
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -266,44 +684,32 @@ namespace System
                                                             Type[] types, ParameterModifier[] modifiers)
                {
                        bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
-                       MethodInfo[] methods = GetMethodsByName (name, bindingAttr, ignoreCase, this);
-                       MethodInfo found = null;
-                       MethodBase[] match;
-                       int count = 0;
-                       
-                       foreach (MethodInfo m in methods) {
-                               // Under MS.NET, Standard|HasThis matches Standard...
-                               if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
-                                       continue;
-                               found = m;
-                               count++;
-                       }
+                       var candidates = GetMethodCandidates (GetMethodsByName (name, bindingAttr, ignoreCase, this), bindingAttr, callConvention, types);
 
-                       if (count == 0)
+                       if (candidates.Count == 0)
                                return null;
                        
-                       if (count == 1 && types == null) 
-                               return (MethodInfo) CheckMethodSecurity (found);
+                       if (types == null || types.Length == 0) {
+                               var firstCandidate = candidates [0];
+                               if (candidates.Count == 1)
+                                       return firstCandidate;
+
+                               if (types == null) {
+                                       for (int j = 1; j < candidates.Count; j++) {
+                                               MethodInfo methodInfo = candidates [j];
+                                               if (!System.DefaultBinder.CompareMethodSigAndName (methodInfo, firstCandidate))
+                                                       throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+                                       }
 
-                       match = new MethodBase [count];
-                       if (count == 1)
-                               match [0] = found;
-                       else {
-                               count = 0;
-                               foreach (MethodInfo m in methods) {
-                                       if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
-                                               continue;
-                                       match [count++] = m;
+                                       // All the methods have the exact same name and sig so return the most derived one.
+                                       return (MethodInfo) System.DefaultBinder.FindMostDerivedNewSlotMeth (candidates.ToArray (), candidates.Count);
                                }
                        }
 
-                       if (types == null) 
-                               return (MethodInfo) CheckMethodSecurity (Binder.FindMostDerivedMatch (match));
-
                        if (binder == null)
-                               binder = Binder.DefaultBinder;
+                               binder = DefaultBinder;
                        
-                       return (MethodInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, match, types, modifiers));
+                       return (MethodInfo) CheckMethodSecurity (binder.SelectMethod (bindingAttr, candidates.ToArray (), types, modifiers));
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -359,12 +765,24 @@ namespace System
                        if (count == 0)
                                return null;
                        
-                       if (count == 1 && (types == null || types.Length == 0) && 
-                           (returnType == null || returnType == props[0].PropertyType))
-                               return props [0];
+                       if (types == null || types.Length == 0) {
+                               if (count == 1) {
+                                       var firstCandidate = props [0];
+
+                                       if ((object)returnType != null && !returnType.IsEquivalentTo (firstCandidate.PropertyType))
+                                               return null;
+
+                                       return firstCandidate;
+                               }
+
+                               throw new AmbiguousMatchException (Environment.GetResourceString("Arg_AmbiguousMatchException"));
+                       }
+
+                       if ((bindingAttr & BindingFlags.ExactBinding) != 0)
+                               return System.DefaultBinder.ExactPropertyBinding (props, returnType, types, modifiers);
 
                        if (binder == null)
-                               binder = Binder.DefaultBinder;
+                               binder = DefaultBinder;
 
                        return binder.SelectProperty (bindingAttr, props, returnType, types, modifiers);
                }
@@ -467,7 +885,8 @@ namespace System
                                                        throw new ArgumentException ("Used Missing.Value for argument without default value", "parameters");
                                        }
                                        object result = m.Invoke (target, invokeAttr, binder, args, culture);
-                                       binder.ReorderArgumentArray (ref args, state);
+                                       if (state != null)
+                                               binder.ReorderArgumentArray (ref args, state);
                                        return result;
                                }
                        }
@@ -496,6 +915,8 @@ namespace System
                        if ((invokeAttr & BindingFlags.GetProperty) != 0) {
                                PropertyInfo[] properties = GetPropertiesByName (name, invokeAttr, ignoreCase, this);
                                object state = null;
+                               if (args == null)
+                                       args = EmptyArray<object>.Value;
                                int i, count = 0;
                                for (i = 0; i < properties.Length; ++i) {
                                        if ((properties [i].GetGetMethod (true) != null))
@@ -513,7 +934,8 @@ namespace System
                                        throwMissingFieldException = true;
                                } else {
                                        object result = m.Invoke (target, invokeAttr, binder, args, culture);
-                                       binder.ReorderArgumentArray (ref args, state);
+                                       if (state != null)
+                                               binder.ReorderArgumentArray (ref args, state);
                                        return result;
                                }
                        } else if ((invokeAttr & BindingFlags.SetProperty) != 0) {
@@ -536,7 +958,8 @@ namespace System
                                        throwMissingFieldException = true;
                                } else {
                                        object result = m.Invoke (target, invokeAttr, binder, args, culture);
-                                       binder.ReorderArgumentArray (ref args, state);
+                                       if (state != null)
+                                               binder.ReorderArgumentArray (ref args, state);
                                        return result;
                                }
                        }
index 1475736d7d5de3aa29a3fc59fbddcb25e8b3e0bc..79fd58267a371f8966ae574a3b63cfa00f3386ec 100644 (file)
@@ -159,10 +159,15 @@ namespace System {
                /// </summary>
                public static Binder DefaultBinder {
                        get {
-                               return Binder.DefaultBinder;
+                               if (defaultBinder == null)
+                                       Interlocked.CompareExchange<Binder> (ref defaultBinder, new DefaultBinder (), null);
+
+                               return defaultBinder;
                        }
                }
 
+               static Binder defaultBinder;
+
                /// <summary>
                ///    The full name of the type including its namespace
                /// </summary>
index c96913e9642e09c2605ba0d29e562e6acab96e59..cd9f255b932802e7b9df2502ef302ca5059008bf 100644 (file)
@@ -318,7 +318,6 @@ namespace MonoTests.System.Reflection
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void SelectMethod_AmbiguousMatch ()
                {
                        Type type = typeof (BinderTest);
@@ -402,7 +401,6 @@ namespace MonoTests.System.Reflection
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void SelectMethod_Params ()
                {
                        Type type = typeof (BinderTest);
@@ -542,8 +540,11 @@ namespace MonoTests.System.Reflection
                                                                    BindingFlags.Public |
                                                                    BindingFlags.Instance);
 
-                       PropertyInfo prop = binder.SelectProperty (0, props, null, new Type [] {null}, null);
-                       Assert.IsNotNull (prop);
+                       try {
+                               binder.SelectProperty (0, props, null, new Type [] {null}, null);
+                               Assert.Fail ();
+                       } catch (ArgumentNullException) {
+                       }
                }
 
                [Test]
@@ -586,7 +587,6 @@ namespace MonoTests.System.Reflection
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void BindToMethod_AmbiguousMatch ()
                {
                        Type type = typeof (BinderTest);
@@ -651,7 +651,6 @@ namespace MonoTests.System.Reflection
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void BindToMethod_Params ()
                {
                        Type type = typeof (BinderTest);
@@ -811,8 +810,6 @@ namespace MonoTests.System.Reflection
                }
 
                [Test]
-               [Category ("NotDotNet")]
-               [Category ("NotWorking")]
                public void BindToMethod_Params_Mono ()
                {
                        Type type = typeof (BinderTest);
@@ -872,7 +869,6 @@ namespace MonoTests.System.Reflection
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void BindToMethod_Params_MS ()
                {
                        Type type = typeof (BinderTest);
@@ -908,26 +904,11 @@ namespace MonoTests.System.Reflection
                                null, out state);
                        Assert.AreSame (mi_params, selected, "#D1");
                        args = new object [] { new object (), new object () };
-                       try {
-                               binder.BindToMethod (flags, match, ref args, null, culture,
-                                       null, out state);
-                               Assert.Fail ("#D2");
-                       } catch (AmbiguousMatchException) {
-                       }
+                       binder.BindToMethod (flags, match, ref args, null, culture, null, out state);
                        args = new object [] { new object (), new object [0] };
-                       try {
-                               binder.BindToMethod (flags, match, ref args, null, culture,
-                                       null, out state);
-                               Assert.Fail ("#D3");
-                       } catch (AmbiguousMatchException) {
-                       }
+                       binder.BindToMethod (flags, match, ref args, null, culture, null, out state);
                        args = new object [] { new object (), new object (), new object () };
-                       try {
-                               binder.BindToMethod (flags, match, ref args, null, culture,
-                                       null, out state);
-                               Assert.Fail ("#D4");
-                       } catch (IndexOutOfRangeException) {
-                       }
+                       binder.BindToMethod (flags, match, ref args, null, culture, null, out state);
 
                        match = new MethodBase [] { mi_params, mi_non_params, mi_single_param };
                        args = new object [] { new object () };
@@ -937,7 +918,7 @@ namespace MonoTests.System.Reflection
                        args = new object [] { new object (), new object () };
                        selected = binder.BindToMethod (flags, match, ref args, null, culture,
                                null, out state);
-                       Assert.AreSame (mi_params, selected, "#E2");
+                       Assert.AreNotSame (mi_params, selected, "#E2");
                }
 
                [Test] // bug #41691
@@ -1461,7 +1442,6 @@ namespace MonoTests.System.Reflection
                }
 
                [Test] // bug #636939
-               [Category ("NotWorking")]
                public void SelectMethodWithParamArrayAndNonEqualTypeArguments ()
                {
             const BindingFlags flags =
index f7fc07e9868264be21053a6a30e36712e3931d4b..d00818dd3726136e1beb6aa37ffbbd9dd0b946d5 100644 (file)
@@ -618,6 +618,16 @@ namespace MonoTests.System {
                        Assert.AreEqual (42, a.A);
                        Assert.AreEqual (null, a.X);
                        Assert.AreEqual (null, a.Y);
+
+                       var b = Activator.CreateInstance (typeof (SimpleParamsObjectConstructor), 1, 2, 3, 4, 5);
+                       Assert.IsNotNull (b);
+               }
+
+               class SimpleParamsObjectConstructor
+               {
+                       public SimpleParamsObjectConstructor (params object[] parameters)
+                       {
+                       }
                }
 
                class SimpleParamsConstructor {
index 94fe67d34ab12960a9683d4b9da0e17fa5d7264c..f200bee4123f28b8722c7d4585e401e7a7cc0ee2 100644 (file)
@@ -1692,21 +1692,6 @@ namespace MonoTests.System
                        Assert.IsTrue (typeof (TimeSpan).IsValueType, "#6");
                }
 
-               [Test]
-               [Category("NotDotNet")]
-               // Depends on the GAC working, which it doesn't durring make distcheck.
-               [Category ("NotWorking")]
-               public void GetTypeWithWhitespace ()
-               {
-                       Assert.IsNotNull (Type.GetType
-                                                  (@"System.Configuration.NameValueSectionHandler,
-                       System,
-Version=1.0.5000.0,
-Culture=neutral
-,
-PublicKeyToken=b77a5c561934e089"));
-               }
-
                [Test]
                public void GetTypeNonVectorArray ()
                {
index 11a27fe056eceb5960adc331f2e8b89a9fedc438..79334484894b46132069bbd4f45f7c6b1bfdd7dc 100644 (file)
@@ -397,7 +397,6 @@ System.Reflection/AssemblySignatureKeyAttribute.cs
 System.Reflection/AssemblyTitleAttribute.cs
 System.Reflection/AssemblyTradeMarkAttribute.cs
 System.Reflection/AssemblyVersionAttribute.cs
-System.Reflection/Binder.cs
 System.Reflection/BindingFlags.cs
 System.Reflection/CallingConventions.cs
 System.Reflection/ConstructorInfo.cs
@@ -1388,6 +1387,7 @@ ReferenceSources/BCLDebug.cs
 ReferenceSources/CalendarData.cs
 ReferenceSources/CompatibilitySwitches.cs
 ReferenceSources/CultureData.cs
+ReferenceSources/DefaultBinder.cs
 ReferenceSources/Environment.cs
 ReferenceSources/ExecutionContext.cs
 ReferenceSources/HashHelpers.cs
@@ -1412,6 +1412,7 @@ ReferenceSources/EncodingTable.cs
 ../../../external/referencesource/mscorlib/system/datetimeoffset.cs
 ../../../external/referencesource/mscorlib/system/dayofweek.cs
 ../../../external/referencesource/mscorlib/system/decimal.cs
+../../../external/referencesource/mscorlib/system/defaultbinder.cs
 ../../../external/referencesource/mscorlib/system/dbnull.cs
 ../../../external/referencesource/mscorlib/system/empty.cs
 ../../../external/referencesource/mscorlib/system/guid.cs
@@ -1550,6 +1551,8 @@ ReferenceSources/EncodingTable.cs
 ../../../external/referencesource/mscorlib/system/io/textwriter.cs
 ../../../external/referencesource/mscorlib/system/io/unmanagedmemorystream.cs
 
+../../../external/referencesource/mscorlib/system/reflection/binder.cs
+
 ../../../external/referencesource/mscorlib/system/runtime/versioning/binarycompatibility.cs
 ../../../external/referencesource/mscorlib/system/runtime/versioning/targetframeworkid.cs