Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System.Reflection.Emit / AssemblyBuilder.cs
index 8318fdecb49ee7511db701565b48ca367ea30e0c..c73c6ada22b50f7009f5b9cabfbab4b7c4feea89 100644 (file)
@@ -30,6 +30,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+#if !FULL_AOT_RUNTIME
 using System;
 using System.Reflection;
 using System.Resources;
@@ -39,6 +40,7 @@ using System.Runtime.Serialization;
 using System.Globalization;
 using System.Runtime.CompilerServices;
 using System.Collections;
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.Security;
 using System.Security.Cryptography;
@@ -68,12 +70,14 @@ namespace System.Reflection.Emit
        }
 
        internal struct MonoResource {
+#pragma warning disable 649
                public byte[] data;
                public string name;
                public string filename;
                public ResourceAttributes attrs;
                public int offset;
                public Stream stream;
+#pragma warning restore 649
        }
 
        internal struct MonoWin32Resource {
@@ -93,11 +97,16 @@ namespace System.Reflection.Emit
        internal class GenericInstanceKey {
                Type gtd;
                internal Type[] args;
+               int hash_code;
 
                internal GenericInstanceKey (Type gtd, Type[] args)
                {
                        this.gtd = gtd;
                        this.args = args;
+
+                       hash_code = gtd.GetHashCode ();
+                       for (int i = 0; i < args.Length; ++i)
+                               hash_code ^= args [i].GetHashCode ();
                }
 
                static bool IsBoundedVector (Type type) {
@@ -193,10 +202,7 @@ namespace System.Reflection.Emit
 
                public override int GetHashCode ()
                {
-                       int hash = gtd.GetHashCode ();
-                       for (int i = 0; i < args.Length; ++i)
-                               hash ^= args [i].GetHashCode ();
-                       return hash;
+                       return hash_code;
                }
        }
 
@@ -204,8 +210,9 @@ namespace System.Reflection.Emit
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_AssemblyBuilder))]
        [ClassInterface (ClassInterfaceType.None)]
