2007-05-16 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / corlib / System.Reflection.Emit / TypeBuilder.cs
index 34e3837ce65a6569a618137d31c2039b44b903ac..141046081c0961a2d49960dc6f8a5df99559ae05 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Paolo Molaro (lupus@ximian.com)
+//   Marek Safar (marek.safar@gmail.com)
 //
 // (C) 2001 Ximian, Inc.  http://www.ximian.com
 //
@@ -45,10 +46,10 @@ using System.Diagnostics.SymbolStore;
 namespace System.Reflection.Emit {
 #if NET_2_0
        [ComVisible (true)]
-       [ClassInterfaceAttribute (ClassInterfaceType.None)]
-       [ComDefaultInterfaceAttribute (typeof (_TypeBuilder))]
+       [ComDefaultInterface (typeof (_TypeBuilder))]
 #endif
-       public sealed class TypeBuilder : Type {
+       [ClassInterface (ClassInterfaceType.None)]
+       public sealed class TypeBuilder : Type, _TypeBuilder {
        #region Sync with reflection.h
        private string tname;
        private string nspace;
@@ -107,7 +108,7 @@ namespace System.Reflection.Emit {
                        this.class_size = UnspecifiedTypeSize;
                        this.table_idx = 1;
                        fullname = this.tname = "<Module>";
-                       this.nspace = "";
+                       this.nspace = String.Empty;
                        pmodule = mb;
                        setup_internal_class (this);
                }
@@ -125,13 +126,14 @@ namespace System.Reflection.Emit {
                                this.nspace = name.Substring (0, sep_index);
                        } else {
                                this.tname = name;
-                               this.nspace = "";
+                               this.nspace = String.Empty;
                        }
                        if (interfaces != null) {
                                this.interfaces = new Type[interfaces.Length];
                                System.Array.Copy (interfaces, this.interfaces, interfaces.Length);
                        }
                        pmodule = mb;
+
                        // skip .<Module> ?
                        table_idx = mb.get_next_table_index (this, 0x02, true);
                        setup_internal_class (this);
@@ -170,28 +172,9 @@ namespace System.Reflection.Emit {
                        return false;
                }*/
 
-               [MonoTODO]
                public override Type UnderlyingSystemType {
                        get {
-
-                               // Return this as requested by Zoltan.
-                               
                                return this;
-
-#if false
-                               // Dont know what to do with the rest, should be killed:
-                               // See bug: 75008.
-                               //
-                               ////// This should return the type itself for non-enum types but 
-                               ////// that breaks mcs.
-                               if (fields != null) {
-                                       foreach (FieldBuilder f in fields) {
-                                               if ((f != null) && (f.Attributes & FieldAttributes.Static) == 0)
-                                                       return f.FieldType;
-                                       }
-                               }
-                               throw new InvalidOperationException ("Underlying type information on enumeration is not specified.");
-#endif
                        }
                }
 
@@ -239,7 +222,7 @@ namespace System.Reflection.Emit {
                        if ((action == SecurityAction.RequestMinimum) ||
                                (action == SecurityAction.RequestOptional) ||
                                (action == SecurityAction.RequestRefuse))
-                               throw new ArgumentException ("Request* values are not permitted", "action");
+                               throw new ArgumentOutOfRangeException ("Request* values are not permitted", "action");
 
                        check_not_created ();
 
@@ -502,7 +485,8 @@ namespace System.Reflection.Emit {
                        check_not_created ();
                        if (IsInterface && (
                                !((attributes & MethodAttributes.Abstract) != 0) || 
-                               !((attributes & MethodAttributes.Virtual) != 0)))
+                               !((attributes & MethodAttributes.Virtual) != 0)) &&
+                               !(((attributes & MethodAttributes.Static) != 0)))
                                throw new ArgumentException ("attributes", "Interface method must be abstract and virtual.");
 
                        if (returnType == null)
@@ -568,7 +552,7 @@ namespace System.Reflection.Emit {
                                nativeCallConv, nativeCharSet);
                }
 
-#if NET_2_0
+#if NET_2_0 || BOOTSTRAP_NET_2_0
                public MethodBuilder DefineMethod (string name, MethodAttributes attributes) {
                        return DefineMethod (name, attributes, CallingConventions.Standard);
                }
@@ -680,6 +664,12 @@ namespace System.Reflection.Emit {
                        if (created != null)
                                return created;
 
+                       if (!IsInterface && (parent == null) && (this != pmodule.assemblyb.corlib_object_type) && (FullName != "<Module>")) {
+                               SetParent (pmodule.assemblyb.corlib_object_type);
+                       }
+
+                       create_generic_class ();
+
                        // Fire TypeResolve events for fields whose type is an unfinished
                        // value type.
                        if (fields != null) {
@@ -702,6 +692,9 @@ namespace System.Reflection.Emit {
                                }
                        }
 
+                       if ((parent != null) && parent.IsSealed)
+                               throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because the parent type is sealed.");
+
                        if (methods != null) {
                                for (int i = 0; i < num_methods; ++i)
                                        ((MethodBuilder)(methods[i])).fixup ();
@@ -896,6 +889,9 @@ namespace System.Reflection.Emit {
                }
 
                public override FieldInfo[] GetFields (BindingFlags bindingAttr) {
+                       if (created != null)
+                               return created.GetFields (bindingAttr);
+
                        if (fields == null)
                                return new FieldInfo [0];
                        ArrayList l = new ArrayList ();
@@ -973,7 +969,7 @@ namespace System.Reflection.Emit {
                        }
                        else
                                candidates = methods;
-                                       
+
                        if (candidates == null)
                                return new MethodInfo [0];
 
@@ -1273,10 +1269,19 @@ namespace System.Reflection.Emit {
                                        }
                                }
                                return;
+#if NET_2_0
+                       } else if (attrname == "System.Runtime.CompilerServices.SpecialNameAttribute") {
+                               attrs |= TypeAttributes.SpecialName;
+                               return;
+#endif
                        } else if (attrname == "System.SerializableAttribute") {
                                attrs |= TypeAttributes.Serializable;
                                return;
+                       } else if (attrname == "System.Runtime.InteropServices.ComImportAttribute") {
+                               attrs |= TypeAttributes.Import;
+                               return;
                        }
+
                        if (cattrs != null) {
                                CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
                                cattrs.CopyTo (new_array, 0);
@@ -1328,18 +1333,22 @@ namespace System.Reflection.Emit {
 
                static int UnmanagedDataCount = 0;
                
-               public FieldBuilder DefineUninitializedData( string name, int size, FieldAttributes attributes) {
+               public FieldBuilder DefineUninitializedData( string name, int size, FieldAttributes attributes)
+               {
                        check_name ("name", name);
                        if ((size <= 0) || (size > 0x3f0000))
                                throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000");
                        check_not_created ();
 
-                       string s = "$ArrayType$"+UnmanagedDataCount.ToString();
-                       UnmanagedDataCount++;
-                       TypeBuilder datablobtype = DefineNestedType (s,
-                               TypeAttributes.NestedPrivate|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed,
-                               pmodule.assemblyb.corlib_value_type, null, PackingSize.Size1, size);
-                       datablobtype.CreateType ();
+                       string typeName = "$ArrayType$" + size;
+                       Type datablobtype = pmodule.GetRegisteredType (fullname + "+" + typeName);
+                       if (datablobtype == null) {
+                               TypeBuilder tb = DefineNestedType (typeName,
+                                       TypeAttributes.NestedPrivate|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed,
+                                       pmodule.assemblyb.corlib_value_type, null, PackingSize.Size1, size);
+                               tb.CreateType ();
+                               datablobtype = tb;
+                       }
                        return DefineField (name, datablobtype, attributes|FieldAttributes.Static|FieldAttributes.HasFieldRVA);
                }
 
@@ -1349,10 +1358,11 @@ namespace System.Reflection.Emit {
                        }
                }
                public void SetParent (Type parentType) {
-                       if (parentType == null)
-                               throw new ArgumentNullException ("parentType");
                        check_not_created ();
 
+                       if (parentType == null && (attrs & TypeAttributes.Interface) == 0)
+                               throw new ArgumentNullException ("parentType");
+
                        parent = parentType;
                        // will just set the parent-related bits if called a second time
                        setup_internal_class (this);
@@ -1399,10 +1409,10 @@ namespace System.Reflection.Emit {
                {
                        if (name == null)
                                throw new ArgumentNullException (argName);
-                       if (name == "")
-                               throw new ArgumentException (argName, "Empty name is not legal.");
+                       if (name.Length == 0)
+                               throw new ArgumentException ("Empty name is not legal", argName);
                        if (name.IndexOf ((char)0) != -1)
-                               throw new ArgumentException (argName, "Illegal name.");
+                               throw new ArgumentException ("Illegal name", argName);
                }
 
                public override String ToString ()
@@ -1466,12 +1476,6 @@ namespace System.Reflection.Emit {
                        return base.GetGenericTypeDefinition ();
                }
 
-               public override bool HasGenericArguments {
-                       get {
-                               throw new NotImplementedException ();
-                       }
-               }
-
                public override bool ContainsGenericParameters {
                        get {
                                return generic_params != null;
@@ -1483,13 +1487,23 @@ namespace System.Reflection.Emit {
                        get;
                }
 
+               public override bool IsGenericTypeDefinition {
+                       get {
+                               return generic_params != null;
+                       }
+               }
+
+               public override bool IsGenericType {
+                       get { return IsGenericTypeDefinition; }
+               }
+
                public override int GenericParameterPosition {
                        get {
                                throw new NotImplementedException ();
                        }
                }
 
-               public override MethodInfo DeclaringMethod {
+               public override MethodBase DeclaringMethod {
                        get {
                                throw new NotImplementedException ();
                        }
@@ -1507,10 +1521,52 @@ namespace System.Reflection.Emit {
                        return generic_params;
                }
 
-               public MethodBuilder DefineGenericMethod (string name, MethodAttributes attributes)
-               {
-                       return DefineMethod (name, attributes, CallingConventions.Standard, null, null);
-               }
+                public static ConstructorInfo GetConstructor (Type instanciated, ConstructorInfo ctor)
+                {
+                       ConstructorInfo res = instanciated.GetConstructor (ctor);
+                       if (res == null)
+                               throw new System.Exception ("constructor not found");
+                       else
+                               return res;
+                }
+
+                public static MethodInfo GetMethod (Type instanciated, MethodInfo meth)
+                {
+                       MethodInfo res = instanciated.GetMethod (meth);
+                       if (res == null)
+                               throw new System.Exception ("method not found");
+                       else
+                               return res;
+                }
+
+                public static FieldInfo GetField (Type instanciated, FieldInfo fld)
+                {
+                       FieldInfo res = instanciated.GetField (fld);
+                       if (res == null)
+                               throw new System.Exception ("field not found");
+                       else
+                               return res;
+                }
 #endif
+
+                void _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+                {
+                        throw new NotImplementedException ();
+                }
+
+                void _TypeBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
+                {
+                        throw new NotImplementedException ();
+                }
+
+                void _TypeBuilder.GetTypeInfoCount (out uint pcTInfo)
+                {
+                        throw new NotImplementedException ();
+                }
+
+                void _TypeBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+                {
+                        throw new NotImplementedException ();
+                }
        }
 }