New tests.
[mono.git] / mcs / class / corlib / System.Reflection.Emit / TypeBuilder.cs
index 56e2df9620098965a343668e33c26c9a14a5ea1e..0a7be28f12e0fdf5cc4146d4913b26bd6bbf5c2e 100644 (file)
@@ -45,26 +45,25 @@ using System.Diagnostics.SymbolStore;
 
 namespace System.Reflection.Emit
 {
-#if NET_2_0
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_TypeBuilder))]
-#endif
        [ClassInterface (ClassInterfaceType.None)]
        public sealed class TypeBuilder : Type, _TypeBuilder
        {
+#pragma warning disable 169            
                #region Sync with reflection.h
                private string tname;
                private string nspace;
                private Type parent;
                private Type nesting_type;
-               private Type[] interfaces;
-               private int num_methods;
-               private MethodBuilder[] methods;
-               private ConstructorBuilder[] ctors;
-               private PropertyBuilder[] properties;
-               private int num_fields;
-               private FieldBuilder[] fields;
-               private EventBuilder[] events;
+               internal Type[] interfaces;
+               internal int num_methods;
+               internal MethodBuilder[] methods;
+               internal ConstructorBuilder[] ctors;
+               internal PropertyBuilder[] properties;
+               internal int num_fields;
+               internal FieldBuilder[] fields;
+               internal EventBuilder[] events;
                private CustomAttributeBuilder[] cattrs;
                internal TypeBuilder[] subtypes;
                internal TypeAttributes attrs;
@@ -73,20 +72,18 @@ namespace System.Reflection.Emit
                private int class_size;
                private PackingSize packing_size;
                private IntPtr generic_container;
-#if NET_2_0 || BOOTSTRAP_NET_2_0
                private GenericTypeParameterBuilder[] generic_params;
-#else
-               private Object generic_params; /* so offsets don't change */
-#endif
                private RefEmitPermissionSet[] permissions;
                private Type created;
                #endregion
+#pragma warning restore 169            
+               
                string fullname;
                bool createTypeCalled;
                private Type underlying_type;
 
                public const int UnspecifiedTypeSize = 0;
-
+               
                protected override TypeAttributes GetAttributeFlagsImpl ()
                {
                        return attrs;
@@ -107,13 +104,13 @@ namespace System.Reflection.Emit
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern EventInfo get_event_info (EventBuilder eb);
 
-               internal TypeBuilder (ModuleBuilder mb, TypeAttributes attr)
+               internal TypeBuilder (ModuleBuilder mb, TypeAttributes attr, int table_idx)
                {
                        this.parent = null;
                        this.attrs = attr;
                        this.class_size = UnspecifiedTypeSize;
-                       this.table_idx = 1;
-                       fullname = this.tname = "<Module>";
+                       this.table_idx = table_idx;
+                       fullname = this.tname = table_idx == 1 ? "<Module>" : "type_" + table_idx.ToString ();
                        this.nspace = String.Empty;
                        pmodule = mb;
                        setup_internal_class (this);
@@ -176,7 +173,8 @@ namespace System.Reflection.Emit
                        get { return nesting_type; }
                }
 
-/*             public override bool IsSubclassOf (Type c)
+               [ComVisible (true)]
+               public override bool IsSubclassOf (Type c)
                {
                        Type t;
                        if (c == null)
@@ -190,14 +188,14 @@ namespace System.Reflection.Emit
                                t = t.BaseType;
                        }
                        return false;
-               }*/
+               }
 
                public override Type UnderlyingSystemType {
                        get {
                                if (is_created)
                                        return created.UnderlyingSystemType;
 
-                               if (IsEnum && !IsCompilerContext) {
+                               if (!IsCompilerContext && IsEnum) {
                                        if (underlying_type != null)
                                                return underlying_type;
                                        throw new InvalidOperationException (
@@ -256,6 +254,7 @@ namespace System.Reflection.Emit
 
                public void AddDeclarativeSecurity (SecurityAction action, PermissionSet pset)
                {
+#if !NET_2_1
                        if (pset == null)
                                throw new ArgumentNullException ("pset");
                        if ((action == SecurityAction.RequestMinimum) ||
@@ -280,11 +279,10 @@ namespace System.Reflection.Emit
 
                        permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ());
                        attrs |= TypeAttributes.HasSecurity;
+#endif
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public void AddInterfaceImplementation (Type interfaceType)
                {
                        if (interfaceType == null)
@@ -363,6 +361,8 @@ namespace System.Reflection.Emit
 
                public override bool IsDefined (Type attributeType, bool inherit)
                {
+                       if (!is_created && !IsCompilerContext)
+                               throw new NotSupportedException ();
                        /*
                         * MS throws NotSupported here, but we can't because some corlib
                         * classes make calls to IsDefined.
@@ -429,9 +429,7 @@ namespace System.Reflection.Emit
                        return res;
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces)
                {
                        return DefineNestedType (name, attr, parent, interfaces, PackingSize.Unspecified, UnspecifiedTypeSize);
@@ -447,23 +445,14 @@ namespace System.Reflection.Emit
                        return DefineNestedType (name, attr, parent, null, packSize, UnspecifiedTypeSize);
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes)
                {
                        return DefineConstructor (attributes, callingConvention, parameterTypes, null, null);
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               public
-#else
-               internal
-#endif
-               ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
+               public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
                {
                        check_not_created ();
                        ConstructorBuilder cb = new ConstructorBuilder (this, attributes,
@@ -481,9 +470,7 @@ namespace System.Reflection.Emit
                        return cb;
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public ConstructorBuilder DefineDefaultConstructor (MethodAttributes attributes)
                {
                        Type parent_type;
@@ -493,6 +480,7 @@ namespace System.Reflection.Emit
                        else
                                parent_type = pmodule.assemblyb.corlib_object_type;
 
+                       parent_type = parent_type.InternalResolve ();
                        ConstructorInfo parent_constructor =
                                parent_type.GetConstructor (
                                        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
@@ -540,12 +528,7 @@ namespace System.Reflection.Emit
                                null, null, parameterTypes, null, null);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               public
-#else
-               internal
-#endif
-               MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
+               public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
                {
                        check_name ("name", name);
                        check_not_created ();
@@ -574,12 +557,7 @@ namespace System.Reflection.Emit
                                null, null, nativeCallConv, nativeCharSet);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               public
-#else
-               internal
-#endif
-               MethodBuilder DefinePInvokeMethod (
+               public MethodBuilder DefinePInvokeMethod (
                                                string name, 
                                                string dllName, 
                                                string entryName, MethodAttributes attributes, 
@@ -627,7 +605,6 @@ namespace System.Reflection.Emit
                                nativeCallConv, nativeCharSet);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
                public MethodBuilder DefineMethod (string name, MethodAttributes attributes)
                {
                        return DefineMethod (name, attributes, CallingConventions.Standard);
@@ -637,7 +614,6 @@ namespace System.Reflection.Emit
                {
                        return DefineMethod (name, attributes, callingConvention, null, null);
                }
-#endif
 
                public void DefineMethodOverride (MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)
                {
@@ -646,6 +622,8 @@ namespace System.Reflection.Emit
                        if (methodInfoDeclaration == null)
                                throw new ArgumentNullException ("methodInfoDeclaration");
                        check_not_created ();
+                       if (methodInfoBody.DeclaringType != this)
+                               throw new ArgumentException ("method body must belong to this type");
 
                        if (methodInfoBody is MethodBuilder) {
                                MethodBuilder mb = (MethodBuilder)methodInfoBody;
@@ -658,12 +636,7 @@ namespace System.Reflection.Emit
                        return DefineField (fieldName, type, null, null, attributes);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               public
-#else
-               internal
-#endif
-               FieldBuilder DefineField (string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
+               public FieldBuilder DefineField (string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
                {
                        check_name ("fieldName", fieldName);
                        if (type == typeof (void))
@@ -699,12 +672,7 @@ namespace System.Reflection.Emit
                        return DefineProperty (name, attributes, returnType, null, null, parameterTypes, null, null);
                }
 
-#if NET_2_0
-               public 
-#else
-               internal
-#endif
-               PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
+               public  PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
                {
                        check_name ("name", name);
                        if (parameterTypes != null)
@@ -727,9 +695,7 @@ namespace System.Reflection.Emit
                        return res;
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public ConstructorBuilder DefineTypeInitializer()
                {
                        return DefineConstructor (MethodAttributes.Public |
@@ -800,6 +766,15 @@ namespace System.Reflection.Emit
                                }
                        }
 
+                       //
+                       // On classes, define a default constructor if not provided
+                       //
+                       if (!(IsInterface || IsValueType) && (ctors == null) && (tname != "<Module>") && 
+                               (GetAttributeFlagsImpl () & TypeAttributes.Abstract | TypeAttributes.Sealed) != (TypeAttributes.Abstract | TypeAttributes.Sealed) && !has_ctor_method ())
+                               DefineDefaultConstructor (MethodAttributes.Public);
+
+                       createTypeCalled = true;
+
                        if ((parent != null) && parent.IsSealed)
                                throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because the parent type is sealed.");
 
@@ -807,26 +782,21 @@ namespace System.Reflection.Emit
                                throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because it is an enum with methods.");
 
                        if (methods != null) {
+                               bool is_concrete = !IsAbstract;
                                for (int i = 0; i < num_methods; ++i) {
                                        MethodBuilder mb = (MethodBuilder)(methods[i]);
+                                       if (is_concrete && mb.IsAbstract)
+                                               throw new InvalidOperationException ("Type is concrete but has abstract method " + mb);
                                        mb.check_override ();
                                        mb.fixup ();
                                }
                        }
 
-                       //
-                       // On classes, define a default constructor if not provided
-                       //
-                       if (!(IsInterface || IsValueType) && (ctors == null) && (tname != "<Module>") && 
-                               (GetAttributeFlagsImpl () & TypeAttributes.Abstract | TypeAttributes.Sealed) != (TypeAttributes.Abstract | TypeAttributes.Sealed) && !has_ctor_method ())
-                               DefineDefaultConstructor (MethodAttributes.Public);
-
                        if (ctors != null){
                                foreach (ConstructorBuilder ctor in ctors) 
                                        ctor.fixup ();
                        }
 
-                       createTypeCalled = true;
                        created = create_runtime_class (this);
                        if (created != null)
                                return created;
@@ -857,14 +827,20 @@ namespace System.Reflection.Emit
                        }
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
                {
                        if (is_created)
                                return created.GetConstructors (bindingAttr);
 
+                       if (!IsCompilerContext)
+                               throw new NotSupportedException ();
+
+                       return GetConstructorsInternal (bindingAttr);
+               }
+
+               internal ConstructorInfo[] GetConstructorsInternal (BindingFlags bindingAttr)
+               {
                        if (ctors == null)
                                return new ConstructorInfo [0];
                        ArrayList l = new ArrayList ();
@@ -902,8 +878,7 @@ namespace System.Reflection.Emit
 
                public override Type GetElementType ()
                {
-                       check_created ();
-                       return created.GetElementType ();
+                       throw new NotSupportedException ();
                }
 
                public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
@@ -920,13 +895,11 @@ namespace System.Reflection.Emit
 
                public override EventInfo[] GetEvents (BindingFlags bindingAttr)
                {
-                       /* FIXME: mcs calls this
-                          check_created ();
-                       */
-                       if (!is_created)
-                               return new EventInfo [0];
-                       else
+                       if (is_created)
                                return created.GetEvents (bindingAttr);
+                       if (!IsCompilerContext)
+                               throw new NotSupportedException ();
+                       return new EventInfo [0]; /*FIXME shouldn't we return the events here?*/
                }
 
                // This is only used from MonoGenericInst.initialize().
@@ -1068,6 +1041,9 @@ namespace System.Reflection.Emit
                
                public override Type[] GetInterfaces ()
                {
+                       if (is_created)
+                               return created.GetInterfaces ();
+
                        if (interfaces != null) {
                                Type[] ret = new Type [interfaces.Length];
                                interfaces.CopyTo (ret, 0);
@@ -1115,11 +1091,7 @@ namespace System.Reflection.Emit
                                                match = (bindingAttr & BindingFlags.Public) != 0;
                                                break;
                                        case MethodAttributes.Assembly:
-#if NET_2_0
                                                match = (bindingAttr & BindingFlags.NonPublic) != 0;
-#else
-                                               match = false;
-#endif
                                                break;
                                        case MethodAttributes.Private:
                                                match = false;
@@ -1243,11 +1215,32 @@ namespace System.Reflection.Emit
                public override Type GetNestedType (string name, BindingFlags bindingAttr)
                {
                        check_created ();
-                       return created.GetNestedType (name, bindingAttr);
+
+                       if (subtypes == null)
+                               return null;
+
+                       foreach (TypeBuilder t in subtypes) {
+                               if (!t.is_created)
+                                       continue;
+                               if ((t.attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) {
+                                       if ((bindingAttr & BindingFlags.Public) == 0)
+                                               continue;
+                               } else {
+                                       if ((bindingAttr & BindingFlags.NonPublic) == 0)
+                                               continue;
+                               }
+                               if (t.Name == name)
+                                       return t.created;
+                       }
+
+                       return null;
                }
 
                public override Type[] GetNestedTypes (BindingFlags bindingAttr)
                {
+                       if (!is_created && !IsCompilerContext)
+                               throw new NotSupportedException ();
+
                        bool match;
                        ArrayList result = new ArrayList ();
 
@@ -1324,13 +1317,10 @@ namespace System.Reflection.Emit
 
                protected override bool HasElementTypeImpl ()
                {
-#if NET_2_0
                        // a TypeBuilder can never represent an array, pointer
                        if (!is_created)
                                return false;
-#else
-                       check_created ();
-#endif
+
                        return created.HasElementType;
                }
 
@@ -1342,13 +1332,12 @@ namespace System.Reflection.Emit
 
                protected override bool IsArrayImpl ()
                {
-                       return Type.IsArrayImpl (this);
+                       return false; /*A TypeBuilder never represents a non typedef type.*/
                }
 
                protected override bool IsByRefImpl ()
                {
-                       // FIXME
-                       return false;
+                       return false; /*A TypeBuilder never represents a non typedef type.*/
                }
 
                protected override bool IsCOMObjectImpl ()
@@ -1358,8 +1347,7 @@ namespace System.Reflection.Emit
 
                protected override bool IsPointerImpl ()
                {
-                       // FIXME
-                       return false;
+                       return false; /*A TypeBuilder never represents a non typedef type.*/
                }
 
                protected override bool IsPrimitiveImpl ()
@@ -1371,49 +1359,75 @@ namespace System.Reflection.Emit
                // FIXME: I doubt just removing this still works.
                protected override bool IsValueTypeImpl ()
                {
-                       return ((type_is_subtype_of (this, pmodule.assemblyb.corlib_value_type, false) || type_is_subtype_of (this, typeof(System.ValueType), false)) &&
-                               this != pmodule.assemblyb.corlib_value_type &&
-                               this != pmodule.assemblyb.corlib_enum_type);
+                       if (this == pmodule.assemblyb.corlib_value_type || this == pmodule.assemblyb.corlib_enum_type)
+                               return false;
+                       Type parent_type = parent;
+                       while (parent_type != null) {
+                               if (parent_type == pmodule.assemblyb.corlib_value_type)
+                                       return true;
+                               parent_type = parent_type.BaseType;
+                       }
+                       return false;
                }
                
-#if NET_2_0
-               [MonoTODO]
                public override Type MakeArrayType ()
                {
-                       return base.MakeArrayType ();
+                       return new ArrayType (this, 0);
                }
 
-               [MonoTODO]
                public override Type MakeArrayType (int rank)
                {
-                       return base.MakeArrayType (rank);
+                       if (rank < 1)
+                               throw new IndexOutOfRangeException ();
+                       return new ArrayType (this, rank);
                }
 
-               [MonoTODO]
                public override Type MakeByRefType ()
                {
-                       return base.MakeByRefType ();
+                       return new ByRefType (this);
                }
 
-               [MonoTODO]
                public override Type MakeGenericType (params Type [] typeArguments)
                {
-                       return base.MakeGenericType (typeArguments);
+                       //return base.MakeGenericType (typeArguments);
+
+                       if (!IsGenericTypeDefinition)
+                               throw new InvalidOperationException ("not a generic type definition");
+                       if (typeArguments == null)
+                               throw new ArgumentNullException ("typeArguments");
+
+                       if (generic_params.Length != typeArguments.Length)
+                               throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", generic_params.Length, typeArguments.Length), "typeArguments");
+
+                       foreach (Type t in typeArguments) {
+                               if (t == null)
+                                       throw new ArgumentNullException ("typeArguments");                              
+                       }
+
+                       Type[] copy = new Type [typeArguments.Length];
+                       typeArguments.CopyTo (copy, 0);
+                       return pmodule.assemblyb.MakeGenericType (this, copy);
                }
 
-               [MonoTODO]
                public override Type MakePointerType ()
                {
-                       return base.MakePointerType ();
+                       return new PointerType (this);
                }
-#endif
-               
+
                public override RuntimeTypeHandle TypeHandle {
                        get {
                                check_created ();
                                return created.TypeHandle;
                        }
                }
+               
+               //
+               // Used internally by mcs only
+               //
+               internal void SetCharSet (TypeAttributes ta)
+               {
+                       this.attrs = ta;
+               }
 
                public void SetCustomAttribute (CustomAttributeBuilder customBuilder)
                {
@@ -1501,11 +1515,9 @@ 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;
@@ -1527,9 +1539,7 @@ namespace System.Reflection.Emit
                        }
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute)
                {
                        SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
@@ -1564,8 +1574,6 @@ namespace System.Reflection.Emit
                        return res;
                }
 
-               static int UnmanagedDataCount = 0;
-               
                public FieldBuilder DefineUninitializedData (string name, int size, FieldAttributes attributes)
                {
                        if (name == null)
@@ -1598,7 +1606,6 @@ namespace System.Reflection.Emit
                {
                        check_not_created ();
 
-#if NET_2_0
                        if (parent == null) {
                                if ((attrs & TypeAttributes.Interface) != 0) {
                                        if ((attrs & TypeAttributes.Abstract) == 0)
@@ -1610,11 +1617,6 @@ namespace System.Reflection.Emit
                        } else {
                                this.parent = parent;
                        }
-#else
-                       if (parent == null)
-                               throw new ArgumentNullException ("parent");
-                       this.parent = parent;
-#endif
 
                        // will just set the parent-related bits if called a second time
                        setup_internal_class (this);
@@ -1624,9 +1626,7 @@ namespace System.Reflection.Emit
                        return pmodule.get_next_table_index (obj, table, inc);
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
                public override InterfaceMapping GetInterfaceMap (Type interfaceType)
                {
                        if (created == null)
@@ -1635,15 +1635,21 @@ namespace System.Reflection.Emit
                        return created.GetInterfaceMap (interfaceType);
                }
 
-               internal bool IsCompilerContext {
+               internal override bool IsCompilerContext {
                        get {
                                return pmodule.assemblyb.IsCompilerContext;
                        }
                }
 
+               internal override Type InternalResolve ()
+               {
+                       check_created ();
+                       return created;
+               }
+
                internal bool is_created {
                        get {
-                               return created != null;
+                               return createTypeCalled;
                        }
                }
 
@@ -1685,15 +1691,6 @@ namespace System.Reflection.Emit
                        return base.IsAssignableFrom (c);
                }
 
-#if NET_2_0
-               [ComVisible (true)]
-#endif
-               [MonoTODO]
-               public override bool IsSubclassOf (Type c)
-               {
-                       return base.IsSubclassOf (c);
-               }
-
                [MonoTODO ("arrays")]
                internal bool IsAssignableTo (Type c)
                {
@@ -1721,7 +1718,6 @@ namespace System.Reflection.Emit
                                return c.IsAssignableFrom (parent);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
                public bool IsCreated ()
                {
                        return is_created;
@@ -1729,17 +1725,18 @@ namespace System.Reflection.Emit
 
                public override Type[] GetGenericArguments ()
                {
-                       if (generic_params != null)
-                               return generic_params;
-
-                       throw new InvalidOperationException ();
+                       if (generic_params == null)
+                               return null;
+                       Type[] args = new Type [generic_params.Length];
+                       generic_params.CopyTo (args, 0);
+                       return args;
                }
 
                public override Type GetGenericTypeDefinition ()
                {
-                       create_generic_class ();
-
-                       return base.GetGenericTypeDefinition ();
+                       if (generic_params == null)
+                               throw new InvalidOperationException ("Type is not generic");
+                       return this;
                }
 
                public override bool ContainsGenericParameters {
@@ -1753,6 +1750,10 @@ namespace System.Reflection.Emit
                        get;
                }
 
+               public override GenericParameterAttributes GenericParameterAttributes {
+                       get { return GenericParameterAttributes.None; }
+               }
+
                public override bool IsGenericTypeDefinition {
                        get {
                                return generic_params != null;
@@ -1766,35 +1767,56 @@ namespace System.Reflection.Emit
                [MonoTODO]
                public override int GenericParameterPosition {
                        get {
-                               throw new NotImplementedException ();
+                               return 0;
                        }
                }
 
                public override MethodBase DeclaringMethod {
                        get {
-                               throw new NotImplementedException ();
+                               return null;
                        }
                }
 
                public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
                {
+                       if (names == null)
+                               throw new ArgumentNullException ("names");
+                       if (names.Length == 0)
+                               throw new ArgumentException ("names");
+
                        setup_generic_class ();
 
                        generic_params = new GenericTypeParameterBuilder [names.Length];
-                       for (int i = 0; i < names.Length; i++)
-                               generic_params [i] = new GenericTypeParameterBuilder (
-                                       this, null, names [i], i);
+                       for (int i = 0; i < names.Length; i++) {
+                               string item = names [i];
+                               if (item == null)
+                                       throw new ArgumentNullException ("names");
+                               generic_params [i] = new GenericTypeParameterBuilder (this, null, item, i);
+                       }
 
                        return generic_params;
                }
 
                public static ConstructorInfo GetConstructor (Type type, ConstructorInfo constructor)
                {
+                       /*FIXME I would expect the same checks of GetMethod here*/
+                       if (type == null)
+                               throw new ArgumentException ("Type is not generic", "type");
+
+                       if (!type.IsGenericType)
+                               throw new ArgumentException ("Type is not a generic type", "type");
+
+                       if (type.IsGenericTypeDefinition)
+                               throw new ArgumentException ("Type cannot be a generic type definition", "type");
+
+                       if (constructor == null)
+                               throw new NullReferenceException (); //MS raises this instead of an ArgumentNullException
+
                        ConstructorInfo res = type.GetConstructor (constructor);
                        if (res == null)
-                               throw new System.Exception ("constructor not found");
-                       else
-                               return res;
+                               throw new ArgumentException ("constructor not found");
+
+                       return res;
                }
 
                static bool IsValidGetMethodType (Type type)
@@ -1822,6 +1844,9 @@ namespace System.Reflection.Emit
                        if (!IsValidGetMethodType (type))
                                throw new ArgumentException ("type is not TypeBuilder but " + type.GetType (), "type");
 
+                       if (type is TypeBuilder && type.ContainsGenericParameters)
+                               type = type.MakeGenericType (type.GetGenericArguments ());
+
                        if (!type.IsGenericType)
                                throw new ArgumentException ("type is not a generic type", "type");
 
@@ -1829,6 +1854,8 @@ namespace System.Reflection.Emit
                                throw new ArgumentException ("method declaring type is not a generic type definition", "method");
                        if (method.DeclaringType != type.GetGenericTypeDefinition ())
                                throw new ArgumentException ("method declaring type is not the generic type definition of type", "method");
+                       if (method == null)
+                               throw new NullReferenceException (); //MS raises this instead of an ArgumentNullException
 
                        MethodInfo res = type.GetMethod (method);
                        if (res == null)
@@ -1839,13 +1866,21 @@ namespace System.Reflection.Emit
 
                public static FieldInfo GetField (Type type, FieldInfo field)
                {
+                       if (!type.IsGenericType)
+                               throw new ArgumentException ("Type is not a generic type", "type");
+
+                       if (type.IsGenericTypeDefinition)
+                               throw new ArgumentException ("Type cannot be a generic type definition", "type");
+
+                       if (field is FieldOnTypeBuilderInst)
+                               throw new ArgumentException ("The specified field must be declared on a generic type definition.", "field");
+
                        FieldInfo res = type.GetField (field);
                        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)
                {