+       [StructLayout (LayoutKind.Sequential)]
        public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder {
-#pragma warning disable 169, 414
+#pragma warning disable 169, 414, 649
                #region Sync with object-internals.h
                private UIntPtr dynamic_assembly; /* GC-tracked */
                private MethodInfo entry_point;
@@ -233,7 +240,7 @@ namespace System.Reflection.Emit
                Type[] type_forwarders;
                byte[] pktoken;
                #endregion
-#pragma warning restore 169, 414
+#pragma warning restore 169, 414, 649
                
                internal Type corlib_object_type = typeof (System.Object);
                internal Type corlib_value_type = typeof (System.ValueType);
@@ -245,9 +252,7 @@ namespace System.Reflection.Emit
                bool is_module_only;
                private Mono.Security.StrongName sn;
                NativeResourceType native_resource;
-               readonly bool is_compiler_context;
                string versioninfo_culture;
-               Hashtable generic_instances = new Hashtable ();
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern void basic_init (AssemblyBuilder ab);
@@ -257,28 +262,15 @@ namespace System.Reflection.Emit
 
                internal AssemblyBuilder (AssemblyName n, string directory, AssemblyBuilderAccess access, bool corlib_internal)
                {
-                       is_compiler_context = (access & COMPILER_ACCESS) != 0;
-
-                       // remove Mono specific flag to allow enum check to pass
-                       access &= ~COMPILER_ACCESS;
-
-#if NET_2_1 && !MONOTOUCH
-                       // only "Run" is supported by Silverlight
-                       // however SMCS requires more than this but runs outside the CoreCLR sandbox
-                       if (SecurityManager.SecurityEnabled && (access != AssemblyBuilderAccess.Run))
-                               throw new ArgumentException ("access");
-#endif
+                       /* This is obsolete now, as mcs doesn't use SRE any more */
+                       if ((access & COMPILER_ACCESS) != 0)
+                               throw new NotImplementedException ("COMPILER_ACCESS is no longer supperted, use a newer mcs.");
 
                        if (!Enum.IsDefined (typeof (AssemblyBuilderAccess), access))
                                throw new ArgumentException (string.Format (CultureInfo.InvariantCulture,
                                        "Argument value {0} is not valid.", (int) access),
                                        "access");
 
-#if NET_4_0
-                       if ((access & AssemblyBuilderAccess.RunAndCollect) == AssemblyBuilderAccess.RunAndCollect)
-                               throw new NotSupportedException ("RunAndCollect not yet supported.");
-#endif
-
                        name = n.Name;
                        this.access = (uint)access;
                        flags = (uint) n.Flags;
@@ -390,9 +382,6 @@ namespace System.Reflection.Emit
                        resources [p].attrs = attribute;
                }
 
-               /// <summary>
-               /// Don't change the method name and parameters order. It is used by mcs 
-               /// </summary>
                internal void AddPermissionRequests (PermissionSet required, PermissionSet optional, PermissionSet refused)
                {
 #if !NET_2_1
@@ -425,12 +414,13 @@ namespace System.Reflection.Emit
 #endif
                }
 
+               // Still in use by al.exe
                internal void EmbedResourceFile (string name, string fileName)
                {
                        EmbedResourceFile (name, fileName, ResourceAttributes.Public);
                }
 
-               internal void EmbedResourceFile (string name, string fileName, ResourceAttributes attribute)
+               void EmbedResourceFile (string name, string fileName, ResourceAttributes attribute)
                {
                        if (resources != null) {
                                MonoResource[] new_r = new MonoResource [resources.Length + 1];
@@ -449,10 +439,9 @@ namespace System.Reflection.Emit
                                s.Read (resources [p].data, 0, (int)len);
                                s.Close ();
                        } catch {
-                               /* do something */
                        }
                }
-
+/*
                internal void EmbedResource (string name, byte[] blob, ResourceAttributes attribute)
                {
                        if (resources != null) {
@@ -467,20 +456,7 @@ namespace System.Reflection.Emit
                        resources [p].attrs = attribute;
                        resources [p].data = blob;
                }
-
-               internal void AddTypeForwarder (Type t) {
-                       if (t == null)
-                               throw new ArgumentNullException ("t");
-
-                       if (type_forwarders == null) {
-                               type_forwarders = new Type [1] { t };
-                       } else {
-                               Type[] arr = new Type [type_forwarders.Length + 1];
-                               Array.Copy (type_forwarders, arr, type_forwarders.Length);
-                               arr [type_forwarders.Length] = t;
-                               type_forwarders = arr;
-                       }
-               }
+*/
 
                public ModuleBuilder DefineDynamicModule (string name)
                {
@@ -532,31 +508,6 @@ namespace System.Reflection.Emit
                        return r;
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern Module InternalAddModule (string fileName);
-
-               /*
-                * Mono extension to support /addmodule in mcs.
-                */
-               internal Module AddModule (string fileName)
-               {
-                       if (fileName == null)
-                               throw new ArgumentNullException (fileName);
-
-                       Module m = InternalAddModule (fileName);
-
-                       if (loaded_modules != null) {
-                               Module[] new_modules = new Module [loaded_modules.Length + 1];
-                               System.Array.Copy (loaded_modules, new_modules, loaded_modules.Length);
-                               loaded_modules = new_modules;
-                       } else {
-                               loaded_modules = new Module [1];
-                       }
-                       loaded_modules [loaded_modules.Length - 1] = m;
-
-                       return m;
-               }
-
                public IResourceWriter DefineResource (string name, string description, string fileName)
                {
                        return DefineResource (name, description, fileName, ResourceAttributes.Public);
@@ -605,6 +556,8 @@ namespace System.Reflection.Emit
                        /*
                         * The format of the argument byte array is not documented
                         * so this method is impossible to implement.
+                        *
+                        * https://connect.microsoft.com/VisualStudio/feedback/details/95784/fatal-assemblybuilder-defineunmanagedresource-byte-and-modulebuilder-defineunmanagedresource-byte-bugs-renders-them-useless
                         */
 
                        throw new NotImplementedException ();
@@ -617,7 +570,7 @@ namespace System.Reflection.Emit
                        if (resourceFileName.Length == 0)
                                throw new ArgumentException ("resourceFileName");
                        if (!File.Exists (resourceFileName) || Directory.Exists (resourceFileName))
-                               throw new FileNotFoundException ("File '" + resourceFileName + "' does not exists or is a directory.");
+                               throw new FileNotFoundException ("File '" + resourceFileName + "' does not exist or is a directory.");
                        if (native_resource != NativeResourceType.None)
                                throw new ArgumentException ("Native resource has already been defined.");
 
@@ -644,7 +597,7 @@ namespace System.Reflection.Emit
                        // avoid definition of more than one unmanaged resource
                        native_resource = NativeResourceType.Assembly;
 
-                       version_res = new Win32VersionResource (1, 0, IsCompilerContext);
+                       version_res = new Win32VersionResource (1, 0, false);
                }
 
                public void DefineVersionInfoResource (string product, string productVersion,
@@ -669,34 +622,6 @@ namespace System.Reflection.Emit
                        version_res.LegalTrademarks = trademark != null ? trademark : " ";
                }
 
-               /* 
-                * Mono extension to support /win32icon in mcs
-                */
-               internal void DefineIconResource (string iconFileName)
-               {
-                       if (iconFileName == null)
-                               throw new ArgumentNullException ("iconFileName");
-                       if (iconFileName.Length == 0)
-                               throw new ArgumentException ("iconFileName");
-                       if (!File.Exists (iconFileName) || Directory.Exists (iconFileName))
-                               throw new FileNotFoundException ("File '" + iconFileName + "' does not exists or is a directory.");
-
-                       using (FileStream fs = new FileStream (iconFileName, FileMode.Open, FileAccess.Read)) {
-                               Win32IconFileReader reader = new Win32IconFileReader (fs);
-                               
-                               ICONDIRENTRY[] entries = reader.ReadIcons ();
-
-                               Win32IconResource[] icons = new Win32IconResource [entries.Length];
-                               for (int i = 0; i < entries.Length; ++i) {
-                                       icons [i] = new Win32IconResource (i + 1, 0, entries [i]);
-                                       AddUnmanagedResource (icons [i]);
-                               }
-
-                               Win32GroupIconResource group = new Win32GroupIconResource (1, 0, icons);
-                               AddUnmanagedResource (group);
-                       }
-               }
-
                private void DefineVersionInfoResourceImpl (string fileName)
                {
                        if (versioninfo_culture != null)
@@ -718,12 +643,9 @@ namespace System.Reflection.Emit
                                                else if (attrname == "System.Reflection.AssemblyTrademarkAttribute")
                                                        version_res.LegalTrademarks = cb.string_arg ();
                                                else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
-                                                       if (!IsCompilerContext)
-                                                               version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
+                                                       version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
                                                } else if (attrname == "System.Reflection.AssemblyFileVersionAttribute") {
-                                                       string fileversion = cb.string_arg ();
-                                                       if (!IsCompilerContext || fileversion != null && fileversion.Length != 0)
-                                                               version_res.FileVersion = fileversion;
+                                                       version_res.FileVersion = cb.string_arg ();
                                                } else if (attrname == "System.Reflection.AssemblyInformationalVersionAttribute")
                                                        version_res.ProductVersion = cb.string_arg ();
                                                else if (attrname == "System.Reflection.AssemblyTitleAttribute")
@@ -737,8 +659,7 @@ namespace System.Reflection.Emit
                                                string attrname = cb.Ctor.ReflectedType.FullName;
 
                                                if (attrname == "System.Reflection.AssemblyCultureAttribute") {
-                                                       if (!IsCompilerContext)
-                                                               version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
+                                                       version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
                                                } else if (attrname == "System.Reflection.AssemblyDescriptionAttribute")
                                                        version_res.Comments = cb.string_arg ();
                                        }
@@ -747,14 +668,7 @@ namespace System.Reflection.Emit
                        }
 
                        version_res.OriginalFilename = fileName;
