New tests.
[mono.git] / mcs / class / corlib / System / Activator.cs
index 355326912dfd2f748931ceb9d31ee5e73b3b3134..db61c741a891fa35a9c5dd548c8f20fbc8565f86 100644 (file)
 
 using System.Globalization;
 using System.Reflection;
-using System.Runtime.Remoting;
-using System.Runtime.Remoting.Activation;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Security.Permissions;
 using System.Security.Policy;
 using System.Configuration.Assemblies;
+using System.Text;
+#if !MOONLIGHT
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Activation;
+#endif
 
 namespace System 
 {
        [ClassInterface (ClassInterfaceType.None)]
-#if NET_2_0
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_Activator))]
-#endif
        public sealed class Activator : _Activator
        {
                const BindingFlags _flags = BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance;
@@ -57,7 +58,8 @@ namespace System
                {
                }
 
-               [MonoTODO]
+#if !MOONLIGHT
+               [MonoTODO ("No COM support")]
                public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
                {
                        if (assemblyName == null)
@@ -72,8 +74,7 @@ namespace System
                        throw new NotImplementedException();
                }
 
-#if NET_1_1
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName,
                                                                  byte []hashValue, AssemblyHashAlgorithm hashAlgorithm)
                {
@@ -88,7 +89,6 @@ namespace System
 
                        throw new NotImplementedException();
                }
-#endif
 
                public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName)
                {
@@ -101,6 +101,9 @@ namespace System
                                activationAttributes, null);
                }
 
+#if NET_4_0
+               [Obsolete]
+#endif
                public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
                                                               BindingFlags bindingAttr, Binder binder, object [] args,
                                                               CultureInfo culture, object [] activationAttributes,
@@ -135,6 +138,9 @@ namespace System
                                activationAttributes, null);
                }
 
+#if NET_4_0
+               [Obsolete]
+#endif
                public static ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase,
                                                           BindingFlags bindingAttr, Binder binder, object [] args,
                                                           CultureInfo culture, object [] activationAttributes, Evidence securityInfo)
@@ -149,12 +155,69 @@ namespace System
                        return (obj != null) ? new ObjectHandle (obj) : null;
                }
 
-#if NET_2_0
+               [MonoNotSupported ("no ClickOnce in mono")]
+               public static ObjectHandle CreateInstance (ActivationContext activationContext)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoNotSupported ("no ClickOnce in mono")]
+               public static ObjectHandle CreateInstance (ActivationContext activationContext, string [] activationCustomData)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               // Cross-domain instance creation
+
+               public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName)
+               {
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+                       return domain.CreateInstanceFrom (assemblyFile, typeName);
+               }
+
+
+#if NET_4_0
+               [Obsolete]
+#endif
+               public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName,
+                                                              bool ignoreCase, BindingFlags bindingAttr, Binder binder,
+                                                              object [] args, CultureInfo culture,
+                                                              object [] activationAttributes,
+                                                              Evidence securityAttributes)
+               {
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+
+                       return domain.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
+               }
+
+               public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName)
+               {
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+                       return domain.CreateInstance (assemblyName, typeName);
+               }
+
+#if NET_4_0
+               [Obsolete]
+#endif
+               public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName,
+                                                          bool ignoreCase, BindingFlags bindingAttr, Binder binder,
+                                                          object [] args, CultureInfo culture,
+                                                          object [] activationAttributes,
+                                                          Evidence securityAttributes)
+               {
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+                       return domain.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
+               }
+#endif // !NET_2_1
+
                public static T CreateInstance <T> ()
                {
                        return (T) CreateInstance (typeof (T));
                }
