New tests.
[mono.git] / mcs / class / corlib / System / Activator.cs
index 9537b27e7d4140d469dd1057e47b722e95277330..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 
 {
-       public sealed class Activator
+       [ClassInterface (ClassInterfaceType.None)]
+       [ComVisible (true)]
+       [ComDefaultInterface (typeof (_Activator))]
+       public sealed class Activator : _Activator
        {
                const BindingFlags _flags = BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance;
                const BindingFlags _accessFlags = BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase | 
@@ -51,7 +58,8 @@ namespace System
                {
                }
 
-               [MonoTODO]
+#if !MOONLIGHT
+               [MonoTODO ("No COM support")]
                public static ObjectHandle CreateComInstanceFrom (string assemblyName, string typeName)
                {
                        if (assemblyName == null)
@@ -60,11 +68,13 @@ namespace System
                        if (typeName == null)
                                throw new ArgumentNullException ("typeName");
 
+                       if (assemblyName.Length == 0)
+                               throw new ArgumentException ("assemblyName");
+
                        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)
                {
@@ -74,9 +84,11 @@ namespace System
                        if (typeName == null)
                                throw new ArgumentNullException ("typeName");
 
+                       if (assemblyName.Length == 0)
+                               throw new ArgumentException ("assemblyName");
+
                        throw new NotImplementedException();
                }
-#endif
 
                public static ObjectHandle CreateInstanceFrom (string assemblyFile, string typeName)
                {
@@ -89,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,
@@ -123,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)
@@ -137,50 +155,83 @@ namespace System
                        return (obj != null) ? new ObjectHandle (obj) : null;
                }
 
-               public static object CreateInstance (Type type)
+               [MonoNotSupported ("no ClickOnce in mono")]
+               public static ObjectHandle CreateInstance (ActivationContext activationContext)
                {
-                       return CreateInstance (type, false);
+                       throw new NotImplementedException ();
                }
 
-               public static object CreateInstance (Type type, object [] args)
+               [MonoNotSupported ("no ClickOnce in mono")]
+               public static ObjectHandle CreateInstance (ActivationContext activationContext, string [] activationCustomData)
                {
-                       return CreateInstance (type, args, new object [0]);
+                       throw new NotImplementedException ();
                }
 
-               public static object CreateInstance (Type type, object [] args, object [] activationAttributes)
+               // Cross-domain instance creation
+
+               public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName)
                {
-                       if (type == null)
-                               throw new ArgumentNullException ("type");
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+                       return domain.CreateInstanceFrom (assemblyFile, typeName);
+               }
 
-                       if (type.IsAbstract)
-                               throw new MemberAccessException (Locale.GetText ("Cannot create an abstract class. Class name: ") +
-                                                               type.FullName);
 
-                       int length = 0;
-                       if (args != null)
-                               length = args.Length;
+#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");
 
-                       Type [] atypes = new Type [length];
-                       for (int i = 0; i < length; ++i)
-                               if (args [i] != null)
-                                       atypes [i] = args [i].GetType ();
-                       
-                       ConstructorInfo ctor = type.GetConstructor (atypes);
-                       if (ctor == null) {
-                               if (type.IsValueType && atypes.Length == 0)
-                                       return CreateInstanceInternal (type);
+                       return domain.CreateInstanceFrom (assemblyFile, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
+               }
 
-                               throw new MissingMethodException (Locale.GetText ("Constructor not found. Class") +
-                                                               type.FullName);
-                       }
+               public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName)
+               {
+                       if (domain == null)
+                               throw new ArgumentNullException ("domain");
+                       return domain.CreateInstance (assemblyName, typeName);
+               }
 