-
-                       if (IsCompilerContext) {
-                               version_res.InternalName = fileName;
-                               if (version_res.ProductVersion.Trim ().Length == 0)
-                                       version_res.ProductVersion = version_res.FileVersion;
-                       } else {
-                               version_res.InternalName = Path.GetFileNameWithoutExtension (fileName);
-                       }
+                       version_res.InternalName = Path.GetFileNameWithoutExtension (fileName);
 
                        AddUnmanagedResource (version_res);
                }
@@ -821,6 +735,19 @@ namespace System.Reflection.Emit
                                }
                        }
 
+                       if (res != null) {
+                               List<Exception> exceptions = null;
+                               foreach (var type in res) {
+                                       if (type is TypeBuilder) {
+                                               if (exceptions == null)
+                                                       exceptions = new List <Exception> ();
+                                               exceptions.Add (new TypeLoadException (string.Format ("Type '{0}' is not finished", type.FullName))); 
+                                       }
+                               }
+                               if (exceptions != null)
+                                       throw new ReflectionTypeLoadException (new Type [exceptions.Count], exceptions.ToArray ());
+                       }
+                       
                        return res == null ? Type.EmptyTypes : res;
                }
 
@@ -839,15 +766,6 @@ namespace System.Reflection.Emit
                        throw not_supported ();
                }
 
