6ae0a2400f2bda50599264e6fdee8267cbbd783f
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / TypeBuilderTest.cs
1
2 //
3 // TypeBuilderTest.cs - NUnit Test Cases for the TypeBuilder class
4 //
5 // Zoltan Varga (vargaz@freemail.hu)
6 //
7 // (C) Ximian, Inc.  http://www.ximian.com
8 //
9 // TODO:
10 //  - implement a mechnanism for easier testing of null argument exceptions
11 //  - with overloaded methods like DefineNestedType (), check the defaults
12 //    on the shorter versions.
13 //  - ToString on enums with the flags attribute set should print all
14 //    values which match, e.g. 0 == AutoLayou,AnsiClass,NotPublic
15 //
16
17 using System;
18 using System.Threading;
19 using System.Reflection;
20 using System.Reflection.Emit;
21 using System.IO;
22 using System.Security;
23 using System.Security.Permissions;
24 using System.Runtime.InteropServices;
25 using NUnit.Framework;
26
27 namespace MonoTests.System.Reflection.Emit
28 {
29
30 [TestFixture]
31 public class TypeBuilderTest : Assertion
32 {       
33         private interface AnInterface {
34         }
35
36         interface Foo {
37         }
38
39         interface Bar : Foo {
40         }
41
42         interface Baz : Bar {
43         }
44
45         private AssemblyBuilder assembly;
46
47         private ModuleBuilder module;
48
49         static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
50
51         [SetUp]
52         protected void SetUp () {
53                 AssemblyName assemblyName = new AssemblyName();
54                 assemblyName.Name = ASSEMBLY_NAME;
55
56                 assembly = 
57                         Thread.GetDomain().DefineDynamicAssembly(
58                                 assemblyName, AssemblyBuilderAccess.RunAndSave, Path.GetTempPath ());
59
60                 module = assembly.DefineDynamicModule("module1");
61         }
62
63         static int typeIndexer = 0;
64
65         // Return a unique type name
66         private string genTypeName () {
67                 return "t" + (typeIndexer ++);
68         }
69
70         private string nullName () {
71                 return String.Format ("{0}", (char)0);
72         }
73
74         [Test]
75         public void TestAssembly () {
76                 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
77                 AssertEquals ("Assembly works",
78                                           tb.Assembly, assembly);
79         }
80
81         [Test]
82         public void TestAssemblyQualifiedName () {
83                 TypeBuilder tb = module.DefineType ("A.B.C.D", TypeAttributes.Public);
84
85                 AssertEquals ("AssemblyQualifiedName works",
86                                           tb.AssemblyQualifiedName, "A.B.C.D, " + assembly.GetName ().FullName);
87         }
88
89         [Test]
90         public void TestAttributes () {
91                 TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.BeforeFieldInit;
92                 TypeBuilder tb = module.DefineType (genTypeName (), attrs);
93
94                 AssertEquals ("Attributes works",
95                                           tb.Attributes, attrs);
96         }
97
98         [Test]
99         public void TestBaseTypeClass () {
100                 TypeAttributes attrs = TypeAttributes.Public;
101                 TypeBuilder tb = module.DefineType (genTypeName (), attrs);
102                 AssertEquals ("BaseType defaults to Object",
103                                           tb.BaseType, typeof (object));
104
105                 TypeBuilder tb2 = module.DefineType (genTypeName (), attrs, tb);
106                 AssertEquals ("BaseType works",
107                                           tb2.BaseType, tb);
108         }
109
110         [Test]
111         [Category("NotWorking")]
112         // See bug: 71301
113         public void TestBaseTypeInterface ()
114         {
115                 TypeBuilder tb3 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
116                 AssertEquals ("Interfaces should default to no base type", null, tb3.BaseType);
117         }
118
119         [Test]
120         public void TestDeclaringType () {
121                 TypeAttributes attrs = 0;
122                 TypeBuilder tb = module.DefineType (genTypeName (), attrs);
123
124                 AssertEquals ("Has no declaring type",
125                                           null, tb.DeclaringType);
126
127                 attrs = TypeAttributes.NestedPublic;
128                 TypeBuilder tb2 = tb.DefineNestedType (genTypeName (), attrs);
129                 TypeBuilder tb3 = tb2.DefineNestedType (genTypeName (), attrs);
130                 AssertEquals ("DeclaringType works",
131                                           tb, tb3.DeclaringType.DeclaringType);
132         }
133
134         [Test]
135         public void TestFullName () {
136                 string name = genTypeName ();
137                 TypeAttributes attrs = 0;
138                 TypeBuilder tb = module.DefineType (name, attrs);
139                 AssertEquals ("FullName works",
140                                           name, tb.FullName);
141
142                 string name2 = genTypeName ();
143                 attrs = TypeAttributes.NestedPublic;
144                 TypeBuilder tb2 = tb.DefineNestedType (name2, attrs);
145
146                 string name3 = genTypeName ();
147                 attrs = TypeAttributes.NestedPublic;
148                 TypeBuilder tb3 = tb2.DefineNestedType (name3, attrs);
149
150                 AssertEquals ("FullName works on nested types",
151                                           name + "+" + name2 + "+" + name3, tb3.FullName);
152         }
153
154         [Test]
155         [ExpectedException (typeof(NotSupportedException))]
156         public void TestGUIDIncomplete () {
157                 TypeBuilder tb = module.DefineType (genTypeName ());
158                 Guid g = tb.GUID;
159         }
160
161         [Test]
162         [Category("NotWorking")]
163                 // See bug: 71302
164         public void TestGUIDComplete ()
165         {
166                 TypeBuilder tb = module.DefineType (genTypeName ());
167                 tb.CreateType ();
168                 Assert(tb.GUID != Guid.Empty);
169         }
170
171         [Test]
172         [Category("NotWorking")]
173         public void TestFixedGUIDComplete ()
174         {
175                 TypeBuilder tb = module.DefineType (genTypeName ());
176
177                 Guid guid = Guid.NewGuid ();
178
179                 ConstructorInfo guidCtor = typeof(GuidAttribute).GetConstructor(
180                         new Type[] {typeof(string)});
181
182                 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (guidCtor,
183                         new object[] { guid.ToString("D") }, new FieldInfo[0], new object[0]);
184
185                 tb.SetCustomAttribute (caBuilder);
186                 tb.CreateType ();
187                 AssertEquals (guid, tb.GUID);
188         }
189
190         [Test]
191         [ExpectedException (typeof(NotSupportedException))]
192         public void TestHasElementType () {
193                 // According to the MSDN docs, this member works, but in reality, it
194                 // returns a NotSupportedException
195                 TypeBuilder tb = module.DefineType (genTypeName ());
196                 bool b = tb.HasElementType;
197         }
198
199         [Test]
200         public void TestIsAbstract () {
201                 TypeBuilder tb = module.DefineType (genTypeName ());
202                 AssertEquals ("",
203                                           false, tb.IsAbstract);
204
205                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Abstract);
206                 AssertEquals ("",
207                                           true, tb2.IsAbstract);
208         }
209
210         [Test]
211         public void TestIsAnsiClass () {
212                 TypeBuilder tb = module.DefineType (genTypeName ());
213                 AssertEquals ("",
214                                           true, tb.IsAnsiClass);
215
216                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass);
217                 AssertEquals ("",
218                                           false, tb2.IsAnsiClass);
219         }
220
221         [Test]
222         public void TestIsArray () {
223                 // How can a TypeBuilder be an array ?
224                 string name = genTypeName ();
225                 TypeBuilder tb = module.DefineType (name);
226                 AssertEquals ("IsArray works",
227                                           false, tb.IsArray);
228         }
229
230         [Test]
231         public void TestIsAutoClass () {
232                 TypeBuilder tb = module.DefineType (genTypeName ());
233                 AssertEquals ("",
234                                           false, tb.IsAutoClass);
235
236                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.AutoClass);
237                 AssertEquals ("",
238                                           true, tb2.IsAutoClass);
239         }
240
241         [Test]
242         public void TestIsAutoLayout () {
243                 TypeBuilder tb = module.DefineType (genTypeName ());
244                 AssertEquals ("AutoLayout defaults to true",
245                                           true, tb.IsAutoLayout);
246
247                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout);
248                 AssertEquals ("",
249                                           false, tb2.IsAutoLayout);
250         }
251
252         [Test]
253         public void TestIsByRef () {
254                 // How can a TypeBuilder be ByRef ?
255                 TypeBuilder tb = module.DefineType (genTypeName ());
256                 AssertEquals ("IsByRef works",
257                                           false, tb.IsByRef);
258         }
259
260         [Test]
261         public void TestIsClass () {
262                 TypeBuilder tb = module.DefineType (genTypeName ());
263                 AssertEquals ("Most types are classes",
264                                           true, tb.IsClass);
265
266                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
267                 AssertEquals ("Interfaces are not classes",
268                                           false, tb2.IsClass);
269
270                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));
271                 AssertEquals ("value types are not classes",
272                                           false, tb3.IsClass);
273
274                 TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum));
275                 AssertEquals ("enums are not classes",
276                                           false, tb4.IsClass);
277         }
278
279         [Test]
280         [Category("NotWorking")]
281         // See bug: 71304
282         public void TestIsCOMObject () {
283                 TypeBuilder tb = module.DefineType (genTypeName ());
284                 AssertEquals ("Probably not", false, tb.IsCOMObject);
285
286                 tb = module.DefineType (genTypeName (), TypeAttributes.Import);
287                 AssertEquals ("type with Import attribute is COM object",
288                         true, tb.IsCOMObject);
289         }
290
291         [Test]
292         public void TestIsContextful () {
293                 TypeBuilder tb = module.DefineType (genTypeName ());
294                 AssertEquals (false, tb.IsContextful);
295
296                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject));
297                 AssertEquals (true, tb2.IsContextful);
298         }
299
300         [Test]
301         public void TestIsEnum () {
302                 TypeBuilder tb = module.DefineType (genTypeName ());
303                 AssertEquals (false, tb.IsEnum);
304
305                 // This returns true under both mono and MS .NET ???
306                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ValueType));
307                 AssertEquals ("value types are not necessary enums",
308                         false, tb2.IsEnum);
309
310                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (Enum));
311                 AssertEquals ("enums are enums", true, tb3.IsEnum);
312         }
313
314         [Test]
315         public void TestIsExplicitLayout () {
316                 TypeBuilder tb = module.DefineType (genTypeName ());
317                 AssertEquals ("ExplicitLayout defaults to false",
318                         false, tb.IsExplicitLayout);
319
320                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout);
321                 AssertEquals (true, tb2.IsExplicitLayout);
322         }
323
324         [Test]
325         public void TestIsImport () {
326                 // How can this be true ?
327                 TypeBuilder tb = module.DefineType (genTypeName ());
328                 AssertEquals (false, tb.IsImport);
329         }
330
331         [Test]
332         public void TestIsInterface () {
333                 TypeBuilder tb = module.DefineType (genTypeName ());
334                 AssertEquals ("Most types are not interfaces",
335                         false, tb.IsInterface);
336
337                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
338                 AssertEquals ("Interfaces are interfaces",
339                         true, tb2.IsInterface);
340
341                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));
342                 AssertEquals ("value types are not interfaces",
343                         false, tb3.IsInterface);
344         }
345
346         [Test]
347         public void TestIsLayoutSequential () {
348                 TypeBuilder tb = module.DefineType (genTypeName ());
349                 AssertEquals ("SequentialLayout defaults to false",
350                         false, tb.IsLayoutSequential);
351
352                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SequentialLayout);
353                 AssertEquals (true, tb2.IsLayoutSequential);
354         }
355
356         [Test]
357         public void TestIsMarshalByRef () {
358                 TypeBuilder tb = module.DefineType (genTypeName ());
359                 AssertEquals (false, tb.IsMarshalByRef);
360
361                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (MarshalByRefObject));
362                 AssertEquals (true, tb2.IsMarshalByRef);
363
364                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject));
365                 AssertEquals (true, tb3.IsMarshalByRef);
366         }
367
368         // TODO: Visibility properties
369
370         [Test]
371         public void TestIsPointer () {
372                 // How can this be true?
373                 TypeBuilder tb = module.DefineType (genTypeName ());
374                 AssertEquals (false, tb.IsPointer);
375         }
376
377         [Test]
378         public void TestIsPrimitive () {
379                 TypeBuilder tb = module.DefineType ("int");
380                 AssertEquals (false, tb.IsPrimitive);
381         }
382
383         [Test]
384         public void IsSealed () {
385                 TypeBuilder tb = module.DefineType (genTypeName ());
386                 AssertEquals ("Sealed defaults to false",
387                         false, tb.IsSealed);
388
389                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Sealed);
390                 AssertEquals ("IsSealed works", true, tb2.IsSealed);
391         }
392
393         [Test]
394         public void IsSerializable () {
395                 TypeBuilder tb = module.DefineType (genTypeName ());
396                 AssertEquals (false, tb.IsSerializable);
397
398                 ConstructorInfo[] ctors = typeof (SerializableAttribute).GetConstructors (BindingFlags.Instance | BindingFlags.Public);
399                 Assert ("SerializableAttribute should have more than 0 public instance ctors", 
400                         ctors.Length > 0);
401
402                 tb.SetCustomAttribute (new CustomAttributeBuilder (ctors[0], new object[0]));
403                 Type createdType = tb.CreateType ();
404
405                 assembly.Save ("TestAssembly.dll");
406                 AssertEquals (true, createdType.IsSerializable);
407         }
408
409         [Test]
410         public void TestIsSpecialName () {
411                 TypeBuilder tb = module.DefineType (genTypeName ());
412                 AssertEquals ("SpecialName defaults to false",
413                         false, tb.IsSpecialName);
414
415                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SpecialName);
416                 AssertEquals ("IsSpecialName works",
417                         true, tb2.IsSpecialName);
418         }
419
420         [Test]
421         public void TestIsUnicodeClass () {
422                 TypeBuilder tb = module.DefineType (genTypeName ());
423                 AssertEquals (false, tb.IsUnicodeClass);
424
425                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass);
426                 AssertEquals (true, tb2.IsUnicodeClass);
427         }
428
429         [Test]
430         public void TestIsValueType () {
431                 TypeBuilder tb = module.DefineType (genTypeName ());
432                 AssertEquals ("Most types are not value types",
433                         false, tb.IsValueType);
434
435                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
436                 AssertEquals ("Interfaces are not value types",
437                         false, tb2.IsValueType);
438
439                 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));
440                 AssertEquals ("value types are value types",
441                         true, tb3.IsValueType);
442
443                 TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum));
444                 AssertEquals ("enums are value types",
445                         true, tb4.IsValueType);
446         }
447
448         [Test]
449         public void TestMemberType () {
450                 TypeBuilder tb = module.DefineType (genTypeName ());
451                 AssertEquals ("A type is a type",
452                         MemberTypes.TypeInfo, tb.MemberType);
453         }
454
455         [Test]
456         public void TestModule () {
457                 TypeBuilder tb = module.DefineType (genTypeName ());
458                 AssertEquals ("Module works", module, tb.Module);
459         }
460
461         [Test]
462         public void TestName () {
463                 TypeBuilder tb = module.DefineType ("A");
464                 AssertEquals ("A", tb.Name);
465
466                 TypeBuilder tb2 = module.DefineType ("A.B.C.D.E");
467                 AssertEquals ("E", tb2.Name);
468
469                 TypeBuilder tb3 = tb2.DefineNestedType ("A");
470                 AssertEquals ("A", tb3.Name);
471
472                 /* Is .E a valid name ?
473                 TypeBuilder tb4 = module.DefineType (".E");
474                 AssertEquals ("",
475                                           "E", tb4.Name);
476                 */
477         }
478
479         [Test]
480         public void TestNamespace () {
481                 TypeBuilder tb = module.DefineType ("A");
482                 AssertEquals ("", tb.Namespace);
483
484                 TypeBuilder tb2 = module.DefineType ("A.B.C.D.E");
485                 AssertEquals ("A.B.C.D", tb2.Namespace);
486
487                 TypeBuilder tb3 = tb2.DefineNestedType ("A");
488                 AssertEquals ("", tb3.Namespace);
489
490                 /* Is .E a valid name ?
491                 TypeBuilder tb4 = module.DefineType (".E");
492                 AssertEquals ("",
493                                           "E", tb4.Name);
494                 */              
495         }
496
497         [Test]
498         public void TestPackingSize () {
499                 TypeBuilder tb = module.DefineType (genTypeName ());
500                 AssertEquals (PackingSize.Unspecified, tb.PackingSize);
501
502                 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (object),
503                         PackingSize.Size16, 16);
504                 AssertEquals (PackingSize.Size16, tb2.PackingSize);
505         }
506
507         [Test]
508         public void TestReflectedType () {
509                 // It is the same as DeclaringType, but why?
510                 TypeBuilder tb = module.DefineType (genTypeName ());
511                 AssertEquals (null, tb.ReflectedType);
512
513                 TypeBuilder tb2 = tb.DefineNestedType (genTypeName ());
514                 AssertEquals (tb, tb2.ReflectedType);
515         }
516
517         [Test]
518         [ExpectedException (typeof(ArgumentNullException))]
519         public void TestSetParentNull ()
520         {
521                 TypeBuilder tb = module.DefineType (genTypeName ());
522                 tb.SetParent (null);
523         }
524
525         [Test]
526         public void TestSetParentIncomplete ()
527         {
528                 TypeBuilder tb = module.DefineType (genTypeName ());
529                 tb.SetParent (typeof(Attribute));
530                 AssertEquals (typeof(Attribute), tb.BaseType);
531         }
532
533         [Test]
534         [ExpectedException (typeof(InvalidOperationException))]
535         public void TestSetParentComplete ()
536         {
537                 TypeBuilder tb = module.DefineType (genTypeName ());
538                 tb.CreateType ();
539                 tb.SetParent (typeof(Attribute));
540         }
541
542         [Test]
543         public void TestSize () {
544                 {
545                         TypeBuilder tb = module.DefineType (genTypeName ());
546                         AssertEquals (0, tb.Size);
547                         tb.CreateType ();
548                         AssertEquals (0, tb.Size);
549                 }
550
551                 {
552                         TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (object),
553                                 PackingSize.Size16, 32);
554                         AssertEquals (32, tb.Size);
555                 }
556         }
557
558         [Test]
559         [ExpectedException (typeof(NotSupportedException))]
560         public void TestTypeHandle () {
561                 TypeBuilder tb = module.DefineType (genTypeName ());
562                 RuntimeTypeHandle handle = tb.TypeHandle;
563         }
564
565         [Test]
566         [ExpectedException (typeof(NotSupportedException))]
567         public void TestTypeInitializerIncomplete ()
568         {
569                 TypeBuilder tb = module.DefineType (genTypeName ());
570                 ConstructorInfo cb = tb.TypeInitializer;
571         }
572
573         [Test]
574         public void TestTypeInitializerComplete ()
575         {
576                 TypeBuilder tb = module.DefineType (genTypeName ());
577                 tb.CreateType ();
578                 ConstructorInfo cb = tb.TypeInitializer;
579         }
580
581         [Test]
582         public void TestTypeToken () {
583                 TypeBuilder tb = module.DefineType (genTypeName ());
584                 TypeToken token = tb.TypeToken;
585         }
586
587         [Test]
588         [Category("NotWorking")]
589         public void TestUnderlyingSystemType () {
590                 {
591                         TypeBuilder tb = module.DefineType (genTypeName ());
592                         AssertEquals ("For non-enums this equals itself",
593                                                   tb, tb.UnderlyingSystemType);
594                 }
595                 {
596                         TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
597                         AssertEquals (tb, tb.UnderlyingSystemType);
598                 }
599                 {
600                         TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (ValueType));
601                         AssertEquals (tb, tb.UnderlyingSystemType);
602                 }
603
604                 {
605                         TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (Enum));
606                         try {
607                                 Type t = tb.UnderlyingSystemType;
608                                 Fail ();
609                         }
610                         catch (InvalidOperationException) {
611                         }
612
613                         tb.DefineField ("val", typeof (int), 0);
614                         AssertEquals (typeof (int), tb.UnderlyingSystemType);
615                 }
616         }
617
618         [Test]
619         public void TestAddInterfaceImplementation () {
620                 TypeBuilder tb = module.DefineType (genTypeName ());
621                 try {
622                         tb.AddInterfaceImplementation (null);
623                         Fail ();
624                 }
625                 catch (ArgumentNullException) {
626                 }
627
628                 tb.AddInterfaceImplementation (typeof (AnInterface));
629                 tb.AddInterfaceImplementation (typeof (AnInterface));
630
631                 Type t = tb.CreateType ();
632                 AssertEquals ("Should merge identical interfaces",
633                                           tb.GetInterfaces ().Length, 1);
634
635                 // Can not be called on a created type
636                 try {
637                         tb.AddInterfaceImplementation (typeof (AnInterface));
638                         Fail ();
639                 }
640                 catch (InvalidOperationException) {
641                 }
642         }
643
644         [Test]
645         [Category("NotWorking")]
646         public void TestCreateType () {
647                 // TODO: LOTS OF TEST SHOULD GO THERE
648                 TypeBuilder tb = module.DefineType (genTypeName ());
649                 tb.CreateType ();
650
651                 // Can not be called on a created type
652                 try {
653                         tb.CreateType ();
654                         Fail ();
655                 }
656                 catch (InvalidOperationException) {
657                 }
658         }
659
660         [Test]
661         public void TestDefineConstructor () {
662                 TypeBuilder tb = module.DefineType (genTypeName ());
663
664                 ConstructorBuilder cb = tb.DefineConstructor (0, 0, null);
665                 cb.GetILGenerator ().Emit (OpCodes.Ret);
666                 tb.CreateType ();
667
668                 // Can not be called on a created type
669                 try {
670                         tb.DefineConstructor (0, 0, null);
671                         Fail ();
672                 }
673                 catch (InvalidOperationException) {
674                 }
675         }
676
677         [Test]
678         public void TestDefineDefaultConstructor () {
679                 TypeBuilder tb = module.DefineType (genTypeName ());
680                 tb.DefineDefaultConstructor (0);
681                 tb.CreateType ();
682
683                 // Can not be called on a created type, altough the MSDN docs does not mention this
684                 try {
685                         tb.DefineDefaultConstructor (0);
686                         Fail ();
687                 }
688                 catch (InvalidOperationException) {
689                 }
690         }
691
692         [Test]
693         [ExpectedException (typeof(InvalidOperationException))]
694         [Category("NotWorking")]
695         public void TestDefineDefaultConstructorParent () {
696                 TypeBuilder tb = module.DefineType (genTypeName ());
697                 tb.DefineConstructor (MethodAttributes.Public,
698                         CallingConventions.Standard, 
699                         new Type[] { typeof(string) });
700                 Type type = tb.CreateType ();
701
702                 // create TypeBuilder for type that derived from the 
703                 // previously created type (which has no default ctor)
704                 tb = module.DefineType (genTypeName (), TypeAttributes.Class
705                         | TypeAttributes.Public, type);
706
707                 // you cannot create a type with a default ctor that
708                 // derives from a type without a default ctor
709                 tb.CreateType ();
710         }
711
712         [Test]
713         public void TestDefineEvent () {
714                 TypeBuilder tb = module.DefineType (genTypeName ());
715
716                 // Test invalid arguments
717                 try {
718                         tb.DefineEvent (null, 0, typeof (int));
719                         Fail ();
720                 }
721                 catch (ArgumentNullException) {
722                 }
723
724                 try {
725                         tb.DefineEvent ("FOO", 0, null);
726                         Fail ();
727                 }
728                 catch (ArgumentNullException) {
729                 }
730
731                 try {
732                         tb.DefineEvent ("", 0, typeof (int));
733                         Fail ();
734                 }
735                 catch (ArgumentException) {
736                 }
737
738                 tb.CreateType ();
739                 // Can not be called on a created type
740                 try {
741                         tb.DefineEvent ("BAR", 0, typeof (int));
742                         Fail ();
743                 }
744                 catch (InvalidOperationException) {
745                 }
746         }
747
748         [Test]
749         public void TestDefineField () {
750                 TypeBuilder tb = module.DefineType (genTypeName ());
751
752                 // Check invalid arguments
753                 try {
754                         tb.DefineField (null, typeof (int), 0);
755                         Fail ();
756                 }
757                 catch (ArgumentNullException) {
758                 }
759
760                 try {
761                         tb.DefineField ("", typeof (int), 0);
762                         Fail ();
763                 }
764                 catch (ArgumentException) {
765                 }
766
767                 try {
768                         // Strangely, 'A<NULL>' is accepted...
769                         string name = String.Format ("{0}", (char)0);
770                         tb.DefineField (name, typeof (int), 0);
771                         Fail ("Names with embedded nulls should be rejected");
772                 }
773                 catch (ArgumentException) {
774                 }
775
776                 try {
777                         tb.DefineField ("A", typeof (void), 0);
778                         Fail ();
779                 }
780                 catch (ArgumentException) {
781                 }
782
783                 tb.CreateType ();
784                 // Can not be called on a created type
785                 try {
786                         tb.DefineField ("B", typeof (int), 0);
787                         Fail ();
788                 }
789                 catch (InvalidOperationException) {
790                 }
791         }
792
793         [Test]
794         public void TestDefineInitializedData () {
795                 TypeBuilder tb = module.DefineType (genTypeName ());
796                 
797                 // Check invalid arguments
798                 try {
799                         tb.DefineInitializedData (null, new byte[1], 0);
800                         Fail ();
801                 }
802                 catch (ArgumentNullException) {
803                 }
804
805                 try {
806                         tb.DefineInitializedData ("FOO", null, 0);
807                         Fail ();
808                 }
809                 catch (ArgumentNullException) {
810                 }
811
812                 try {
813                         tb.DefineInitializedData ("", new byte[1], 0);
814                         Fail ();
815                 }
816                 catch (ArgumentException) {
817                 }
818
819                 // The size of the data is less than or equal to zero ???
820                 try {
821                         tb.DefineInitializedData ("BAR", new byte[0], 0);
822                         Fail ();
823                 }
824                 catch (ArgumentException) {
825                 }
826
827                 try {
828                         string name = String.Format ("{0}", (char)0);
829                         tb.DefineInitializedData (name, new byte[1], 0);
830                         Fail ("Names with embedded nulls should be rejected");
831                 }
832                 catch (ArgumentException) {
833                 }
834
835                 tb.CreateType ();
836
837                 // Can not be called on a created type, altough the MSDN docs does not mention this
838                 try {
839                         tb.DefineInitializedData ("BAR2", new byte[1], 0);
840                         Fail ();
841                 }
842                 catch (InvalidOperationException) {
843                 }
844         }
845
846         [Test]
847         public void DefineUninitializedDataInvalidArgs () {
848                 TypeBuilder tb = module.DefineType (genTypeName ());
849                 
850                 try {
851                         tb.DefineUninitializedData (null, 1, 0);
852                         Fail ();
853                 }
854                 catch (ArgumentNullException) {
855                 }
856
857                 try {
858                         tb.DefineUninitializedData ("", 1, 0);
859                         Fail ();
860                 }
861                 catch (ArgumentException) {
862                 }
863
864                 // The size of the data is less than or equal to zero ???
865                 try {
866                         tb.DefineUninitializedData ("BAR", 0, 0);
867                         Fail ();
868                 }
869                 catch (ArgumentException) {
870                 }
871
872                 try {
873                         string name = String.Format ("{0}", (char)0);
874                         tb.DefineUninitializedData (name, 1, 0);
875                         Fail ("Names with embedded nulls should be rejected");
876                 }
877                 catch (ArgumentException) {
878                 }
879         }
880
881         [Test]
882         [ExpectedException (typeof (InvalidOperationException))]
883         public void DefineUninitializedDataAlreadyCreated () {
884                 TypeBuilder tb = module.DefineType (genTypeName ());
885                 tb.CreateType ();
886
887                 tb.DefineUninitializedData ("BAR2", 1, 0);
888         }
889
890         [Test]
891         public void DefineUninitializedData () {
892                 TypeBuilder tb = module.DefineType (genTypeName ());
893
894                 tb.DefineUninitializedData ("foo", 4, FieldAttributes.Public);
895
896                 Type t = tb.CreateType ();
897
898                 object o = Activator.CreateInstance (t);
899
900                 FieldInfo fi = t.GetField ("foo");
901
902                 object fieldVal = fi.GetValue (o);
903
904                 IntPtr ptr = Marshal.AllocHGlobal (4);
905                 Marshal.StructureToPtr (fieldVal, ptr, true);
906                 Marshal.FreeHGlobal (ptr);
907         }
908
909         [Test]
910         public void TestDefineMethod () {
911                 TypeBuilder tb = module.DefineType (genTypeName ());
912
913                 // Check invalid arguments
914                 try {
915                         tb.DefineMethod (null, 0, null, null);
916                         Fail ();
917                 }
918                 catch (ArgumentNullException) {
919                 }
920
921                 try {
922                         tb.DefineMethod ("", 0, null, null);
923                         Fail ();
924                 }
925                 catch (ArgumentException) {
926                 }
927
928                 // Check non-virtual methods on an interface
929                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
930                 try {
931                         tb2.DefineMethod ("FOO", MethodAttributes.Abstract, null, null);
932                         Fail ();
933                 }
934                 catch (ArgumentException) {
935                 }
936
937                 tb.CreateType ();
938                 // Can not be called on a created type
939                 try {
940                         tb.DefineMethod ("bar", 0, null, null);
941                         Fail ();
942                 }
943                 catch (InvalidOperationException) {
944                 }
945         }
946
947         // TODO: DefineMethodOverride
948
949         [Test]
950         public void TestDefineNestedType () {
951                 TypeBuilder tb = module.DefineType (genTypeName ());
952
953                 // Check invalid arguments
954                 try {
955                         tb.DefineNestedType (null);
956                         Fail ("Should reject null name");
957                 }
958                 catch (ArgumentNullException) {
959                 }
960
961                 try {
962                         tb.DefineNestedType ("");
963                         Fail ("Should reject empty name");
964                 }
965                 catch (ArgumentException) {
966                 }
967
968                 try {
969                         tb.DefineNestedType (nullName ());
970                         Fail ("Should reject name with embedded 0s");
971                 }
972                 catch (ArgumentException) {
973                 }
974
975                 // If I fix the code so this works then mcs breaks -> how can mcs
976                 // works under MS .NET in the first place ???
977                 /*
978                 try {
979                         tb.DefineNestedType ("AA", TypeAttributes.Public, null, null);
980                         Fail ("Nested visibility must be specified.");
981                 }
982                 catch (ArgumentException) {
983                 }
984                 */
985
986                 try {
987                         tb.DefineNestedType ("BB", TypeAttributes.NestedPublic, null,
988                                                                  new Type[1]);
989                         Fail ("Should reject empty interface");
990                 }
991                 catch (ArgumentException) {
992                 }
993
994                 // I think this should reject non-interfaces, but it does not
995                 tb.DefineNestedType ("BB", TypeAttributes.NestedPublic, null,
996                                                          new Type[1] { typeof (object) });
997
998                 // Normal invocation
999                 tb.DefineNestedType ("Nest");
1000
1001                 tb.CreateType ();
1002
1003                 // According to the MSDN docs, this cannnot be called after the type
1004                 // is created, but it works.
1005                 tb.DefineNestedType ("Nest2");
1006
1007                 // According to the MSDN docs, a Sealed class can't contain nested 
1008                 // types, but this is not true
1009                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Sealed);
1010                 tb2.DefineNestedType ("AA");
1011
1012                 // According to the MSDN docs, interfaces can only contain interfaces,
1013                 // but this is not true
1014                 TypeBuilder tb3 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
1015
1016                 tb3.DefineNestedType ("AA");
1017
1018                 // Check shorter versions
1019                 {
1020                         TypeBuilder nested = tb.DefineNestedType ("N1");
1021
1022                         AssertEquals (nested.Name, "N1");
1023                         AssertEquals (nested.BaseType, typeof (object));
1024                         AssertEquals (nested.Attributes, TypeAttributes.NestedPrivate);
1025                         AssertEquals (nested.GetInterfaces ().Length, 0);
1026                 }
1027
1028                 // TODO:
1029         }
1030
1031         [Test]
1032         public void TestDefinePInvokeMethod () {
1033                 TypeBuilder tb = module.DefineType (genTypeName ());
1034
1035                 tb.DefinePInvokeMethod ("A", "B", "C", 0, 0, null, null, 0, 0);
1036
1037                 // Try invalid parameters
1038                 try {
1039                         tb.DefinePInvokeMethod (null, "B", "C", 0, 0, null, null, 0, 0);
1040                         Fail ();
1041                 }
1042                 catch (ArgumentNullException) {
1043                 }
1044                 // etc...
1045
1046                 // Try invalid attributes
1047                 try {
1048                         tb.DefinePInvokeMethod ("A2", "B", "C", MethodAttributes.Abstract, 0, null, null, 0, 0);
1049                 }
1050                 catch (ArgumentException) {
1051                 }
1052
1053                 // Try an interface parent
1054                 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
1055
1056                 try {
1057                         tb2.DefinePInvokeMethod ("A", "B", "C", 0, 0, null, null, 0, 0);
1058                 }
1059                 catch (ArgumentException) {
1060                 }
1061         }
1062
1063         [Test]
1064         public void TestDefineProperty () {
1065                 TypeBuilder tb = module.DefineType (genTypeName ());
1066
1067                 // Check null parameter types
1068                 try {
1069                         tb.DefineProperty ("A", 0, null, new Type[1]);
1070                 }
1071                 catch (ArgumentNullException) {
1072                 }
1073         }
1074
1075         [Test]
1076         [ExpectedException (typeof(NotSupportedException))]
1077         [Category("NotWorking")]
1078         public void TestIsDefinedIncomplete () {
1079                 TypeBuilder tb = module.DefineType (genTypeName ());
1080                 tb.IsDefined (typeof (int), true);
1081         }
1082
1083         [Test]
1084         public void TestIsDefinedComplete () {
1085                 TypeBuilder tb = module.DefineType (genTypeName ());
1086
1087                 ConstructorInfo obsoleteCtor = typeof(ObsoleteAttribute).GetConstructor(
1088                         new Type[] {typeof(string)});
1089
1090                 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (obsoleteCtor,
1091                         new object[] { "obsolete message" }, new FieldInfo[0], new object[0]);
1092
1093                 tb.SetCustomAttribute (caBuilder);
1094                 tb.CreateType ();
1095                 AssertEquals (true, tb.IsDefined (typeof(ObsoleteAttribute), false));
1096         }
1097
1098         [Test]
1099         [ExpectedException (typeof(NotSupportedException))]
1100         public void TestGetCustomAttributesIncomplete ()
1101         {
1102                 TypeBuilder tb = module.DefineType (genTypeName ());
1103                 tb.GetCustomAttributes (false);
1104         }
1105
1106         [Test]
1107         public void TestGetCustomAttributesComplete ()
1108         {
1109                 TypeBuilder tb = module.DefineType (genTypeName ());
1110
1111                 ConstructorInfo guidCtor = typeof(GuidAttribute).GetConstructor (
1112                         new Type[] { typeof(string) });
1113
1114                 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (guidCtor,
1115                         new object[] { Guid.NewGuid ().ToString ("D") }, new FieldInfo[0], new object[0]);
1116
1117                 tb.SetCustomAttribute (caBuilder);
1118                 tb.CreateType ();
1119
1120                 AssertEquals (1, tb.GetCustomAttributes (false).Length);
1121         }
1122
1123         [Test]
1124         [ExpectedException (typeof(NotSupportedException))]
1125         public void TestGetCustomAttributesOfTypeIncomplete ()
1126         {
1127                 TypeBuilder tb = module.DefineType (genTypeName ());
1128                 tb.GetCustomAttributes (typeof(ObsoleteAttribute), false);
1129         }
1130
1131         [Test]
1132         public void TestGetCustomAttributesOfTypeComplete ()
1133         {
1134                 TypeBuilder tb = module.DefineType (genTypeName ());
1135
1136                 ConstructorInfo guidCtor = typeof(GuidAttribute).GetConstructor (
1137                         new Type[] { typeof(string) });
1138
1139                 CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (guidCtor,
1140                         new object[] { Guid.NewGuid ().ToString ("D") }, new FieldInfo[0], new object[0]);
1141
1142                 tb.SetCustomAttribute (caBuilder);
1143                 tb.CreateType ();
1144
1145                 AssertEquals (1, tb.GetCustomAttributes (typeof(GuidAttribute), false).Length);
1146                 AssertEquals (0, tb.GetCustomAttributes (typeof(ObsoleteAttribute), false).Length);
1147         }
1148
1149         [Test]
1150         [ExpectedException (typeof(ArgumentNullException))]
1151         public void TestGetCustomAttributesOfNullTypeComplete ()
1152         {
1153                 TypeBuilder tb = module.DefineType (genTypeName ());
1154                 tb.CreateType ();
1155                 tb.GetCustomAttributes (null, false);
1156         }
1157
1158         [Test]
1159         [ExpectedException (typeof(NotSupportedException))]
1160         [Ignore("mcs depends on this")]
1161         public void TestGetEventsIncomplete () {
1162                 TypeBuilder tb = module.DefineType (genTypeName ());
1163                 tb.GetEvents ();
1164         }
1165
1166         [Test]
1167         public void TestGetEventsComplete () {
1168                 TypeBuilder tb = module.DefineType (genTypeName ());
1169
1170                 MethodBuilder onclickMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public, 
1171                         typeof(void), new Type[] { typeof(Object) });
1172                 onclickMethod.GetILGenerator ().Emit (OpCodes.Ret);
1173
1174                 // create public event
1175                 EventBuilder eventbuilder = tb.DefineEvent ("Change", EventAttributes.None,
1176                         typeof(ResolveEventHandler));
1177                 eventbuilder.SetRaiseMethod (onclickMethod);
1178
1179                 Type emittedType = tb.CreateType ();
1180
1181                 AssertEquals (1, tb.GetEvents ().Length);
1182                 AssertEquals (tb.GetEvents ().Length, emittedType.GetEvents ().Length);
1183         }
1184
1185
1186         [Test]
1187         [ExpectedException (typeof(NotSupportedException))]
1188         [Ignore("mcs depends on this")]
1189         public void TestGetEventsFlagsIncomplete () {
1190                 TypeBuilder tb = module.DefineType (genTypeName ());
1191                 tb.GetEvents (BindingFlags.Public);
1192         }
1193
1194         [Test]
1195         public void TestGetEventsFlagsComplete () {
1196                 TypeBuilder tb = module.DefineType (genTypeName ());
1197
1198                 MethodBuilder onchangeMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public,
1199                         typeof(void), new Type[] { typeof(Object) });
1200                 onchangeMethod.GetILGenerator ().Emit (OpCodes.Ret);
1201
1202                 // create public event
1203                 EventBuilder changeEvent = tb.DefineEvent ("Change", EventAttributes.None,
1204                         typeof(ResolveEventHandler));
1205                 changeEvent.SetRaiseMethod (onchangeMethod);
1206
1207                 // create non-public event
1208                 EventBuilder redoChangeEvent = tb.DefineEvent ("RedoChange", EventAttributes.None,
1209                         typeof(ResolveEventHandler));
1210
1211                 Type emittedType = tb.CreateType ();
1212
1213                 AssertEquals (1, tb.GetEvents (BindingFlags.Instance | BindingFlags.Public).Length);
1214                 AssertEquals (1, tb.GetEvents (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1215                 AssertEquals (2, tb.GetEvents (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length);
1216                 AssertEquals (tb.GetEvents (BindingFlags.Instance | BindingFlags.Public).Length,
1217                         emittedType.GetEvents (BindingFlags.Instance | BindingFlags.Public).Length);
1218                 AssertEquals (tb.GetEvents (BindingFlags.Instance | BindingFlags.NonPublic).Length,
1219                         emittedType.GetEvents (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1220                 AssertEquals (tb.GetEvents (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length,
1221                         emittedType.GetEvents (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length);
1222         }
1223
1224         [Test]
1225         [ExpectedException (typeof(NotSupportedException))]
1226         [Ignore("mcs depends on this")]
1227         public void TestGetEventIncomplete () {
1228                 TypeBuilder tb = module.DefineType (genTypeName ());
1229                 tb.GetEvent ("FOO");
1230         }
1231
1232         [Test]
1233         public void TestGetEventComplete () {
1234                 TypeBuilder tb = module.DefineType (genTypeName ());
1235
1236                 MethodBuilder onclickMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public,
1237                         typeof(void), new Type[] { typeof(Object) });
1238                 onclickMethod.GetILGenerator ().Emit (OpCodes.Ret);
1239
1240                 EventBuilder eventbuilder = tb.DefineEvent ("Change", EventAttributes.None,
1241                         typeof(ResolveEventHandler));
1242                 eventbuilder.SetRaiseMethod (onclickMethod);
1243
1244                 Type emittedType = tb.CreateType ();
1245
1246                 AssertNotNull (tb.GetEvent ("Change"));
1247                 AssertEquals (tb.GetEvent ("Change"), emittedType.GetEvent ("Change"));
1248                 AssertNull (tb.GetEvent ("NotChange"));
1249                 AssertEquals (tb.GetEvent ("NotChange"), emittedType.GetEvent ("NotChange"));
1250         }
1251
1252         [Test]
1253         [ExpectedException (typeof(NotSupportedException))]
1254         [Ignore("mcs depends on this")]
1255         public void TestGetEventFlagsIncomplete () {
1256                 TypeBuilder tb = module.DefineType (genTypeName ());
1257                 tb.GetEvent ("FOO", BindingFlags.Public);
1258         }
1259
1260         [Test]
1261         public void TestGetEventFlagsComplete () {
1262                 TypeBuilder tb = module.DefineType (genTypeName ());
1263
1264                 MethodBuilder onclickMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public,
1265                         typeof(void), new Type[] { typeof(Object) });
1266                 onclickMethod.GetILGenerator ().Emit (OpCodes.Ret);
1267
1268                 EventBuilder eventbuilder = tb.DefineEvent ("Change", EventAttributes.None,
1269                         typeof(ResolveEventHandler));
1270                 eventbuilder.SetRaiseMethod (onclickMethod);
1271
1272                 Type emittedType = tb.CreateType ();
1273
1274                 AssertNotNull (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.Public));
1275                 AssertEquals (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.Public),
1276                         emittedType.GetEvent ("Change", BindingFlags.Instance | BindingFlags.Public));
1277                 AssertNull (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.NonPublic));
1278                 AssertEquals (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.NonPublic),
1279                         emittedType.GetEvent ("Change", BindingFlags.Instance | BindingFlags.NonPublic));
1280         }
1281
1282         [Test]
1283         [ExpectedException (typeof(NotSupportedException))]
1284         [Ignore("mcs depends on this")]
1285         public void TestGetFieldsIncomplete () {
1286                 TypeBuilder tb = module.DefineType (genTypeName ());
1287                 tb.GetFields ();
1288         }
1289
1290         [Test]
1291         public void TestGetFieldsComplete () {
1292                 TypeBuilder tb = module.DefineType (genTypeName ());
1293                 tb.DefineField ("TestField", typeof(int), FieldAttributes.Public);
1294
1295                 Type emittedType = tb.CreateType ();
1296
1297                 AssertEquals (1, tb.GetFields ().Length);
1298                 AssertEquals (tb.GetFields ().Length, emittedType.GetFields().Length);
1299         }
1300
1301         [Test]
1302         [ExpectedException (typeof(NotSupportedException))]
1303         [Ignore("mcs depends on this")]
1304         public void TestGetFieldsFlagsIncomplete () {
1305                 TypeBuilder tb = module.DefineType (genTypeName ());
1306                 tb.GetFields (BindingFlags.Instance | BindingFlags.Public);
1307         }
1308
1309         [Test]
1310         public void TestGetFieldsFlagsComplete () {
1311                 TypeBuilder tb = module.DefineType (genTypeName ());
1312                 tb.DefineField ("TestField", typeof(int), FieldAttributes.Public);
1313
1314                 Type emittedType = tb.CreateType ();
1315
1316                 AssertEquals (1, tb.GetFields (BindingFlags.Instance | BindingFlags.Public).Length);
1317                 AssertEquals (tb.GetFields (BindingFlags.Instance | BindingFlags.Public).Length, 
1318                         emittedType.GetFields (BindingFlags.Instance | BindingFlags.Public).Length);
1319                 AssertEquals (0, tb.GetFields (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1320                 AssertEquals (tb.GetFields (BindingFlags.Instance | BindingFlags.NonPublic).Length,
1321                         emittedType.GetFields (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1322         }
1323
1324         [Test]
1325         [ExpectedException (typeof(NotSupportedException))]
1326         [Ignore("mcs depends on this")]
1327         public void TestGetFieldIncomplete () {
1328                 TypeBuilder tb = module.DefineType (genTypeName ());
1329                 tb.GetField ("test");
1330         }
1331
1332         [Test]
1333         public void TestGetFieldComplete () {
1334                 TypeBuilder tb = module.DefineType (genTypeName ());
1335                 tb.DefineField ("TestField", typeof(int), FieldAttributes.Public);
1336
1337                 Type emittedType = tb.CreateType ();
1338
1339                 AssertNotNull (tb.GetField ("TestField"));
1340                 AssertEquals (tb.GetField ("TestField").Name, emittedType.GetField ("TestField").Name);
1341                 //AssertNull (tb.GetField ("TestOtherField"));
1342                 //AssertEquals (tb.GetField ("TestOtherField").Name, 
1343                 //      emittedType.GetField ("TestOtherField").Name);
1344         }
1345
1346         [Test]
1347         [ExpectedException (typeof(NotSupportedException))]
1348         [Ignore("mcs depends on this")]
1349         public void TestGetFieldFlagsIncomplete () {
1350                 TypeBuilder tb = module.DefineType (genTypeName ());
1351                 tb.GetField ("test", BindingFlags.Public);
1352         }
1353
1354         [Test]
1355         public void TestGetFieldFlagsComplete () {
1356                 TypeBuilder tb = module.DefineType (genTypeName ());
1357                 tb.DefineField ("TestField", typeof(int), FieldAttributes.Public);
1358
1359                 Type emittedType = tb.CreateType ();
1360
1361                 AssertNotNull (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.Public));
1362                 AssertEquals (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.Public).Name,
1363                         emittedType.GetField ("TestField", BindingFlags.Instance | BindingFlags.Public).Name);
1364                 AssertNull (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.NonPublic));
1365                 AssertEquals (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.NonPublic),
1366                         emittedType.GetField ("TestField", BindingFlags.Instance | BindingFlags.NonPublic));
1367         }
1368
1369         [Test]
1370         [ExpectedException (typeof(NotSupportedException))]
1371         [Ignore("mcs depends on this")]
1372         public void TestGetPropertiesIncomplete () {
1373                 TypeBuilder tb = module.DefineType (genTypeName ());
1374                 tb.GetProperties ();
1375         }
1376
1377         [Test]
1378         public void TestGetPropertiesComplete () {
1379                 TypeBuilder tb = module.DefineType (genTypeName ());
1380                 DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public);
1381
1382                 Type emittedType = tb.CreateType ();
1383
1384                 AssertEquals (1, tb.GetProperties ().Length);
1385                 AssertEquals (tb.GetProperties ().Length, emittedType.GetProperties ().Length);
1386         }
1387
1388         [Test]
1389         [ExpectedException (typeof(NotSupportedException))]
1390         [Ignore("mcs depends on this")]
1391         public void TestGetPropertiesFlagsIncomplete () {
1392                 TypeBuilder tb = module.DefineType (genTypeName ());
1393                 tb.GetProperties (BindingFlags.Public);
1394         }
1395
1396         [Test]
1397         public void TestGetPropertiesFlagsComplete () {
1398                 TypeBuilder tb = module.DefineType (genTypeName ());
1399                 DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public);
1400
1401                 Type emittedType = tb.CreateType ();
1402
1403                 AssertEquals (1, tb.GetProperties (BindingFlags.Instance | BindingFlags.Public).Length);
1404                 AssertEquals (tb.GetProperties (BindingFlags.Instance | BindingFlags.Public).Length,
1405                         emittedType.GetProperties (BindingFlags.Instance | BindingFlags.Public).Length);
1406                 AssertEquals (0, tb.GetProperties (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1407                 AssertEquals (tb.GetProperties (BindingFlags.Instance | BindingFlags.NonPublic).Length,
1408                         emittedType.GetProperties (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1409         }
1410
1411         [Test]
1412         [ExpectedException (typeof(NotSupportedException))]
1413         public void TestGetPropertyIncomplete () {
1414                 TypeBuilder tb = module.DefineType (genTypeName ());
1415                 tb.GetProperty ("test");
1416         }
1417
1418         [Test]
1419         public void TestGetPropertyComplete () {
1420                 TypeBuilder tb = module.DefineType (genTypeName ());
1421                 DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public);
1422
1423                 Type emittedType = tb.CreateType ();
1424
1425                 AssertNotNull (emittedType.GetProperty ("CustomerName"));
1426                 AssertNull (emittedType.GetProperty ("OtherCustomerName"));
1427
1428                 try {
1429                         tb.GetProperty ("CustomerName");
1430                         Fail ();
1431                 } catch (NotSupportedException) {}
1432         }
1433
1434         [Test]
1435         [ExpectedException (typeof(NotSupportedException))]
1436         public void TestGetPropertyFlagsIncomplete () {
1437                 TypeBuilder tb = module.DefineType (genTypeName ());
1438                 tb.GetProperty ("test", BindingFlags.Public);
1439         }
1440
1441         [Test]
1442         public void TestGetPropertyFlagsComplete () {
1443                 TypeBuilder tb = module.DefineType (genTypeName ());
1444                 DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public);
1445
1446                 Type emittedType = tb.CreateType ();
1447
1448                 AssertNotNull (emittedType.GetProperty ("CustomerName", BindingFlags.Instance | 
1449                         BindingFlags.Public));
1450                 AssertNull (emittedType.GetProperty ("CustomerName", BindingFlags.Instance |
1451                         BindingFlags.NonPublic));
1452
1453                 try {
1454                         tb.GetProperty ("CustomerName", BindingFlags.Instance | BindingFlags.Public);
1455                         Fail ();
1456                 }
1457                 catch (NotSupportedException) { }
1458         }
1459
1460         [Test]
1461         [ExpectedException (typeof(NotSupportedException))]
1462         [Ignore("mcs depends on this")]
1463         public void TestGetMethodsIncomplete () {
1464                 TypeBuilder tb = module.DefineType (genTypeName ());
1465                 tb.GetMethods ();
1466         }
1467
1468         [Test]
1469         [Category("NotWorking")]
1470         public void TestGetMethodsComplete () {
1471                 TypeBuilder tb = module.DefineType (genTypeName ());
1472                 MethodBuilder helloMethod = tb.DefineMethod ("HelloMethod", 
1473                         MethodAttributes.Public, typeof(string), new Type[0]);
1474                 ILGenerator helloMethodIL = helloMethod.GetILGenerator ();
1475                 helloMethodIL.Emit (OpCodes.Ldstr, "Hi! ");
1476                 helloMethodIL.Emit (OpCodes.Ldarg_1);
1477                 MethodInfo infoMethod = typeof(string).GetMethod ("Concat", 
1478                         new Type[] { typeof(string), typeof(string) });
1479                 helloMethodIL.Emit (OpCodes.Call, infoMethod);
1480                 helloMethodIL.Emit (OpCodes.Ret);
1481
1482                 Type emittedType = tb.CreateType ();
1483
1484                 AssertEquals (typeof(object).GetMethods (BindingFlags.Public | BindingFlags.Instance).Length + 1, 
1485                         tb.GetMethods ().Length);
1486                 AssertEquals (tb.GetMethods ().Length, emittedType.GetMethods ().Length);
1487         }
1488
1489         [Test]
1490         [ExpectedException (typeof(NotSupportedException))]
1491         [Ignore("mcs depends on this")]
1492         public void TestGetMethodsFlagsIncomplete () {
1493                 TypeBuilder tb = module.DefineType (genTypeName ());
1494                 tb.GetMethods (BindingFlags.Public);
1495         }
1496
1497         [Test]
1498         public void TestGetMethodsFlagsComplete () {
1499                 TypeBuilder tb = module.DefineType (genTypeName ());
1500                 MethodBuilder helloMethod = tb.DefineMethod ("HelloMethod",
1501                         MethodAttributes.Public, typeof(string), new Type[0]);
1502                 ILGenerator helloMethodIL = helloMethod.GetILGenerator ();
1503                 helloMethodIL.Emit (OpCodes.Ldstr, "Hi! ");
1504                 helloMethodIL.Emit (OpCodes.Ldarg_1);
1505                 MethodInfo infoMethod = typeof(string).GetMethod ("Concat", 
1506                         new Type[] { typeof(string), typeof(string) });
1507                 helloMethodIL.Emit (OpCodes.Call, infoMethod);
1508                 helloMethodIL.Emit (OpCodes.Ret);
1509
1510                 Type emittedType = tb.CreateType ();
1511
1512                 AssertEquals (1, tb.GetMethods (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Length);
1513                 AssertEquals (tb.GetMethods (BindingFlags.Instance | BindingFlags.Public).Length,
1514                         emittedType.GetMethods (BindingFlags.Instance | BindingFlags.Public).Length);
1515                 AssertEquals (0, tb.GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Length);
1516                 AssertEquals (tb.GetMethods (BindingFlags.Instance | BindingFlags.NonPublic).Length,
1517                         emittedType.GetMethods (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1518         }
1519
1520         [Test]
1521         [ExpectedException (typeof(NotSupportedException))]
1522         public void TestGetMemberIncomplete () {
1523                 TypeBuilder tb = module.DefineType (genTypeName ());
1524                 tb.GetMember ("FOO", MemberTypes.All, BindingFlags.Public);
1525         }
1526
1527         [Test]
1528         public void TestGetMemberComplete () {
1529                 TypeBuilder tb = module.DefineType (genTypeName ());
1530                 tb.DefineField ("FOO", typeof(int), FieldAttributes.Private);
1531
1532                 Type emittedType = tb.CreateType ();
1533
1534                 AssertEquals (1, tb.GetMember ("FOO", MemberTypes.Field, BindingFlags.Instance | BindingFlags.NonPublic).Length);
1535                 AssertEquals (0, tb.GetMember ("FOO", MemberTypes.Field, BindingFlags.Instance | BindingFlags.Public).Length);
1536         }
1537
1538         [Test]
1539         [ExpectedException (typeof(NotSupportedException))]
1540         public void TestGetMembersIncomplete () {
1541                 TypeBuilder tb = module.DefineType (genTypeName ());
1542                 tb.GetMembers ();
1543         }
1544
1545         [Test]
1546         public void TestGetMembersComplete () {
1547                 TypeBuilder tb = module.DefineType (genTypeName ());
1548                 Type emittedType = tb.CreateType ();
1549
1550                 AssertEquals (tb.GetMembers ().Length, emittedType.GetMembers ().Length);
1551         }
1552
1553         [Test]
1554         [ExpectedException (typeof(NotSupportedException))]
1555         public void TestGetMembersFlagsIncomplete () {
1556                 TypeBuilder tb = module.DefineType (genTypeName ());
1557                 tb.GetMembers (BindingFlags.Public);
1558         }
1559
1560         [Test]
1561         public void TestGetMembersFlagsComplete () {
1562                 TypeBuilder tb = module.DefineType (genTypeName ());
1563                 tb.DefineField ("FOO", typeof(int), FieldAttributes.Public);
1564
1565                 Type emittedType = tb.CreateType ();
1566
1567                 Assert (tb.GetMembers (BindingFlags.Instance | BindingFlags.Public).Length != 0);
1568                 AssertEquals (tb.GetMembers (BindingFlags.Instance | BindingFlags.Public).Length,
1569                         emittedType.GetMembers (BindingFlags.Instance | BindingFlags.Public).Length);
1570                 AssertEquals (tb.GetMembers (BindingFlags.Instance | BindingFlags.NonPublic).Length,
1571                         emittedType.GetMembers (BindingFlags.Instance | BindingFlags.NonPublic).Length);
1572         }
1573
1574         [Test]
1575         [ExpectedException (typeof(NotSupportedException))]
1576         public void TestGetInterfaceIncomplete () {
1577                 TypeBuilder tb = module.DefineType (genTypeName ());
1578                 tb.GetInterface ("FOO", true);
1579         }
1580
1581         [Test]
1582         public void TestGetInterfaces () {
1583                 TypeBuilder tb = module.DefineType (genTypeName ());
1584                 Type[] interfaces = tb.GetInterfaces ();
1585                 AssertEquals (0, interfaces.Length);
1586
1587                 TypeBuilder tbInterface = module.DefineType (genTypeName (), TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract);
1588                 Type emittedInterface = tbInterface.CreateType ();
1589
1590                 tb = module.DefineType (genTypeName (), TypeAttributes.Public, typeof(object), new Type[] { emittedInterface });
1591                 interfaces = tb.GetInterfaces ();
1592                 AssertEquals (1, interfaces.Length);
1593         }
1594
1595         [Test]
1596         [ExpectedException (typeof (InvalidOperationException))]
1597         public void TestAddDeclarativeSecurityAlreadyCreated () {
1598                 TypeBuilder tb = module.DefineType (genTypeName ());
1599                 tb.CreateType ();
1600
1601                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
1602                 tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
1603         }
1604
1605         [Test]
1606         [ExpectedException (typeof (ArgumentNullException))]
1607         public void TestAddDeclarativeSecurityNullPermissionSet () {
1608                 TypeBuilder tb = module.DefineType (genTypeName ());
1609
1610                 tb.AddDeclarativeSecurity (SecurityAction.Demand, null);
1611         }
1612
1613         [Test]
1614         public void TestAddDeclarativeSecurityInvalidAction () {
1615                 TypeBuilder tb = module.DefineType (genTypeName ());
1616
1617                 SecurityAction[] actions = new SecurityAction [] { 
1618                         SecurityAction.RequestMinimum,
1619                         SecurityAction.RequestOptional,
1620                         SecurityAction.RequestRefuse };
1621                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
1622
1623                 foreach (SecurityAction action in actions) {
1624                         try {
1625                                 tb.AddDeclarativeSecurity (action, set);
1626                                 Fail ();
1627                         }
1628                         catch (ArgumentException) {
1629                         }
1630                 }
1631         }
1632
1633         [Test]
1634         [ExpectedException (typeof (InvalidOperationException))]
1635         public void TestAddDeclarativeSecurityDuplicateAction () {
1636                 TypeBuilder tb = module.DefineType (genTypeName ());
1637
1638                 PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
1639                 tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
1640                 tb.AddDeclarativeSecurity (SecurityAction.Demand, set);
1641         }
1642
1643         [Test]
1644         public void TestEnums () {
1645                 TypeAttributes typeAttrs = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed;            
1646                 TypeBuilder enumToCreate = module.DefineType(genTypeName (), typeAttrs, 
1647                                                                                                          typeof(Enum));
1648                 enumToCreate.SetCustomAttribute (new CustomAttributeBuilder (typeof (FlagsAttribute).GetConstructors ()[0], new Type [0]));
1649                 // add value__ field, see DefineEnum method of ModuleBuilder
1650                 enumToCreate.DefineField("value__", typeof(Int32), 
1651                         FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
1652
1653                 // add enum entries
1654                 FieldBuilder fb = enumToCreate.DefineField("A", enumToCreate, 
1655                         FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
1656                 fb.SetConstant((Int32) 0);
1657
1658                 fb = enumToCreate.DefineField("B", enumToCreate, 
1659                         FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
1660                 fb.SetConstant((Int32) 1);
1661
1662                 fb = enumToCreate.DefineField("C", enumToCreate, 
1663                         FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
1664                 fb.SetConstant((Int32) 2);
1665
1666                 Type enumType = enumToCreate.CreateType();
1667
1668                 object enumVal = Enum.ToObject(enumType, (Int32) 3);
1669
1670                 AssertEquals ("B, C", enumVal.ToString ());
1671                 AssertEquals (3, (Int32)enumVal);
1672         }
1673
1674         [Test]
1675         public void DefineEnum () {
1676                 TypeBuilder typeBuilder = module.DefineType (genTypeName (),
1677                                                                                                          TypeAttributes.Public);
1678                 EnumBuilder enumBuilder = module.DefineEnum (genTypeName (),
1679                                                                                                          TypeAttributes.Public, typeof(int));
1680                 typeBuilder.DefineField ("myField", enumBuilder, FieldAttributes.Private);
1681                 enumBuilder.CreateType();
1682                 typeBuilder.CreateType();
1683         }
1684
1685         [Test]
1686         [ExpectedException(typeof(TypeLoadException))]
1687         [Category("NotWorking")]
1688         public void DefineEnumThrowIfTypeBuilderCalledBeforeEnumBuilder () {
1689                 TypeBuilder typeBuilder = module.DefineType (genTypeName (),
1690                                                                                                          TypeAttributes.Public);
1691                 EnumBuilder enumBuilder = module.DefineEnum (genTypeName (),
1692                                                                                                          TypeAttributes.Public, typeof(int));
1693                 typeBuilder.DefineField ("myField", enumBuilder, FieldAttributes.Private);
1694                 typeBuilder.CreateType();
1695                 enumBuilder.CreateType();
1696         }
1697
1698         private void DefineStringProperty (TypeBuilder tb, string propertyName, string fieldName, MethodAttributes methodAttribs) {
1699                 // define the field holding the property value
1700                 FieldBuilder fieldBuilder = tb.DefineField (fieldName,
1701                         typeof(string), FieldAttributes.Private);
1702
1703                 PropertyBuilder propertyBuilder = tb.DefineProperty (
1704                         propertyName, PropertyAttributes.HasDefault, typeof(string),
1705                         new Type[] { typeof(string) });
1706
1707                 // First, we'll define the behavior of the "get" property for CustomerName as a method.
1708                 MethodBuilder getMethodBuilder = tb.DefineMethod ("Get" + propertyName,
1709                                                                 methodAttribs,
1710                                                                 typeof(string),
1711                                                                 new Type[] { });
1712
1713                 ILGenerator getIL = getMethodBuilder.GetILGenerator ();
1714
1715                 getIL.Emit (OpCodes.Ldarg_0);
1716                 getIL.Emit (OpCodes.Ldfld, fieldBuilder);
1717                 getIL.Emit (OpCodes.Ret);
1718
1719                 // Now, we'll define the behavior of the "set" property for CustomerName.
1720                 MethodBuilder setMethodBuilder = tb.DefineMethod ("Set" + propertyName,
1721                                                                 methodAttribs,
1722                                                                 null,
1723                                                                 new Type[] { typeof(string) });
1724
1725                 ILGenerator setIL = setMethodBuilder.GetILGenerator ();
1726
1727                 setIL.Emit (OpCodes.Ldarg_0);
1728                 setIL.Emit (OpCodes.Ldarg_1);
1729                 setIL.Emit (OpCodes.Stfld, fieldBuilder);
1730                 setIL.Emit (OpCodes.Ret);
1731
1732                 // Last, we must map the two methods created above to our PropertyBuilder to 
1733                 // their corresponding behaviors, "get" and "set" respectively. 
1734                 propertyBuilder.SetGetMethod (getMethodBuilder);
1735                 propertyBuilder.SetSetMethod (setMethodBuilder);
1736         }
1737
1738         static int handler_called = 0;
1739
1740         [Test]
1741         public void TestTypeResolve () {
1742                 string typeName = genTypeName ();
1743
1744                 ResolveEventHandler handler = new ResolveEventHandler (TypeResolve);
1745         AppDomain.CurrentDomain.TypeResolve += handler;
1746                 handler_called = 0;
1747                 Type t = Type.GetType (typeName);
1748                 AssertEquals (typeName, t.Name);
1749                 AssertEquals (1, handler_called);
1750         AppDomain.CurrentDomain.TypeResolve -= handler;
1751         }
1752     
1753     Assembly TypeResolve (object sender, ResolveEventArgs args) {
1754                 TypeBuilder tb = module.DefineType (args.Name, TypeAttributes.Public);
1755                 tb.CreateType ();
1756                 handler_called ++;
1757                 return tb.Assembly;
1758         }
1759
1760         [Test]
1761         public void TestIsAssignableTo () {
1762                 Type icomparable = typeof (IComparable);
1763
1764                 TypeBuilder tb = module.DefineType (genTypeName (),
1765                                                                                         TypeAttributes.Public, null, new Type[] { icomparable, typeof (Bar) });
1766
1767                 Assert ("01", icomparable.IsAssignableFrom (tb));
1768                 Assert ("02", !tb.IsAssignableFrom (icomparable));
1769
1770                 Assert ("03", typeof (Bar).IsAssignableFrom (tb));
1771                 Assert ("04", !typeof (Baz).IsAssignableFrom (tb));
1772
1773                 Assert ("05", tb.IsAssignableFrom (tb));
1774
1775                 Assert ("06", !tb.IsAssignableFrom (typeof (IDisposable)));
1776                 tb.AddInterfaceImplementation (typeof (IDisposable));
1777         }
1778
1779         [Test]
1780         [Category("NotDotNet")]
1781         public void TestIsAssignableTo_NotDotNet () {
1782                 Type icomparable = typeof (IComparable);
1783
1784                 TypeBuilder tb = module.DefineType (genTypeName (),
1785                                                                                         TypeAttributes.Public, null, new Type[] { icomparable, typeof (Bar) });
1786
1787                 Assert ("01", typeof (Foo).IsAssignableFrom (tb));
1788
1789                 tb.AddInterfaceImplementation (typeof (IDisposable));
1790
1791                 Assert ("02", tb.IsAssignableFrom (typeof (IDisposable)));
1792
1793                 // bug #73469
1794                 // Assert ("07", typeof (Bar[]).IsAssignableFrom (module.GetType (tb.FullName + "[]")));
1795         }
1796 }
1797 }