-                       if (activationAttributes != null && activationAttributes.Length > 0 && type.IsMarshalByRef) {
-                               object newOb = ActivationServices.CreateProxyFromAttributes (type, activationAttributes);
-                               if (newOb != null)
-                                       return ctor.Invoke (newOb, args);
-                       }
+#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));
+               }
+
+               public static object CreateInstance (Type type)
+               {
+                       return CreateInstance (type, false);
+               }
+
+               public static object CreateInstance (Type type, params object [] args)
+               {
+                       return CreateInstance (type, args, new object [0]);
+               }
 
-                       return ctor.Invoke (args);
+               public static object CreateInstance (Type type, object [] args, object [] activationAttributes)
+               {
+                       return CreateInstance (type, BindingFlags.Default, Binder.DefaultBinder, args, null, activationAttributes);
                }
 
                public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
@@ -192,86 +243,210 @@ namespace System
                public static object CreateInstance (Type type, BindingFlags bindingAttr, Binder binder, object [] args,
                                                     CultureInfo culture, object [] activationAttributes)
                {
-                       if (type == null)
-                               throw new ArgumentNullException ("type");
-               
-                       if (type.IsAbstract)
-                               throw new MemberAccessException (Locale.GetText ("Cannot create an abstract class. Class name: ") +
-                                                               type.FullName);
-                               
+                       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;
+                       if (binder == null)
+                               binder = Binder.DefaultBinder;
+
+                       object state;
+                       ConstructorInfo ctor = (ConstructorInfo) binder.BindToMethod (bindingAttr, type.GetConstructors (bindingAttr), ref args, null, null, null, out state);
 
-                       Type[] atypes = new Type [length];
-                       for (int i = 0; i < length; ++i)
-                               if (args [i] != null)
-                                       atypes [i] = args [i].GetType ();
-                               
-                       ConstructorInfo ctor = type.GetConstructor (bindingAttr, binder, atypes, null);
                        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));
                        }
 
-                       if (activationAttributes != null && activationAttributes.Length > 0 && type.IsMarshalByRef) {
+                       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)
                { 
-                       if (type == null)
-                               throw new ArgumentNullException ("type");
-               
-                       if (type.IsAbstract)
-                               throw new MemberAccessException (Locale.GetText ("Cannot create an abstract class. Class name: ") +
-                                                               type.FullName);
+                       CheckType (type);
+
+                       if (type.ContainsGenericParameters)
+                               throw new ArgumentException (type + " is an open generic type", "type");
 
-                       BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
-                       if (nonPublic)
-                               flags |= BindingFlags.NonPublic;
+                       CheckAbstractType (type);
 
-                       ConstructorInfo ctor = type.GetConstructor (flags, null, CallingConventions.Any, Type.EmptyTypes, null);
+                       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);
                }
 
+               private static void CheckType (Type type)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+
+                       if ((type == typeof (TypedReference)) || (type == typeof (ArgIterator)) || (type == typeof (void)) ||
+                               (type == typeof (RuntimeArgumentHandle))) {
+                               string msg = Locale.GetText ("CreateInstance cannot be used to create this type ({0}).", type.FullName);
+                               throw new NotSupportedException (msg);
+                       }
+               }
+
+               private static void CheckAbstractType (Type type)
+               {
+                       if (type.IsAbstract) {
+                               string msg = Locale.GetText ("Cannot create an abstract class '{0}'.", type.FullName);
+                               throw new MissingMethodException (msg);
+                       }
+               }
+
+#if !MOONLIGHT
                [SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
                public static object GetObject (Type type, string url)
                {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+
                        return RemotingServices.Connect (type, url);
                }
 
                [SecurityPermission (SecurityAction.LinkDemand, RemotingConfiguration = true)]
                public static object GetObject (Type type, string url, object state)
                {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+
                        return RemotingServices.Connect (type, url, state);
                }
-
+#endif
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal static extern object CreateInstanceInternal (Type type);
+
+               void _Activator.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               void _Activator.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               void _Activator.GetTypeInfoCount (out uint pcTInfo)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               void _Activator.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
+                       IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+               {
+                       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
        }
 }