2007-05-16 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / corlib / System.Reflection.Emit / TypeBuilder.cs
index 4781c729367ec3707c6786c2596ba3f16f588c84..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
 //
@@ -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,10 @@ 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
@@ -704,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 ();
@@ -898,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 ();
@@ -1339,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);
                }
 
@@ -1360,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);
@@ -1494,13 +1493,17 @@ namespace System.Reflection.Emit {
                        }
                }
 
+               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 ();
                        }
@@ -1518,11 +1521,6 @@ 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);