-               /*
-                * This is set when the the AssemblyBuilder is created by (g)mcs
-                * or vbnc.
-                */
-               internal bool IsCompilerContext
-               {
-                       get { return is_compiler_context; }
-               }
-
                internal bool IsSave {
                        get {
                                return access != (uint)AssemblyBuilderAccess.Run;
@@ -864,7 +782,13 @@ namespace System.Reflection.Emit
 
                        }
                }
-
+/*
+               internal bool IsCollectible {
+                       get {
+                               return access == (uint)AssemblyBuilderAccess.RunAndCollect;
+                       }
+               }
+*/
                internal string AssemblyDir {
                        get {
                                return dir;
@@ -935,7 +859,7 @@ namespace System.Reflection.Emit
                         */
                        if ((entry_point != null) && entry_point.DeclaringType.Module != mainModule) {
                                Type[] paramTypes;
-                               if (entry_point.GetParameters ().Length == 1)
+                               if (entry_point.GetParametersCount () == 1)
                                        paramTypes = new Type [] { typeof (string) };
                                else
                                        paramTypes = Type.EmptyTypes;
@@ -1000,37 +924,6 @@ namespace System.Reflection.Emit
                        if (customBuilder == null)
                                throw new ArgumentNullException ("customBuilder");
 
-                       if (IsCompilerContext) {
-                               string attrname = customBuilder.Ctor.ReflectedType.FullName;
-                               byte [] data;
-                               int pos;
-
-                               if (attrname == "System.Reflection.AssemblyVersionAttribute") {
-                                       version = create_assembly_version (customBuilder.string_arg ());
-                                       return;
-                               } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
-                                       culture = GetCultureString (customBuilder.string_arg ());
-                               } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
-                                       data = customBuilder.Data;
-                                       pos = 2;
-                                       algid = (uint) data [pos];
-                                       algid |= ((uint) data [pos + 1]) << 8;
-                                       algid |= ((uint) data [pos + 2]) << 16;
-                                       algid |= ((uint) data [pos + 3]) << 24;
-                               } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
-                                       data = customBuilder.Data;
-                                       pos = 2;
-                                       flags |= (uint) data [pos];
-                                       flags |= ((uint) data [pos + 1]) << 8;
-                                       flags |= ((uint) data [pos + 2]) << 16;
-                                       flags |= ((uint) data [pos + 3]) << 24;
-
-                                       // ignore PublicKey flag if assembly is not strongnamed
-                                       if (sn == null)
-                                               flags &= ~(uint) AssemblyNameFlags.PublicKey;
-                               }
-                       }
-
                        if (cattrs != null) {
                                CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
                                cattrs.CopyTo (new_array, 0);
@@ -1052,18 +945,6 @@ namespace System.Reflection.Emit
                        SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
                }
 
