3972192308d8082a7c6be66c929a8989b4a85dce
[mono.git] / mcs / class / corlib / System.Reflection.Emit / TypeBuilder.cs
1 //
2 // System.Reflection.Emit.TypeBuilder.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //   Marek Safar (marek.safar@gmail.com)
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 #if !FULL_AOT_RUNTIME
35 using System;
36 using System.Text;
37 using System.Reflection;
38 using System.Reflection.Emit;
39 using System.Runtime.CompilerServices;
40 using System.Runtime.InteropServices;
41 using System.Globalization;
42 using System.Collections;
43 using System.Security;
44 using System.Security.Permissions;
45 using System.Diagnostics.SymbolStore;
46
47
48 namespace System.Reflection.Emit
49 {
50         [ComVisible (true)]
51         [ComDefaultInterface (typeof (_TypeBuilder))]
52         [ClassInterface (ClassInterfaceType.None)]
53         [StructLayout (LayoutKind.Sequential)]
54         public sealed class TypeBuilder : TypeInfo, _TypeBuilder
55         {
56 #pragma warning disable 169             
57                 #region Sync with reflection.h
58                 private string tname; // name in internal form
59                 private string nspace; // namespace in internal form
60                 private Type parent;
61                 private Type nesting_type;
62                 internal Type[] interfaces;
63                 internal int num_methods;
64                 internal MethodBuilder[] methods;
65                 internal ConstructorBuilder[] ctors;
66                 internal PropertyBuilder[] properties;
67                 internal int num_fields;
68                 internal FieldBuilder[] fields;
69                 internal EventBuilder[] events;
70                 private CustomAttributeBuilder[] cattrs;
71                 internal TypeBuilder[] subtypes;
72                 internal TypeAttributes attrs;
73                 private int table_idx;
74                 private ModuleBuilder pmodule;
75                 private int class_size;
76                 private PackingSize packing_size;
77                 private IntPtr generic_container;
78                 private GenericTypeParameterBuilder[] generic_params;
79                 private RefEmitPermissionSet[] permissions;
80                 private TypeInfo created;
81                 #endregion
82 #pragma warning restore 169             
83                 
84                 TypeName fullname;
85                 bool createTypeCalled;
86                 private Type underlying_type;
87
88                 public const int UnspecifiedTypeSize = 0;
89                 
90                 protected override TypeAttributes GetAttributeFlagsImpl ()
91                 {
92                         return attrs;
93                 }
94                 
95                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
96                 private extern void setup_internal_class ();
97                 
98                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
99                 private extern void create_generic_class ();
100
101                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
102                 private extern EventInfo get_event_info (EventBuilder eb);
103
104                 internal TypeBuilder (ModuleBuilder mb, TypeAttributes attr, int table_idx)
105                 {
106                         this.parent = null;
107                         this.attrs = attr;
108                         this.class_size = UnspecifiedTypeSize;
109                         this.table_idx = table_idx;
110                         this.tname = table_idx == 1 ? "<Module>" : "type_" + table_idx.ToString ();
111                         this.nspace = String.Empty;
112                         this.fullname = TypeIdentifiers.WithoutEscape(this.tname);
113                         pmodule = mb;
114                         setup_internal_class ();
115                 }
116
117                 internal TypeBuilder (ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packing_size, int type_size, Type nesting_type)
118                 {
119                         int sep_index;
120                         this.parent = ResolveUserType (parent);
121                         this.attrs = attr;
122                         this.class_size = type_size;
123                         this.packing_size = packing_size;
124                         this.nesting_type = nesting_type;
125
126                         check_name ("fullname", name);
127
128                         if (parent == null && (attr & TypeAttributes.Interface) != 0 && (attr & TypeAttributes.Abstract) == 0)
129                                 throw new InvalidOperationException ("Interface must be declared abstract.");
130
131                         sep_index = name.LastIndexOf('.');
132                         if (sep_index != -1) {
133                                 this.tname = name.Substring (sep_index + 1);
134                                 this.nspace = name.Substring (0, sep_index);
135                         } else {
136                                 this.tname = name;
137                                 this.nspace = String.Empty;
138                         }
139                         if (interfaces != null) {
140                                 this.interfaces = new Type[interfaces.Length];
141                                 System.Array.Copy (interfaces, this.interfaces, interfaces.Length);
142                         }
143                         pmodule = mb;
144
145                         if (((attr & TypeAttributes.Interface) == 0) && (parent == null))
146                                 this.parent = typeof (object);
147
148                         // skip .<Module> ?
149                         table_idx = mb.get_next_table_index (this, 0x02, true);
150                         setup_internal_class ();
151                         fullname = GetFullName ();
152                 }
153
154                 public override Assembly Assembly {
155                         get {return pmodule.Assembly;}
156                 }
157
158                 public override string AssemblyQualifiedName {
159                         get {
160                                 return fullname.DisplayName + ", " + Assembly.FullName;
161                         }
162                 }
163
164                 public override Type BaseType {
165                         get {
166                                 return parent;
167                         }
168                 }
169
170                 public override Type DeclaringType {
171                         get { return nesting_type; }
172                 }
173
174                 [ComVisible (true)]
175                 public override bool IsSubclassOf (Type c)
176                 {
177                         Type t;
178                         if (c == null)
179                                 return false;
180                         if (c == this)
181                                 return false;
182                         t = parent;
183                         while (t != null) {
184                                 if (c == t)
185                                         return true;
186                                 t = t.BaseType;
187                         }
188                         return false;
189                 }
190
191                 public override Type UnderlyingSystemType {
192                         get {
193                                 if (is_created)
194                                         return created.UnderlyingSystemType;
195
196                                 if (IsEnum) {
197                                         if (underlying_type != null)
198                                                 return underlying_type;
199                                         throw new InvalidOperationException (
200                                                 "Enumeration type is not defined.");
201                                 }
202
203                                 return this;
204                         }
205                 }
206
207                 TypeName GetFullName ()
208                 {
209                         TypeIdentifier ident = TypeIdentifiers.FromInternal (tname);
210                         if (nesting_type != null)
211                                 return TypeNames.FromDisplay (nesting_type.FullName).NestedName (ident);
212                         if ((nspace != null) && (nspace.Length > 0))
213                                 return TypeIdentifiers.FromInternal (nspace, ident);
214                         return ident;
215                 }
216         
217                 public override string FullName {
218                         get {
219                                 return fullname.DisplayName;
220                         }
221                 }
222         
223                 public override Guid GUID {
224                         get {
225                                 check_created ();
226                                 return created.GUID;
227                         }
228                 }
229
230                 public override Module Module {
231                         get {return pmodule;}
232                 }
233
234                 public override string Name {
235                         get {return tname;}
236                 }
237
238                 public override string Namespace {
239                         get {return nspace;}
240                 }
241
242                 public PackingSize PackingSize {
243                         get {return packing_size;}
244                 }
245
246                 public int Size {
247                         get { return class_size; }
248                 }
249
250                 public override Type ReflectedType {
251                         get { return nesting_type; }
252                 }
253
254                 public void AddDeclarativeSecurity (SecurityAction action, PermissionSet pset)
255                 {
256 #if !MOBILE
257                         if (pset == null)
258                                 throw new ArgumentNullException ("pset");
259                         if ((action == SecurityAction.RequestMinimum) ||
260                                 (action == SecurityAction.RequestOptional) ||
261                                 (action == SecurityAction.RequestRefuse))
262                                 throw new ArgumentOutOfRangeException ("Request* values are not permitted", "action");
263
264                         check_not_created ();
265
266                         if (permissions != null) {
267                                 /* Check duplicate actions */
268                                 foreach (RefEmitPermissionSet set in permissions)
269                                         if (set.action == action)
270                                                 throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction.");
271
272                                 RefEmitPermissionSet[] new_array = new RefEmitPermissionSet [permissions.Length + 1];
273                                 permissions.CopyTo (new_array, 0);
274                                 permissions = new_array;
275                         }
276                         else
277                                 permissions = new RefEmitPermissionSet [1];
278
279                         permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ());
280                         attrs |= TypeAttributes.HasSecurity;
281 #endif
282                 }
283
284                 [ComVisible (true)]
285                 public void AddInterfaceImplementation (Type interfaceType)
286                 {
287                         if (interfaceType == null)
288                                 throw new ArgumentNullException ("interfaceType");
289                         check_not_created ();
290
291                         if (interfaces != null) {
292                                 // Check for duplicates
293                                 foreach (Type t in interfaces)
294                                         if (t == interfaceType)
295                                                 return;
296
297                                 Type[] ifnew = new Type [interfaces.Length + 1];
298                                 interfaces.CopyTo (ifnew, 0);
299                                 ifnew [interfaces.Length] = interfaceType;
300                                 interfaces = ifnew;
301                         } else {
302                                 interfaces = new Type [1];
303                                 interfaces [0] = interfaceType;
304                         }
305                 }
306
307                 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder,
308                                                                        CallingConventions callConvention, Type[] types,
309                                                                        ParameterModifier[] modifiers)
310                 {
311                         check_created ();
312
313                         if (created == typeof (object)) {
314                                 /* 
315                                  * This happens when building corlib. Calling created.GetConstructor 
316                                  * would return constructors from the real mscorlib, instead of the
317                                  * newly built one.
318                                  */
319
320                                 if (ctors == null)
321                                         return null;
322  
323                                 ConstructorBuilder found = null;
324                                 int count = 0;
325                         
326                                 foreach (ConstructorBuilder cb in ctors) {
327                                         if (callConvention != CallingConventions.Any && cb.CallingConvention != callConvention)
328                                                 continue;
329                                         found = cb;
330                                         count++;
331                                 }
332
333                                 if (count == 0)
334                                         return null;
335                                 if (types == null) {
336                                         if (count > 1)
337                                                 throw new AmbiguousMatchException ();
338                                         return found;
339                                 }
340                                 MethodBase[] match = new MethodBase [count];
341                                 if (count == 1)
342                                         match [0] = found;
343                                 else {
344                                         count = 0;
345                                         foreach (ConstructorInfo m in ctors) {
346                                                 if (callConvention != CallingConventions.Any && m.CallingConvention != callConvention)
347                                                         continue;
348                                                 match [count++] = m;
349                                         }
350                                 }
351                                 if (binder == null)
352                                         binder = DefaultBinder;
353                                 return (ConstructorInfo) binder.SelectMethod (bindingAttr, match,
354                                                                                                                           types, modifiers);
355                         }
356
357                         return created.GetConstructor (bindingAttr, binder, 
358                                 callConvention, types, modifiers);
359                 }
360
361                 public override bool IsDefined (Type attributeType, bool inherit)
362                 {
363                         if (!is_created)
364                                 throw new NotSupportedException ();
365                         /*
366                          * MS throws NotSupported here, but we can't because some corlib
367                          * classes make calls to IsDefined.
368                          */
369                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
370                 }
371                 
372                 public override object[] GetCustomAttributes(bool inherit)
373                 {
374                         check_created ();
375
376                         return created.GetCustomAttributes (inherit);
377                 }
378                 
379                 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
380                 {
381                         check_created ();
382
383                         return created.GetCustomAttributes (attributeType, inherit);
384                 }
385
386                 public TypeBuilder DefineNestedType (string name)
387                 {
388                         return DefineNestedType (name, TypeAttributes.NestedPrivate,
389                                 pmodule.assemblyb.corlib_object_type, null);
390                 }
391
392                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr)
393                 {
394                         return DefineNestedType (name, attr, pmodule.assemblyb.corlib_object_type, null);
395                 }
396
397                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent)
398                 {
399                         return DefineNestedType (name, attr, parent, null);
400                 }
401
402                 private TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces,
403                                                       PackingSize packSize, int typeSize)
404                 {
405                         // Visibility must be NestedXXX
406                         /* This breaks mcs
407                         if (((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.Public) ||
408                                 ((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic))
409                                 throw new ArgumentException ("attr", "Bad type flags for nested type.");
410                         */
411                         if (interfaces != null)
412                                 foreach (Type iface in interfaces)
413                                         if (iface == null)
414                                                 throw new ArgumentNullException ("interfaces");
415
416                         TypeBuilder res = new TypeBuilder (pmodule, name, attr, parent, interfaces, packSize, typeSize, this);
417                         res.fullname = res.GetFullName ();
418                         pmodule.RegisterTypeName (res, res.fullname);
419                         if (subtypes != null) {
420                                 TypeBuilder[] new_types = new TypeBuilder [subtypes.Length + 1];
421                                 System.Array.Copy (subtypes, new_types, subtypes.Length);
422                                 new_types [subtypes.Length] = res;
423                                 subtypes = new_types;
424                         } else {
425                                 subtypes = new TypeBuilder [1];
426                                 subtypes [0] = res;
427                         }
428                         return res;
429                 }
430
431                 [ComVisible (true)]
432                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces)
433                 {
434                         return DefineNestedType (name, attr, parent, interfaces, PackingSize.Unspecified, UnspecifiedTypeSize);
435                 }
436
437                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, int typeSize)
438                 {
439                         return DefineNestedType (name, attr, parent, null, PackingSize.Unspecified, typeSize);
440                 }
441
442                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packSize)
443                 {
444                         return DefineNestedType (name, attr, parent, null, packSize, UnspecifiedTypeSize);
445                 }
446
447                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packSize,
448                                                      int typeSize)
449                 {
450                         return DefineNestedType (name, attr, parent, null, packSize, typeSize);
451                 }
452
453                 [ComVisible (true)]
454                 public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes)
455                 {
456                         return DefineConstructor (attributes, callingConvention, parameterTypes, null, null);
457                 }
458
459                 [ComVisible (true)]
460                 public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
461                 {
462                         check_not_created ();
463                         ConstructorBuilder cb = new ConstructorBuilder (this, attributes,
464                                 callingConvention, parameterTypes, requiredCustomModifiers,
465                                 optionalCustomModifiers);
466                         if (ctors != null) {
467                                 ConstructorBuilder[] new_ctors = new ConstructorBuilder [ctors.Length+1];
468                                 System.Array.Copy (ctors, new_ctors, ctors.Length);
469                                 new_ctors [ctors.Length] = cb;
470                                 ctors = new_ctors;
471                         } else {
472                                 ctors = new ConstructorBuilder [1];
473                                 ctors [0] = cb;
474                         }
475                         return cb;
476                 }
477
478                 [ComVisible (true)]
479                 public ConstructorBuilder DefineDefaultConstructor (MethodAttributes attributes)
480                 {
481                         Type parent_type, old_parent_type;
482
483                         if (parent != null)
484                                 parent_type = parent;
485                         else
486                                 parent_type = pmodule.assemblyb.corlib_object_type;
487
488                         old_parent_type = parent_type;
489                         parent_type = parent_type.InternalResolve ();
490                         /*This avoids corlib to have self references.*/
491                         if (parent_type == typeof (object) || parent_type == typeof (ValueType))
492                                 parent_type = old_parent_type;
493
494                         ConstructorInfo parent_constructor =
495                                 parent_type.GetConstructor (
496                                         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
497                                         null, Type.EmptyTypes, null);
498                         if (parent_constructor == null) {
499                                 throw new NotSupportedException ("Parent does"
500                                         + " not have a default constructor."
501                                         + " The default constructor must be"
502                                         + " explicitly defined.");
503                         }
504
505                         ConstructorBuilder cb = DefineConstructor (attributes, 
506                                 CallingConventions.Standard, Type.EmptyTypes);
507                         ILGenerator ig = cb.GetILGenerator ();
508                         ig.Emit (OpCodes.Ldarg_0);
509                         ig.Emit (OpCodes.Call, parent_constructor);
510                         ig.Emit (OpCodes.Ret);
511                         return cb;
512                 }
513
514                 private void append_method (MethodBuilder mb)
515                 {
516                         if (methods != null) {
517                                 if (methods.Length == num_methods) {
518                                         MethodBuilder[] new_methods = new MethodBuilder [methods.Length * 2];
519                                         System.Array.Copy (methods, new_methods, num_methods);
520                                         methods = new_methods;
521                                 }
522                         } else {
523                                 methods = new MethodBuilder [1];
524                         }
525                         methods [num_methods] = mb;
526                         num_methods ++;
527                 }
528
529                 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
530                 {
531                         return DefineMethod (name, attributes, CallingConventions.Standard,
532                                 returnType, parameterTypes);
533                 }
534
535                 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
536                 {
537                         return DefineMethod (name, attributes, callingConvention, returnType,
538                                 null, null, parameterTypes, null, null);
539                 }
540
541                 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
542                 {
543                         check_name ("name", name);
544                         check_not_created ();
545                         if (IsInterface && (
546                                 !((attributes & MethodAttributes.Abstract) != 0) || 
547                                 !((attributes & MethodAttributes.Virtual) != 0)) &&
548                                 !(((attributes & MethodAttributes.Static) != 0)))
549                                 throw new ArgumentException ("Interface method must be abstract and virtual.");
550
551                         if (returnType == null)
552                                 returnType = pmodule.assemblyb.corlib_void_type;
553                         MethodBuilder res = new MethodBuilder (this, name, attributes, 
554                                 callingConvention, returnType,
555                                 returnTypeRequiredCustomModifiers,
556                                 returnTypeOptionalCustomModifiers, parameterTypes,
557                                 parameterTypeRequiredCustomModifiers,
558                                 parameterTypeOptionalCustomModifiers);
559                         append_method (res);
560                         return res;
561                 }
562
563                 public MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
564                 {
565                         return DefinePInvokeMethod (name, dllName, entryName, attributes,
566                                 callingConvention, returnType, null, null, parameterTypes,
567                                 null, null, nativeCallConv, nativeCharSet);
568                 }
569
570                 public MethodBuilder DefinePInvokeMethod (
571                                                 string name, 
572                                                 string dllName, 
573                                                 string entryName, MethodAttributes attributes, 
574                                                 CallingConventions callingConvention, 
575                                                 Type returnType, 
576                                                 Type[] returnTypeRequiredCustomModifiers, 
577                                                 Type[] returnTypeOptionalCustomModifiers, 
578                                                 Type[] parameterTypes, 
579                                                 Type[][] parameterTypeRequiredCustomModifiers, 
580                                                 Type[][] parameterTypeOptionalCustomModifiers, 
581                                                 CallingConvention nativeCallConv, 
582                                                 CharSet nativeCharSet)
583                 {
584                         check_name ("name", name);
585                         check_name ("dllName", dllName);
586                         check_name ("entryName", entryName);
587                         if ((attributes & MethodAttributes.Abstract) != 0)
588                                 throw new ArgumentException ("PInvoke methods must be static and native and cannot be abstract.");
589                         if (IsInterface)
590                                 throw new ArgumentException ("PInvoke methods cannot exist on interfaces.");
591                         check_not_created ();
592
593                         MethodBuilder res 
594                                 = new MethodBuilder (
595                                                 this, 
596                                                 name, 
597                                                 attributes, 
598                                                 callingConvention,
599                                                 returnType, 
600                                                 returnTypeRequiredCustomModifiers, 
601                                                 returnTypeOptionalCustomModifiers, 
602                                                 parameterTypes, 
603                                                 parameterTypeRequiredCustomModifiers, 
604                                                 parameterTypeOptionalCustomModifiers,
605                                                 dllName, 
606                                                 entryName, 
607                                                 nativeCallConv, 
608                                                 nativeCharSet);
609                         append_method (res);
610                         return res;
611                 }
612
613                 public MethodBuilder DefinePInvokeMethod (string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) {
614                         return DefinePInvokeMethod (name, dllName, name, attributes, callingConvention, returnType, parameterTypes,
615                                 nativeCallConv, nativeCharSet);
616                 }
617
618                 public MethodBuilder DefineMethod (string name, MethodAttributes attributes)
619                 {
620                         return DefineMethod (name, attributes, CallingConventions.Standard);
621                 }
622
623                 public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention)
624                 {
625                         return DefineMethod (name, attributes, callingConvention, null, null);
626                 }
627
628                 public void DefineMethodOverride (MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)
629                 {
630                         if (methodInfoBody == null)
631                                 throw new ArgumentNullException ("methodInfoBody");
632                         if (methodInfoDeclaration == null)
633                                 throw new ArgumentNullException ("methodInfoDeclaration");
634                         check_not_created ();
635                         if (methodInfoBody.DeclaringType != this)
636                                 throw new ArgumentException ("method body must belong to this type");
637
638                         if (methodInfoBody is MethodBuilder) {
639                                 MethodBuilder mb = (MethodBuilder)methodInfoBody;
640                                 mb.set_override (methodInfoDeclaration);
641                         }
642                 }
643
644                 public FieldBuilder DefineField (string fieldName, Type type, FieldAttributes attributes)
645                 {
646                         return DefineField (fieldName, type, null, null, attributes);
647                 }
648
649                 public FieldBuilder DefineField (string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
650                 {
651                         check_name ("fieldName", fieldName);
652                         if (type == typeof (void))
653                                 throw new ArgumentException ("Bad field type in defining field.");
654                         check_not_created ();
655
656                         FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes, requiredCustomModifiers, optionalCustomModifiers);
657                         if (fields != null) {
658                                 if (fields.Length == num_fields) {
659                                         FieldBuilder[] new_fields = new FieldBuilder [fields.Length * 2];
660                                         System.Array.Copy (fields, new_fields, num_fields);
661                                         fields = new_fields;
662                                 }
663                                 fields [num_fields] = res;
664                                 num_fields ++;
665                         } else {
666                                 fields = new FieldBuilder [1];
667                                 fields [0] = res;
668                                 num_fields ++;
669                         }
670
671                         if (IsEnum) {
672                                 if (underlying_type == null && (attributes & FieldAttributes.Static) == 0)
673                                         underlying_type = type;
674                         }
675
676                         return res;
677                 }
678
679                 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes)
680                 {
681                         return DefineProperty (name, attributes, 0, returnType, null, null, parameterTypes, null, null);
682                 }
683                 
684                 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
685                 {
686                         return DefineProperty (name, attributes, callingConvention, returnType , null, null, parameterTypes, null, null);
687                 }       
688
689                 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
690                 {
691                         return DefineProperty (name, attributes, 0, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
692                 }
693                 
694                 public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
695                 {
696                         check_name ("name", name);
697                         if (parameterTypes != null)
698                                 foreach (Type param in parameterTypes)
699                                         if (param == null)
700                                                 throw new ArgumentNullException ("parameterTypes");
701                         check_not_created ();
702
703                         PropertyBuilder res = new PropertyBuilder (this, name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
704
705                         if (properties != null) {
706                                 Array.Resize (ref properties, properties.Length + 1);
707                                 properties [properties.Length - 1] = res;
708                         } else {
709                                 properties = new PropertyBuilder [1] { res };
710                         }
711                         return res;
712                 }
713
714                 [ComVisible (true)]
715                 public ConstructorBuilder DefineTypeInitializer()
716                 {
717                         return DefineConstructor (MethodAttributes.Public |
718                                 MethodAttributes.Static | MethodAttributes.SpecialName |
719                                 MethodAttributes.RTSpecialName, CallingConventions.Standard,
720                                 null);
721                 }
722
723                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
724                 private extern TypeInfo create_runtime_class ();
725
726                 private bool is_nested_in (Type t)
727                 {
728                         while (t != null) {
729                                 if (t == this)
730                                         return true;
731                                 else
732                                         t = t.DeclaringType;
733                         }
734                         return false;
735                 }
736
737                 // Return whenever this type has a ctor defined using DefineMethod ()
738                 private bool has_ctor_method () {
739                         MethodAttributes ctor_attrs = MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
740
741                         for (int i = 0; i < num_methods; ++i) {
742                                 MethodBuilder mb = (MethodBuilder)(methods[i]);
743
744                                 if (mb.Name == ConstructorInfo.ConstructorName && (mb.Attributes & ctor_attrs) == ctor_attrs)
745                                         return true;
746                         }
747
748                         return false;
749             }
750
751                 public Type CreateType ()
752                 {
753                         return CreateTypeInfo ();
754                 }
755                 
756                 public
757                 TypeInfo CreateTypeInfo ()
758                 {
759                         /* handle nesting_type */
760                         if (createTypeCalled)
761                                 return created;
762
763                         if (!IsInterface && (parent == null) && (this != pmodule.assemblyb.corlib_object_type) && (FullName != "<Module>")) {
764                                 SetParent (pmodule.assemblyb.corlib_object_type);
765                         }
766
767                         create_generic_class ();
768
769                         // Fire TypeResolve events for fields whose type is an unfinished
770                         // value type.
771                         if (fields != null) {
772                                 foreach (FieldBuilder fb in fields) {
773                                         if (fb == null)
774                                                 continue;
775                                         Type ft = fb.FieldType;
776                                         if (!fb.IsStatic && (ft is TypeBuilder) && ft.IsValueType && (ft != this) && is_nested_in (ft)) {
777                                                 TypeBuilder tb = (TypeBuilder)ft;
778                                                 if (!tb.is_created) {
779                                                         AppDomain.CurrentDomain.DoTypeResolve (tb);
780                                                         if (!tb.is_created) {
781                                                                 // FIXME: We should throw an exception here,
782                                                                 // but mcs expects that the type is created
783                                                                 // even if the exception is thrown
784                                                                 //throw new TypeLoadException ("Could not load type " + tb);
785                                                         }
786                                                 }
787                                         }
788                                 }
789                         }
790
791                         //
792                         // On classes, define a default constructor if not provided
793                         //
794                         if (!(IsInterface || IsValueType) && (ctors == null) && (tname != "<Module>") && 
795                                 (GetAttributeFlagsImpl () & TypeAttributes.Abstract | TypeAttributes.Sealed) != (TypeAttributes.Abstract | TypeAttributes.Sealed) && !has_ctor_method ())
796                                 DefineDefaultConstructor (MethodAttributes.Public);
797
798                         createTypeCalled = true;
799
800                         if ((parent != null) && parent.IsSealed)
801                                 throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because the parent type is sealed.");
802
803                         if (parent == pmodule.assemblyb.corlib_enum_type && methods != null)
804                                 throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because it is an enum with methods.");
805                         if (interfaces != null) {
806                                 foreach (var iface in interfaces) {
807                                         if (iface.IsNestedPrivate && iface.Assembly != Assembly)
808                                                 throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because it is implements the inaccessible interface '" + iface.FullName + "'.");
809                                 }
810                         }
811
812                         if (methods != null) {
813                                 bool is_concrete = !IsAbstract;
814                                 for (int i = 0; i < num_methods; ++i) {
815                                         MethodBuilder mb = (MethodBuilder)(methods[i]);
816                                         if (is_concrete && mb.IsAbstract)
817                                                 throw new InvalidOperationException ("Type is concrete but has abstract method " + mb);
818                                         mb.check_override ();
819                                         mb.fixup ();
820                                 }
821                         }
822
823                         if (ctors != null){
824                                 foreach (ConstructorBuilder ctor in ctors) 
825                                         ctor.fixup ();
826                         }
827
828                         ResolveUserTypes ();
829
830                         created = create_runtime_class ();
831                         if (created != null)
832                                 return created;
833                         return this;
834                 }
835
836                 void ResolveUserTypes () {
837                         parent = ResolveUserType (parent);
838                         ResolveUserTypes (interfaces);
839                         if (fields != null) {
840                                 foreach (var fb in fields) {
841                                         if (fb != null)
842                                                 fb.ResolveUserTypes ();
843                                 }
844                         }
845                         if (methods != null) {
846                                 foreach (var mb in methods) {
847                                         if (mb != null)
848                                                 mb.ResolveUserTypes ();
849                                 }
850                         }
851                         if (ctors != null) {
852                                 foreach (var cb in ctors) {
853                                         if (cb != null)
854                                                 cb.ResolveUserTypes ();
855                                 }
856                         }
857                 }
858
859                 static internal void ResolveUserTypes (Type[] types) {
860                         if (types != null)
861                                 for (int i = 0; i < types.Length; ++i)
862                                         types [i] = ResolveUserType (types [i]);
863                 }
864
865                 static internal Type ResolveUserType (Type t) {
866                         if (t != null && ((t.GetType ().Assembly != typeof (int).Assembly) || (t is TypeDelegator))) {
867                                 t = t.UnderlyingSystemType;
868                                 if (t != null && ((t.GetType ().Assembly != typeof (int).Assembly) || (t is TypeDelegator)))
869                                         throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
870                                 return t;
871                         } else {
872                                 return t;
873                         }
874                 }
875
876                 internal void GenerateDebugInfo (ISymbolWriter symbolWriter)
877                 {
878                         symbolWriter.OpenNamespace (this.Namespace);
879
880                         if (methods != null) {
881                                 for (int i = 0; i < num_methods; ++i) {
882                                         MethodBuilder metb = (MethodBuilder) methods[i]; 
883                                         metb.GenerateDebugInfo (symbolWriter);
884                                 }
885                         }
886
887                         if (ctors != null) {
888                                 foreach (ConstructorBuilder ctor in ctors)
889                                         ctor.GenerateDebugInfo (symbolWriter);
890                         }
891                         
892                         symbolWriter.CloseNamespace ();
893
894                         if (subtypes != null) {
895                                 for (int i = 0; i < subtypes.Length; ++i)
896                                         subtypes [i].GenerateDebugInfo (symbolWriter);
897                         }
898                 }
899
900                 [ComVisible (true)]
901                 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
902                 {
903                         if (is_created)
904                                 return created.GetConstructors (bindingAttr);
905
906                         throw new NotSupportedException ();
907                 }
908
909                 internal ConstructorInfo[] GetConstructorsInternal (BindingFlags bindingAttr)
910                 {
911                         if (ctors == null)
912                                 return new ConstructorInfo [0];
913                         ArrayList l = new ArrayList ();
914                         bool match;
915                         MethodAttributes mattrs;
916                         
917                         foreach (ConstructorBuilder c in ctors) {
918                                 match = false;
919                                 mattrs = c.Attributes;
920                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
921                                         if ((bindingAttr & BindingFlags.Public) != 0)
922                                                 match = true;
923                                 } else {
924                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
925                                                 match = true;
926                                 }
927                                 if (!match)
928                                         continue;
929                                 match = false;
930                                 if ((mattrs & MethodAttributes.Static) != 0) {
931                                         if ((bindingAttr & BindingFlags.Static) != 0)
932                                                 match = true;
933                                 } else {
934                                         if ((bindingAttr & BindingFlags.Instance) != 0)
935                                                 match = true;
936                                 }
937                                 if (!match)
938                                         continue;
939                                 l.Add (c);
940                         }
941                         ConstructorInfo[] result = new ConstructorInfo [l.Count];
942                         l.CopyTo (result);
943                         return result;
944                 }
945
946                 public override Type GetElementType ()
947                 {
948                         throw new NotSupportedException ();
949                 }
950
951                 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
952                 {
953                         check_created ();
954                         return created.GetEvent (name, bindingAttr);
955                 }
956
957                 /* Needed to keep signature compatibility with MS.NET */
958                 public override EventInfo[] GetEvents ()
959                 {
960                         const BindingFlags DefaultBindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
961                         return GetEvents (DefaultBindingFlags);
962                 }
963
964                 public override EventInfo[] GetEvents (BindingFlags bindingAttr)
965                 {
966                         if (is_created)
967                                 return created.GetEvents (bindingAttr);
968                         throw new NotSupportedException ();
969                 }
970
971                 // This is only used from MonoGenericInst.initialize().
972                 internal EventInfo[] GetEvents_internal (BindingFlags bindingAttr)
973                 {
974                         if (events == null)
975                                 return new EventInfo [0];
976                         ArrayList l = new ArrayList ();
977                         bool match;
978                         MethodAttributes mattrs;
979                         MethodInfo accessor;
980
981                         foreach (EventBuilder eb in events) {
982                                 if (eb == null)
983                                         continue;
984                                 EventInfo c = get_event_info (eb);
985                                 match = false;
986                                 accessor = c.GetAddMethod (true);
987                                 if (accessor == null)
988                                         accessor = c.GetRemoveMethod (true);
989                                 if (accessor == null)
990                                         continue;
991                                 mattrs = accessor.Attributes;
992                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
993                                         if ((bindingAttr & BindingFlags.Public) != 0)
994                                                 match = true;
995                                 } else {
996                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
997                                                 match = true;
998                                 }
999                                 if (!match)
1000                                         continue;
1001                                 match = false;
1002                                 if ((mattrs & MethodAttributes.Static) != 0) {
1003                                         if ((bindingAttr & BindingFlags.Static) != 0)
1004                                                 match = true;
1005                                 } else {
1006                                         if ((bindingAttr & BindingFlags.Instance) != 0)
1007                                                 match = true;
1008                                 }
1009                                 if (!match)
1010                                         continue;
1011                                 l.Add (c);
1012                         }
1013                         EventInfo[] result = new EventInfo [l.Count];
1014                         l.CopyTo (result);
1015                         return result;
1016                 }
1017
1018                 public override FieldInfo GetField (string name, BindingFlags bindingAttr)
1019                 {
1020                         if (created != null)
1021                                 return created.GetField (name, bindingAttr);
1022
1023                         if (fields == null)
1024                                 return null;
1025
1026                         bool match;
1027                         FieldAttributes mattrs;
1028                         
1029                         foreach (FieldInfo c in fields) {
1030                                 if (c == null)
1031                                         continue;
1032                                 if (c.Name != name)
1033                                         continue;
1034                                 match = false;
1035                                 mattrs = c.Attributes;
1036                                 if ((mattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
1037                                         if ((bindingAttr & BindingFlags.Public) != 0)
1038                                                 match = true;
1039                                 } else {
1040                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
1041                                                 match = true;
1042                                 }
1043                                 if (!match)
1044                                         continue;
1045                                 match = false;
1046                                 if ((mattrs & FieldAttributes.Static) != 0) {
1047                                         if ((bindingAttr & BindingFlags.Static) != 0)
1048                                                 match = true;
1049                                 } else {
1050                                         if ((bindingAttr & BindingFlags.Instance) != 0)
1051                                                 match = true;
1052                                 }
1053                                 if (!match)
1054                                         continue;
1055                                 return c;
1056                         }
1057                         return null;
1058                 }
1059
1060                 public override FieldInfo[] GetFields (BindingFlags bindingAttr)
1061                 {
1062                         if (created != null)
1063                                 return created.GetFields (bindingAttr);
1064
1065                         if (fields == null)
1066                                 return new FieldInfo [0];
1067                         ArrayList l = new ArrayList ();
1068                         bool match;
1069                         FieldAttributes mattrs;
1070                         
1071                         foreach (FieldInfo c in fields) {
1072                                 if (c == null)
1073                                         continue;
1074                                 match = false;
1075                                 mattrs = c.Attributes;
1076                                 if ((mattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
1077                                         if ((bindingAttr & BindingFlags.Public) != 0)
1078                                                 match = true;
1079                                 } else {
1080                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
1081                                                 match = true;
1082                                 }
1083                                 if (!match)
1084                                         continue;
1085                                 match = false;
1086                                 if ((mattrs & FieldAttributes.Static) != 0) {
1087                                         if ((bindingAttr & BindingFlags.Static) != 0)
1088                                                 match = true;
1089                                 } else {
1090                                         if ((bindingAttr & BindingFlags.Instance) != 0)
1091                                                 match = true;
1092                                 }
1093                                 if (!match)
1094                                         continue;
1095                                 l.Add (c);
1096                         }
1097                         FieldInfo[] result = new FieldInfo [l.Count];
1098                         l.CopyTo (result);
1099                         return result;
1100                 }
1101
1102                 public override Type GetInterface (string name, bool ignoreCase)
1103                 {
1104                         check_created ();
1105                         return created.GetInterface (name, ignoreCase);
1106                 }
1107                 
1108                 public override Type[] GetInterfaces ()
1109                 {
1110                         if (is_created)
1111                                 return created.GetInterfaces ();
1112
1113                         if (interfaces != null) {
1114                                 Type[] ret = new Type [interfaces.Length];
1115                                 interfaces.CopyTo (ret, 0);
1116                                 return ret;
1117                         } else {
1118                                 return Type.EmptyTypes;
1119                         }
1120                 }
1121
1122                 public override MemberInfo[] GetMember (string name, MemberTypes type,
1123                                                                                                 BindingFlags bindingAttr)
1124                 {
1125                         check_created ();
1126                         return created.GetMember (name, type, bindingAttr);
1127                 }
1128
1129                 public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
1130                 {
1131                         check_created ();
1132                         return created.GetMembers (bindingAttr);
1133                 }
1134
1135                 private MethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type)
1136                 {
1137                         MethodInfo[] candidates;
1138                         bool match;
1139                         MethodAttributes mattrs;
1140
1141                         if (((bindingAttr & BindingFlags.DeclaredOnly) == 0) && (parent != null)) {
1142                                 MethodInfo [] parent_methods = parent.GetMethods (bindingAttr);
1143                                 ArrayList parent_candidates = new ArrayList (parent_methods.Length);
1144
1145                                 bool flatten = (bindingAttr & BindingFlags.FlattenHierarchy) != 0;
1146
1147                                 for (int i = 0; i < parent_methods.Length; i++) {
1148                                         MethodInfo m = parent_methods [i];
1149
1150                                         mattrs = m.Attributes;
1151
1152                                         if (m.IsStatic && !flatten)
1153                                                 continue;
1154
1155                                         switch (mattrs & MethodAttributes.MemberAccessMask) {
1156                                         case MethodAttributes.Public:
1157                                                 match = (bindingAttr & BindingFlags.Public) != 0;
1158                                                 break;
1159                                         case MethodAttributes.Assembly:
1160                                                 match = (bindingAttr & BindingFlags.NonPublic) != 0;
1161                                                 break;
1162                                         case MethodAttributes.Private:
1163                                                 match = false;
1164                                                 break;
1165                                         default:
1166                                                 match = (bindingAttr & BindingFlags.NonPublic) != 0;
1167                                                 break;
1168                                         }
1169
1170                                         if (match)
1171                                                 parent_candidates.Add (m);
1172                                 }
1173
1174                                 if (methods == null) {
1175                                         candidates = new MethodInfo [parent_candidates.Count];
1176                                         parent_candidates.CopyTo (candidates);
1177                                 } else {
1178                                         candidates = new MethodInfo [methods.Length + parent_candidates.Count];
1179                                         parent_candidates.CopyTo (candidates, 0);
1180                                         methods.CopyTo (candidates, parent_candidates.Count);
1181                                 }
1182                         }
1183                         else
1184                                 candidates = methods;
1185
1186                         if (candidates == null)
1187                                 return new MethodInfo [0];
1188
1189                         ArrayList l = new ArrayList ();
1190
1191                         foreach (MethodInfo c in candidates) {
1192                                 if (c == null)
1193                                         continue;
1194                                 if (name != null) {
1195                                         if (String.Compare (c.Name, name, ignoreCase) != 0)
1196                                                 continue;
1197                                 }
1198                                 match = false;
1199                                 mattrs = c.Attributes;
1200                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
1201                                         if ((bindingAttr & BindingFlags.Public) != 0)
1202                                                 match = true;
1203                                 } else {
1204                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
1205                                                 match = true;
1206                                 }
1207                                 if (!match)
1208                                         continue;
1209                                 match = false;
1210                                 if ((mattrs & MethodAttributes.Static) != 0) {
1211                                         if ((bindingAttr & BindingFlags.Static) != 0)
1212                                                 match = true;
1213                                 } else {
1214                                         if ((bindingAttr & BindingFlags.Instance) != 0)
1215                                                 match = true;
1216                                 }
1217                                 if (!match)
1218                                         continue;
1219                                 l.Add (c);
1220                         }
1221
1222                         MethodInfo[] result = new MethodInfo [l.Count];
1223                         l.CopyTo (result);
1224                         return result;
1225                 }
1226
1227                 public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
1228                 {
1229                         return GetMethodsByName (null, bindingAttr, false, this);
1230                 }
1231
1232                 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr,
1233                                                              Binder binder,
1234                                                              CallingConventions callConvention,
1235                                                              Type[] types, ParameterModifier[] modifiers)
1236                 {
1237                         check_created ();
1238
1239                         if (types == null)
1240                                 return created.GetMethod (name, bindingAttr);
1241
1242                         return created.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers);
1243                 }
1244
1245                 public override Type GetNestedType (string name, BindingFlags bindingAttr)
1246                 {
1247                         check_created ();
1248
1249                         if (subtypes == null)
1250                                 return null;
1251
1252                         foreach (TypeBuilder t in subtypes) {
1253                                 if (!t.is_created)
1254                                         continue;
1255                                 if ((t.attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) {
1256                                         if ((bindingAttr & BindingFlags.Public) == 0)
1257                                                 continue;
1258                                 } else {
1259                                         if ((bindingAttr & BindingFlags.NonPublic) == 0)
1260                                                 continue;
1261                                 }
1262                                 if (t.Name == name)
1263                                         return t.created;
1264                         }
1265
1266                         return null;
1267                 }
1268
1269                 public override Type[] GetNestedTypes (BindingFlags bindingAttr)
1270                 {
1271                         if (!is_created)
1272                                 throw new NotSupportedException ();
1273
1274                         bool match;
1275                         ArrayList result = new ArrayList ();
1276
1277                         if (subtypes == null)
1278                                 return Type.EmptyTypes;
1279                         foreach (TypeBuilder t in subtypes) {
1280                                 match = false;
1281                                 if ((t.attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) {
1282                                         if ((bindingAttr & BindingFlags.Public) != 0)
1283                                                 match = true;
1284                                 } else {
1285                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
1286                                                 match = true;
1287                                 }
1288                                 if (!match)
1289                                         continue;
1290                                 result.Add (t);
1291                         }
1292                         Type[] r = new Type [result.Count];
1293                         result.CopyTo (r);
1294                         return r;
1295                 }
1296
1297                 public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
1298                 {
1299                         if (is_created)
1300                                 return created.GetProperties (bindingAttr);
1301
1302                         if (properties == null)
1303                                 return new PropertyInfo [0];
1304                         ArrayList l = new ArrayList ();
1305                         bool match;
1306                         MethodAttributes mattrs;
1307                         MethodInfo accessor;
1308                         
1309                         foreach (PropertyInfo c in properties) {
1310                                 match = false;
1311                                 accessor = c.GetGetMethod (true);
1312                                 if (accessor == null)
1313                                         accessor = c.GetSetMethod (true);
1314                                 if (accessor == null)
1315                                         continue;
1316                                 mattrs = accessor.Attributes;
1317                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
1318                                         if ((bindingAttr & BindingFlags.Public) != 0)
1319                                                 match = true;
1320                                 } else {
1321                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
1322                                                 match = true;
1323                                 }
1324                                 if (!match)
1325                                         continue;
1326                                 match = false;
1327                                 if ((mattrs & MethodAttributes.Static) != 0) {
1328                                         if ((bindingAttr & BindingFlags.Static) != 0)
1329                                                 match = true;
1330                                 } else {
1331                                         if ((bindingAttr & BindingFlags.Instance) != 0)
1332                                                 match = true;
1333                                 }
1334                                 if (!match)
1335                                         continue;
1336                                 l.Add (c);
1337                         }
1338                         PropertyInfo[] result = new PropertyInfo [l.Count];
1339                         l.CopyTo (result);
1340                         return result;
1341                 }
1342                 
1343                 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1344                 {
1345                         throw not_supported ();
1346                 }
1347
1348                 protected override bool HasElementTypeImpl ()
1349                 {
1350                         // a TypeBuilder can never represent an array, pointer
1351                         if (!is_created)
1352                                 return false;
1353
1354                         return created.HasElementType;
1355                 }
1356
1357                 public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
1358                 {
1359                         check_created ();
1360                         return created.InvokeMember (name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
1361                 }
1362
1363                 protected override bool IsArrayImpl ()
1364                 {
1365                         return false; /*A TypeBuilder never represents a non typedef type.*/
1366                 }
1367
1368                 protected override bool IsByRefImpl ()
1369                 {
1370                         return false; /*A TypeBuilder never represents a non typedef type.*/
1371                 }
1372
1373                 protected override bool IsCOMObjectImpl ()
1374                 {
1375                         return ((GetAttributeFlagsImpl () & TypeAttributes.Import) != 0);
1376                 }
1377
1378                 protected override bool IsPointerImpl ()
1379                 {
1380                         return false; /*A TypeBuilder never represents a non typedef type.*/
1381                 }
1382
1383                 protected override bool IsPrimitiveImpl ()
1384                 {
1385                         // FIXME
1386                         return false;
1387                 }
1388
1389                 // FIXME: I doubt just removing this still works.
1390                 protected override bool IsValueTypeImpl ()
1391                 {
1392                         if (this == pmodule.assemblyb.corlib_value_type || this == pmodule.assemblyb.corlib_enum_type)
1393                                 return false;
1394                         Type parent_type = parent;
1395                         while (parent_type != null) {
1396                                 if (parent_type == pmodule.assemblyb.corlib_value_type)
1397                                         return true;
1398                                 parent_type = parent_type.BaseType;
1399                         }
1400                         return false;
1401                 }
1402                 
1403                 public override Type MakeArrayType ()
1404                 {
1405                         return new ArrayType (this, 0);
1406                 }
1407
1408                 public override Type MakeArrayType (int rank)
1409                 {
1410                         if (rank < 1)
1411                                 throw new IndexOutOfRangeException ();
1412                         return new ArrayType (this, rank);
1413                 }
1414
1415                 public override Type MakeByRefType ()
1416                 {
1417                         return new ByRefType (this);
1418                 }
1419
1420                 public override Type MakeGenericType (params Type [] typeArguments)
1421                 {
1422                         //return base.MakeGenericType (typeArguments);
1423
1424                         if (!IsGenericTypeDefinition)
1425                                 throw new InvalidOperationException ("not a generic type definition");
1426                         if (typeArguments == null)
1427                                 throw new ArgumentNullException ("typeArguments");
1428
1429                         if (generic_params.Length != typeArguments.Length)
1430                                 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");
1431
1432                         foreach (Type t in typeArguments) {
1433                                 if (t == null)
1434                                         throw new ArgumentNullException ("typeArguments");                              
1435                         }
1436
1437                         Type[] copy = new Type [typeArguments.Length];
1438                         typeArguments.CopyTo (copy, 0);
1439                         return pmodule.assemblyb.MakeGenericType (this, copy);
1440                 }
1441
1442                 public override Type MakePointerType ()
1443                 {
1444                         return new PointerType (this);
1445                 }
1446
1447                 public override RuntimeTypeHandle TypeHandle {
1448                         get {
1449                                 check_created ();
1450                                 return created.TypeHandle;
1451                         }
1452                 }
1453                 
1454                 public void SetCustomAttribute (CustomAttributeBuilder customBuilder)
1455                 {
1456                         if (customBuilder == null)
1457                                 throw new ArgumentNullException ("customBuilder");
1458
1459                         string attrname = customBuilder.Ctor.ReflectedType.FullName;
1460                         if (attrname == "System.Runtime.InteropServices.StructLayoutAttribute") {
1461                                 byte[] data = customBuilder.Data;
1462                                 int layout_kind; /* the (stupid) ctor takes a short or an int ... */
1463                                 layout_kind = (int)data [2];
1464                                 layout_kind |= ((int)data [3]) << 8;
1465                                 attrs &= ~TypeAttributes.LayoutMask;
1466                                 switch ((LayoutKind)layout_kind) {
1467                                 case LayoutKind.Auto:
1468                                         attrs |= TypeAttributes.AutoLayout;
1469                                         break;
1470                                 case LayoutKind.Explicit:
1471                                         attrs |= TypeAttributes.ExplicitLayout;
1472                                         break;
1473                                 case LayoutKind.Sequential:
1474                                         attrs |= TypeAttributes.SequentialLayout;
1475                                         break;
1476                                 default:
1477                                         // we should ignore it since it can be any value anyway...
1478                                         throw new Exception ("Error in customattr");
1479                                 }
1480                                 
1481                                 var ctor_type = customBuilder.Ctor is ConstructorBuilder ? ((ConstructorBuilder)customBuilder.Ctor).parameters[0] : customBuilder.Ctor.GetParametersInternal()[0].ParameterType;
1482                                 int pos = 6;
1483                                 if (ctor_type.FullName == "System.Int16")
1484                                         pos = 4;
1485                                 int nnamed = (int)data [pos++];
1486                                 nnamed |= ((int)data [pos++]) << 8;
1487                                 for (int i = 0; i < nnamed; ++i) {
1488                                         //byte named_type = data [pos++];
1489                                         pos ++;
1490                                         byte type = data [pos++];
1491                                         int len;
1492                                         string named_name;
1493
1494                                         if (type == 0x55) {
1495                                                 len = CustomAttributeBuilder.decode_len (data, pos, out pos);
1496                                                 //string named_typename = 
1497                                                 CustomAttributeBuilder.string_from_bytes (data, pos, len);
1498                                                 pos += len;
1499                                                 // FIXME: Check that 'named_type' and 'named_typename' match, etc.
1500                                                 //        See related code/FIXME in mono/mono/metadata/reflection.c
1501                                         }
1502
1503                                         len = CustomAttributeBuilder.decode_len (data, pos, out pos);
1504                                         named_name = CustomAttributeBuilder.string_from_bytes (data, pos, len);
1505                                         pos += len;
1506                                         /* all the fields are integers in StructLayout */
1507                                         int value = (int)data [pos++];
1508                                         value |= ((int)data [pos++]) << 8;
1509                                         value |= ((int)data [pos++]) << 16;
1510                                         value |= ((int)data [pos++]) << 24;
1511                                         switch (named_name) {
1512                                         case "CharSet":
1513                                                 switch ((CharSet)value) {
1514                                                 case CharSet.None:
1515                                                 case CharSet.Ansi:
1516                                                         attrs &= ~(TypeAttributes.UnicodeClass | TypeAttributes.AutoClass);
1517                                                         break;
1518                                                 case CharSet.Unicode:
1519                                                         attrs &= ~TypeAttributes.AutoClass;
1520                                                         attrs |= TypeAttributes.UnicodeClass;
1521                                                         break;
1522                                                 case CharSet.Auto:
1523                                                         attrs &= ~TypeAttributes.UnicodeClass;
1524                                                         attrs |= TypeAttributes.AutoClass;
1525                                                         break;
1526                                                 default:
1527                                                         break; // error out...
1528                                                 }
1529                                                 break;
1530                                         case "Pack":
1531                                                 packing_size = (PackingSize)value;
1532                                                 break;
1533                                         case "Size":
1534                                                 class_size = value;
1535                                                 break;
1536                                         default:
1537                                                 break; // error out...
1538                                         }
1539                                 }
1540                                 return;
1541                         } else if (attrname == "System.Runtime.CompilerServices.SpecialNameAttribute") {
1542                                 attrs |= TypeAttributes.SpecialName;
1543                                 return;
1544                         } else if (attrname == "System.SerializableAttribute") {
1545                                 attrs |= TypeAttributes.Serializable;
1546                                 return;
1547                         } else if (attrname == "System.Runtime.InteropServices.ComImportAttribute") {
1548                                 attrs |= TypeAttributes.Import;
1549                                 return;
1550                         } else if (attrname == "System.Security.SuppressUnmanagedCodeSecurityAttribute") {
1551                                 attrs |= TypeAttributes.HasSecurity;
1552                         }
1553
1554                         if (cattrs != null) {
1555                                 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
1556                                 cattrs.CopyTo (new_array, 0);
1557                                 new_array [cattrs.Length] = customBuilder;
1558                                 cattrs = new_array;
1559                         } else {
1560                                 cattrs = new CustomAttributeBuilder [1];
1561                                 cattrs [0] = customBuilder;
1562                         }
1563                 }
1564
1565                 [ComVisible (true)]
1566                 public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute)
1567                 {
1568                         SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
1569                 }
1570
1571                 public EventBuilder DefineEvent (string name, EventAttributes attributes, Type eventtype)
1572                 {
1573                         check_name ("name", name);
1574                         if (eventtype == null)
1575                                 throw new ArgumentNullException ("type");
1576                         check_not_created ();
1577
1578                         EventBuilder res = new EventBuilder (this, name, attributes, eventtype);
1579                         if (events != null) {
1580                                 EventBuilder[] new_events = new EventBuilder [events.Length+1];
1581                                 System.Array.Copy (events, new_events, events.Length);
1582                                 new_events [events.Length] = res;
1583                                 events = new_events;
1584                         } else {
1585                                 events = new EventBuilder [1];
1586                                 events [0] = res;
1587                         }
1588                         return res;
1589                 }
1590
1591                 public FieldBuilder DefineInitializedData (string name, byte[] data, FieldAttributes attributes) {
1592                         if (data == null)
1593                                 throw new ArgumentNullException ("data");
1594
1595                         FieldBuilder res = DefineUninitializedData (name, data.Length, attributes);
1596                         res.SetRVAData (data);
1597                         return res;
1598                 }
1599
1600                 public FieldBuilder DefineUninitializedData (string name, int size, FieldAttributes attributes)
1601                 {
1602                         if (name == null)
1603                                 throw new ArgumentNullException ("name");
1604                         if (name.Length == 0)
1605                                 throw new ArgumentException ("Empty name is not legal", "name");
1606                         if ((size <= 0) || (size > 0x3f0000))
1607                                 throw new ArgumentException ("Data size must be > 0 and < 0x3f0000");
1608                         check_not_created ();
1609
1610                         string typeName = "$ArrayType$" + size;
1611                         TypeIdentifier ident = TypeIdentifiers.WithoutEscape (typeName);
1612                         Type datablobtype = pmodule.GetRegisteredType (fullname.NestedName(ident));
1613                         if (datablobtype == null) {
1614                                 TypeBuilder tb = DefineNestedType (typeName,
1615                                         TypeAttributes.NestedPrivate|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed,
1616                                         pmodule.assemblyb.corlib_value_type, null, PackingSize.Size1, size);
1617                                 tb.CreateType ();
1618                                 datablobtype = tb;
1619                         }
1620                         return DefineField (name, datablobtype, attributes|FieldAttributes.Static|FieldAttributes.HasFieldRVA);
1621                 }
1622
1623                 public TypeToken TypeToken {
1624                         get {
1625                                 return new TypeToken (0x02000000 | table_idx);
1626                         }
1627                 }
1628
1629                 public void SetParent (Type parent)
1630                 {
1631                         check_not_created ();
1632
1633                         if (parent == null) {
1634                                 if ((attrs & TypeAttributes.Interface) != 0) {
1635                                         if ((attrs & TypeAttributes.Abstract) == 0)
1636                                                 throw new InvalidOperationException ("Interface must be declared abstract.");
1637                                         this.parent = null;
1638                                 } else {
1639                                         this.parent = typeof (object);
1640                                 }
1641                         } else {
1642                                 this.parent = parent;
1643                         }
1644                         this.parent = ResolveUserType (this.parent);
1645
1646                         // will just set the parent-related bits if called a second time
1647                         setup_internal_class ();
1648                 }
1649
1650                 internal int get_next_table_index (object obj, int table, bool inc) {
1651                         return pmodule.get_next_table_index (obj, table, inc);
1652                 }
1653
1654                 [ComVisible (true)]
1655                 public override InterfaceMapping GetInterfaceMap (Type interfaceType)
1656                 {
1657                         if (created == null)
1658                                 throw new NotSupportedException ("This method is not implemented for incomplete types.");
1659
1660                         return created.GetInterfaceMap (interfaceType);
1661                 }
1662
1663                 internal override Type InternalResolve ()
1664                 {
1665                         check_created ();
1666                         return created;
1667                 }
1668
1669                 internal bool is_created {
1670                         get {
1671                                 return createTypeCalled;
1672                         }
1673                 }
1674
1675                 private Exception not_supported ()
1676                 {
1677                         return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
1678                 }
1679
1680                 private void check_not_created ()
1681                 {
1682                         if (is_created)
1683                                 throw new InvalidOperationException ("Unable to change after type has been created.");
1684                 }
1685
1686                 private void check_created ()
1687                 {
1688                         if (!is_created)
1689                                 throw not_supported ();
1690                 }
1691
1692                 private void check_name (string argName, string name)
1693                 {
1694                         if (name == null)
1695                                 throw new ArgumentNullException (argName);
1696                         if (name.Length == 0)
1697                                 throw new ArgumentException ("Empty name is not legal", argName);
1698                         if (name [0] == ((char)0))
1699                                 throw new ArgumentException ("Illegal name", argName);
1700                 }
1701
1702                 public override String ToString ()
1703                 {
1704                         return FullName;
1705                 }
1706
1707                 [MonoTODO]
1708                 public override bool IsAssignableFrom (Type c)
1709                 {
1710                         return base.IsAssignableFrom (c);
1711                 }
1712
1713                 [MonoTODO ("arrays")]
1714                 internal bool IsAssignableTo (Type c)
1715                 {
1716                         if (c == this)
1717                                 return true;
1718
1719                         if (c.IsInterface) {
1720                                 if (parent != null && is_created) {
1721                                         if (c.IsAssignableFrom (parent))
1722                                                 return true;
1723                                 }
1724
1725                                 if (interfaces == null)
1726                                         return false;
1727                                 foreach (Type t in interfaces)
1728                                         if (c.IsAssignableFrom (t))
1729                                                 return true;
1730                                 if (!is_created)
1731                                         return false;
1732                         }
1733
1734                         if (parent == null)
1735                                 return c == typeof (object);
1736                         else
1737                                 return c.IsAssignableFrom (parent);
1738                 }
1739
1740                 public bool IsCreated ()
1741                 {
1742                         return is_created;
1743                 }
1744
1745                 public override Type[] GetGenericArguments ()
1746                 {
1747                         if (generic_params == null)
1748                                 return null;
1749                         Type[] args = new Type [generic_params.Length];
1750                         generic_params.CopyTo (args, 0);
1751                         return args;
1752                 }
1753
1754                 public override Type GetGenericTypeDefinition ()
1755                 {
1756                         if (generic_params == null)
1757                                 throw new InvalidOperationException ("Type is not generic");
1758                         return this;
1759                 }
1760
1761                 public override bool ContainsGenericParameters {
1762                         get {
1763                                 return generic_params != null;
1764                         }
1765                 }
1766
1767                 public extern override bool IsGenericParameter {
1768                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1769                         get;
1770                 }
1771
1772                 public override GenericParameterAttributes GenericParameterAttributes {
1773                         get { return GenericParameterAttributes.None; }
1774                 }
1775
1776                 public override bool IsGenericTypeDefinition {
1777                         get {
1778                                 return generic_params != null;
1779                         }
1780                 }
1781
1782                 public override bool IsGenericType {
1783                         get { return IsGenericTypeDefinition; }
1784                 }
1785
1786                 [MonoTODO]
1787                 public override int GenericParameterPosition {
1788                         get {
1789                                 return 0;
1790                         }
1791                 }
1792
1793                 public override MethodBase DeclaringMethod {
1794                         get {
1795                                 return null;
1796                         }
1797                 }
1798
1799                 public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
1800                 {
1801                         if (names == null)
1802                                 throw new ArgumentNullException ("names");
1803                         if (names.Length == 0)
1804                                 throw new ArgumentException ("names");
1805
1806                         generic_params = new GenericTypeParameterBuilder [names.Length];
1807                         for (int i = 0; i < names.Length; i++) {
1808                                 string item = names [i];
1809                                 if (item == null)
1810                                         throw new ArgumentNullException ("names");
1811                                 generic_params [i] = new GenericTypeParameterBuilder (this, null, item, i);
1812                         }
1813
1814                         return generic_params;
1815                 }
1816
1817                 public static ConstructorInfo GetConstructor (Type type, ConstructorInfo constructor)
1818                 {
1819                         /*FIXME I would expect the same checks of GetMethod here*/
1820                         if (type == null)
1821                                 throw new ArgumentException ("Type is not generic", "type");
1822
1823                         if (!type.IsGenericType)
1824                                 throw new ArgumentException ("Type is not a generic type", "type");
1825
1826                         if (type.IsGenericTypeDefinition)
1827                                 throw new ArgumentException ("Type cannot be a generic type definition", "type");
1828
1829                         if (constructor == null)
1830                                 throw new NullReferenceException (); //MS raises this instead of an ArgumentNullException
1831
1832                         if (!constructor.DeclaringType.IsGenericTypeDefinition)
1833                                 throw new ArgumentException ("constructor declaring type is not a generic type definition", "constructor");
1834                         if (constructor.DeclaringType != type.GetGenericTypeDefinition ())
1835                                 throw new ArgumentException ("constructor declaring type is not the generic type definition of type", "constructor");
1836
1837                         ConstructorInfo res = type.GetConstructor (constructor);
1838                         if (res == null)
1839                                 throw new ArgumentException ("constructor not found");
1840
1841                         return res;
1842                 }
1843
1844                 static bool IsValidGetMethodType (Type type)
1845                 {
1846                         if (type is TypeBuilder || type is MonoGenericClass)
1847                                 return true;
1848                         /*GetMethod() must work with TypeBuilders after CreateType() was called.*/
1849                         if (type.Module is ModuleBuilder)
1850                                 return true;
1851                         if (type.IsGenericParameter)
1852                                 return false;
1853
1854                         Type[] inst = type.GetGenericArguments ();
1855                         if (inst == null)
1856                                 return false;
1857                         for (int i = 0; i < inst.Length; ++i) {
1858                                 if (IsValidGetMethodType (inst [i]))
1859                                         return true;
1860                         }
1861                         return false;
1862                 }
1863
1864                 public static MethodInfo GetMethod (Type type, MethodInfo method)
1865                 {
1866                         if (!IsValidGetMethodType (type))
1867                                 throw new ArgumentException ("type is not TypeBuilder but " + type.GetType (), "type");
1868
1869                         if (type is TypeBuilder && type.ContainsGenericParameters)
1870                                 type = type.MakeGenericType (type.GetGenericArguments ());
1871
1872                         if (!type.IsGenericType)
1873                                 throw new ArgumentException ("type is not a generic type", "type");
1874
1875                         if (!method.DeclaringType.IsGenericTypeDefinition)
1876                                 throw new ArgumentException ("method declaring type is not a generic type definition", "method");
1877                         if (method.DeclaringType != type.GetGenericTypeDefinition ())
1878                                 throw new ArgumentException ("method declaring type is not the generic type definition of type", "method");
1879                         if (method == null)
1880                                 throw new NullReferenceException (); //MS raises this instead of an ArgumentNullException
1881
1882                         MethodInfo res = type.GetMethod (method);
1883                         if (res == null)
1884                                 throw new ArgumentException (String.Format ("method {0} not found in type {1}", method.Name, type));
1885                                 
1886                         return res;
1887                 }
1888
1889                 public static FieldInfo GetField (Type type, FieldInfo field)
1890                 {
1891                         if (!type.IsGenericType)
1892                                 throw new ArgumentException ("Type is not a generic type", "type");
1893
1894                         if (type.IsGenericTypeDefinition)
1895                                 throw new ArgumentException ("Type cannot be a generic type definition", "type");
1896
1897                         if (field is FieldOnTypeBuilderInst)
1898                                 throw new ArgumentException ("The specified field must be declared on a generic type definition.", "field");
1899
1900                         if (field.DeclaringType != type.GetGenericTypeDefinition ())
1901                                 throw new ArgumentException ("field declaring type is not the generic type definition of type", "method");
1902
1903                         FieldInfo res = type.GetField (field);
1904                         if (res == null)
1905                                 throw new System.Exception ("field not found");
1906                         else
1907                                 return res;
1908                 }
1909
1910
1911                 void _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1912                 {
1913                         throw new NotImplementedException ();
1914                 }
1915
1916                 void _TypeBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1917                 {
1918                         throw new NotImplementedException ();
1919                 }
1920
1921                 void _TypeBuilder.GetTypeInfoCount (out uint pcTInfo)
1922                 {
1923                         throw new NotImplementedException ();
1924                 }
1925
1926                 void _TypeBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1927                 {
1928                         throw new NotImplementedException ();
1929                 }
1930
1931                 internal override bool IsUserType {
1932                         get {
1933                                 return false;
1934                         }
1935                 }
1936
1937                 public override bool IsConstructedGenericType {
1938                         get { return false; }
1939                 }
1940
1941                 public override bool IsAssignableFrom (TypeInfo typeInfo)
1942                 {
1943                         return base.IsAssignableFrom (typeInfo);
1944                 }
1945         }
1946 }
1947 #endif