-#endif
 
                public static object CreateInstance (Type type)
                {
@@ -181,68 +244,90 @@ namespace System
                                                     CultureInfo culture, object [] activationAttributes)
                {
                        CheckType (type);
-               
+
+                       if (type.ContainsGenericParameters)
+                               throw new ArgumentException (type + " is an open generic type", "type");
+
                        // It seems to apply the same rules documented for InvokeMember: "If the type of lookup
                        // is omitted, BindingFlags.Public | BindingFlags.Instance will apply".
                        if ((bindingAttr & _accessFlags) == 0)
                                bindingAttr |= BindingFlags.Public | BindingFlags.Instance;
 
-                       int length = 0;
-                       if (args != null)
-                               length = args.Length;
-
-                       Type[] atypes = length == 0 ? Type.EmptyTypes : new Type [length];
-                       for (int i = 0; i < length; ++i)
-                               if (args [i] != null)
-                                       atypes [i] = args [i].GetType ();
-
                        if (binder == null)
                                binder = Binder.DefaultBinder;
 
-                       ConstructorInfo ctor = (ConstructorInfo) binder.SelectMethod (bindingAttr, type.GetConstructors (bindingAttr), atypes, null);
+                       object state;
+                       ConstructorInfo ctor = (ConstructorInfo) binder.BindToMethod (bindingAttr, type.GetConstructors (bindingAttr), ref args, null, null, null, out state);
 
                        if (ctor == null) {
                                // Not sure about this
-                               if (type.IsValueType && atypes.Length == 0) {
+                               if (type.IsValueType && (args == null || args.Length == 0)) {
                                        return CreateInstanceInternal (type);
                                }
 
-                               throw new MissingMethodException (Locale.GetText ("Constructor not found. Class: ") +
-                                                               type.FullName);
+                               var sb = new StringBuilder ();
+                               if (args != null) {
+                                       for (int i = 0; i < args.Length; i++) {
+                                               if (i > 0)
+                                                       sb.Append (", ");
+
+                                               var argument = args [i];
+                                               var arg_type = argument != null ? argument.GetType () : null;
+                                               sb.Append (arg_type != null ? arg_type.ToString () : "(unknown)");
+                                       }
+                               }
+
+                               throw new MissingMethodException (String.Format (Locale.GetText ("No constructor found for {0}::.ctor({1})"),
+                                                                                type.FullName, sb));
                        }
 
                        CheckAbstractType (type);
-
+#if !MOONLIGHT
                        if (activationAttributes != null && activationAttributes.Length > 0) {
                                if (!type.IsMarshalByRef) {
                                        string msg = Locale.GetText ("Type '{0}' doesn't derive from MarshalByRefObject.", type.FullName);
                                        throw new NotSupportedException (msg);
                                }
                                object newOb = ActivationServices.CreateProxyFromAttributes (type, activationAttributes);
-                               if (newOb != null)
-                                       return ctor.Invoke (newOb, bindingAttr, binder, args, culture);
+                               if (newOb != null) {
+                                       // This returns null
+                                       ctor.Invoke (newOb, bindingAttr, binder, args, culture);
+                                       return newOb;
+                               }
                        }
-
+#endif
                        return ctor.Invoke (bindingAttr, binder, args, culture);
                }
 
                public static object CreateInstance (Type type, bool nonPublic)
                { 
                        CheckType (type);
-                       CheckAbstractType (type);
 
-                       BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
-                       if (nonPublic)
-                               flags |= BindingFlags.NonPublic;
+                       if (type.ContainsGenericParameters)
+                               throw new ArgumentException (type + " is an open generic type", "type");
 
-                       ConstructorInfo ctor = type.GetConstructor (flags, null, CallingConventions.Any, Type.EmptyTypes, null);
+                       CheckAbstractType (type);
+
+                       ConstructorInfo ctor;
+                       MonoType monoType = type as MonoType;
+
+                       if (monoType != null) {
+                               ctor = monoType.GetDefaultConstructor ();
+                               if (!nonPublic && ctor != null && !ctor.IsPublic)
+                                       ctor = null;
+                       } else {
+                               BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
+                               if (nonPublic)
+                                       flags |= BindingFlags.NonPublic;
+                               ctor = type.GetConstructor (flags, null, CallingConventions.Any, Type.EmptyTypes, null);
+                       }
 
                        if (ctor == null) {
                                if (type.IsValueType)
                                        return CreateInstanceInternal (type);
 
-                               throw new MissingMethodException (Locale.GetText ("Default constructor not found."),
-                                                               ".ctor() of " + type.FullName);
+                               throw new MissingMethodException (Locale.GetText ("Default constructor not found for type " + 
+                                                       type.FullName + "."));
                        }
 
                        return ctor.Invoke (null);
@@ -264,14 +349,11 @@ namespace System
                {
                        if (type.IsAbstract) {
                                string msg = Locale.GetText ("Cannot create an abstract class '{0}'.", type.FullName);
-#if NET_2_0
                                throw new MissingMethodException (msg);
-#else
-                               throw new MemberAccessException (msg);
-#endif
                        }
                }
 
+#if !MOONLIGHT
                [SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
                public static object GetObject (Type type, string url)
                {
@@ -289,11 +371,10 @@ namespace System
 
                        return RemotingServices.Connect (type, url, state);
                }
-
+#endif
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal static extern object CreateInstanceInternal (Type type);
 
-#if NET_1_1
                void _Activator.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
                {
                        throw new NotImplementedException ();
@@ -314,6 +395,58 @@ namespace System
                {
                        throw new NotImplementedException ();
                }
+
+#if NET_4_0
+               public static ObjectHandle CreateInstance (string assemblyName, string typeName, bool ignoreCase,
+                                                          BindingFlags bindingAttr, Binder binder, object [] args,
+                                                          CultureInfo culture, object [] activationAttributes)
+               {
+                       Assembly assembly = null;
+                       if(assemblyName == null)
+                               assembly = Assembly.GetCallingAssembly ();
+                       else
+                               assembly = Assembly.Load (assemblyName);
+                       Type type = assembly.GetType (typeName, true, ignoreCase);
+                       object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
+                       return (obj != null) ? new ObjectHandle (obj) : null;
+               }
+
+               public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName,
+                                                          bool ignoreCase, BindingFlags bindingAttr, Binder binder,
+                                                          object [] args, CultureInfo culture,
+                                                          object [] activationAttributes)
+               {
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+                       return domain.CreateInstance (assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes);
+               }
+
+               public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName, bool ignoreCase,
+                                                              BindingFlags bindingAttr, Binder binder, object [] args,
+                                                              CultureInfo culture, object [] activationAttributes)
+               {
+                       Assembly assembly = Assembly.LoadFrom (assemblyFile);
+                       if (assembly == null)
+                               return null;
+
+                       Type type = assembly.GetType (typeName, true, ignoreCase);
+                       if (type == null)
+                               return null;
+
+                       object obj = CreateInstance (type, bindingAttr, binder, args, culture, activationAttributes);
+                       return (obj != null) ? new ObjectHandle (obj) : null;
+               }
+
+               public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName,
+                                                              bool ignoreCase, BindingFlags bindingAttr, Binder binder,
+                                                              object [] args, CultureInfo culture,
+                                                              object [] activationAttributes)
+               {
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+
+                       return domain.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes);
+               }
 #endif
        }
 }