-               internal void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type) {
-                       this.corlib_object_type = corlib_object_type;
-                       this.corlib_value_type = corlib_value_type;
-                       this.corlib_enum_type = corlib_enum_type;
-               }
-
-               internal void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type, Type corlib_void_type)
-               {
-                       SetCorlibTypeBuilders (corlib_object_type, corlib_value_type, corlib_enum_type);
-                       this.corlib_void_type = corlib_void_type;
-               }
-
                private Exception not_supported () {
                        // Strange message but this is what MS.NET prints...
                        return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
@@ -1164,16 +1045,7 @@ namespace System.Reflection.Emit
                /*Warning, @typeArguments must be a mscorlib internal array. So make a copy before passing it in*/
                internal Type MakeGenericType (Type gtd, Type[] typeArguments)
                {
-                       if (!IsCompilerContext)
-                               return new MonoGenericClass (gtd, typeArguments);
-
-                       GenericInstanceKey key = new GenericInstanceKey (gtd, typeArguments);
-                       MonoGenericClass res = (MonoGenericClass)generic_instances [key];
-                       if (res == null) {
-                               res = new MonoGenericClass (gtd, typeArguments);
-                               generic_instances [key] = res;
-                       }
-                       return res;
+                       return new MonoGenericClass (gtd, typeArguments);
                }
 
                void _AssemblyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
@@ -1195,5 +1067,128 @@ namespace System.Reflection.Emit
                {
                        throw new NotImplementedException ();
                }
+
+#if NET_4_0
+               public override Type GetType (string name, bool throwOnError, bool ignoreCase)
+               {
+                       if (name == null)
+                               throw new ArgumentNullException (name);
+                       if (name.Length == 0)
+                       throw new ArgumentException ("name", "Name cannot be empty");
+
+                       var res = InternalGetType (null, name, throwOnError, ignoreCase);
+                       if (res is TypeBuilder) {
+                               if (throwOnError)
+                                       throw new TypeLoadException (string.Format ("Could not load type '{0}' from assembly '{1}'", name, this.name));
+                               return null;
+                       }
+                       return res;
+               }
+
+               public override Module GetModule (String name)
+               {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       if (name.Length == 0)
+                               throw new ArgumentException ("Name can't be empty");
+
+                       if (modules == null)
+                               return null;
+
+                       foreach (Module module in modules) {
+                               if (module.ScopeName == name)
+                                       return module;
+                       }
+
+                       return null;
+               }
+
+               public override Module[] GetModules (bool getResourceModules)
+               {
+                       Module[] modules = GetModulesInternal ();
+
+                       if (!getResourceModules) {
+                               var result = new List<Module> (modules.Length);
+                               foreach (Module m in modules)
+                                       if (!m.IsResource ())
+                                               result.Add (m);
+                               return result.ToArray ();
+                       }
+                       return modules;
+               }
+
+               public override AssemblyName GetName (bool copiedName)
+               {
+                       return base.GetName (copiedName);
+               }
+
+               [MonoTODO ("This always returns an empty array")]
+               public override AssemblyName[] GetReferencedAssemblies () {
+                       return GetReferencedAssemblies (this);
+               }
+
+               public override Module[] GetLoadedModules (bool getResourceModules)
+               {
+                       return GetModules (getResourceModules);
+               }
+
+               //FIXME MS has issues loading satelite assemblies from SRE
+               public override Assembly GetSatelliteAssembly (CultureInfo culture)
+               {
+                       return GetSatelliteAssembly (culture, null, true);
+               }
+
+               //FIXME MS has issues loading satelite assemblies from SRE
+               public override Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
+               {
+                       return GetSatelliteAssembly (culture, version, true);
+               }
+
+               public override Module ManifestModule {
+                       get {
+                               return GetManifestModule ();
+                       }
+               }
+
+               public override bool GlobalAssemblyCache {
+                       get {
+                               return false;
+                       }
+               }
+
+               public override bool IsDynamic {
+                       get { return true; }
+               }
+
+               public override bool Equals (object obj)
+               {
+                       return base.Equals (obj);
+               }
+
+               public override int GetHashCode ()
+               {
+                       return base.GetHashCode ();
+               }
+
+               public override bool IsDefined (Type attributeType, bool inherit)
+               {
+                       return base.IsDefined (attributeType, inherit);
+               }
+
+               public override object[] GetCustomAttributes (bool inherit)
+               {
+                       return base.GetCustomAttributes (inherit);
+               }
+
+               public override object[] GetCustomAttributes (Type attributeType, bool inherit)
+               {
+                       return base.GetCustomAttributes (attributeType, inherit);
+               }
+
+               public override string FullName {
+                       get { return base.FullName; }
+               }
+#endif
        }
 }
+#endif