2 // TypeBuilderTest.cs - NUnit Test Cases for the TypeBuilder class
\r
4 // Zoltan Varga (vargaz@freemail.hu)
\r
6 // (C) Ximian, Inc. http://www.ximian.com
\r
9 using System.Threading;
\r
10 using System.Reflection;
\r
11 using System.Reflection.Emit;
\r
13 using NUnit.Framework;
\r
15 namespace MonoTests.System.Reflection.Emit
\r
18 public class TypeBuilderTest : TestCase
\r
20 private AssemblyBuilder assembly;
\r
22 private ModuleBuilder module;
\r
24 static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
\r
26 protected override void SetUp () {
\r
27 AssemblyName assemblyName = new AssemblyName();
\r
28 assemblyName.Name = ASSEMBLY_NAME;
\r
31 Thread.GetDomain().DefineDynamicAssembly(
\r
32 assemblyName, AssemblyBuilderAccess.Run);
\r
34 module = assembly.DefineDynamicModule("module1");
\r
37 static int typeIndexer = 0;
\r
39 // Return a unique type name
\r
40 private string genTypeName () {
\r
41 return "t" + (typeIndexer ++);
\r
44 public void TestAssembly () {
\r
45 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
\r
46 AssertEquals ("Assembly works",
\r
47 tb.Assembly, assembly);
\r
50 public void TestAssemblyQualifiedName () {
\r
51 TypeBuilder tb = module.DefineType ("A.B.C.D", TypeAttributes.Public);
\r
53 AssertEquals ("AssemblyQualifiedName works",
\r
54 tb.AssemblyQualifiedName, "A.B.C.D, " + assembly.GetName ().FullName);
\r
57 public void TestAttributes () {
\r
58 TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.BeforeFieldInit;
\r
59 TypeBuilder tb = module.DefineType (genTypeName (), attrs);
\r
61 AssertEquals ("Attributes works",
\r
62 tb.Attributes, attrs);
\r
65 public void TestBaseType () {
\r
66 TypeAttributes attrs = TypeAttributes.Public;
\r
67 TypeBuilder tb = module.DefineType (genTypeName (), attrs);
\r
68 AssertEquals ("BaseType defaults to Object",
\r
69 tb.BaseType, typeof (object));
\r
71 TypeBuilder tb2 = module.DefineType (genTypeName (), attrs, tb);
\r
72 AssertEquals ("BaseType works",
\r
75 /* This does not run under mono
\r
76 TypeBuilder tb3 = module.DefineType (genTypeName (),
\r
77 TypeAttributes.Interface |
\r
78 TypeAttributes.Abstract);
\r
79 AssertEquals ("Interfaces default to no base type",
\r
80 null, tb3.BaseType);
\r
84 public void TestDeclaringType () {
\r
85 TypeAttributes attrs = 0;
\r
86 TypeBuilder tb = module.DefineType (genTypeName (), attrs);
\r
88 AssertEquals ("Has no declaring type",
\r
89 null, tb.DeclaringType);
\r
91 attrs = TypeAttributes.NestedPublic;
\r
92 TypeBuilder tb2 = tb.DefineNestedType (genTypeName (), attrs);
\r
93 TypeBuilder tb3 = tb2.DefineNestedType (genTypeName (), attrs);
\r
94 AssertEquals ("DeclaringType works",
\r
95 tb, tb3.DeclaringType.DeclaringType);
\r
98 public void TestFullName () {
\r
99 string name = genTypeName ();
\r
100 TypeAttributes attrs = 0;
\r
101 TypeBuilder tb = module.DefineType (name, attrs);
\r
102 AssertEquals ("FullName works",
\r
103 name, tb.FullName);
\r
105 string name2 = genTypeName ();
\r
106 attrs = TypeAttributes.NestedPublic;
\r
107 TypeBuilder tb2 = tb.DefineNestedType (name2, attrs);
\r
109 string name3 = genTypeName ();
\r
110 attrs = TypeAttributes.NestedPublic;
\r
111 TypeBuilder tb3 = tb2.DefineNestedType (name3, attrs);
\r
113 AssertEquals ("FullName works on nested types",
\r
114 name + "+" + name2 + "+" + name3, tb3.FullName);
\r
117 public void TestGUID () {
\r
118 TypeBuilder tb = module.DefineType (genTypeName ());
\r
123 catch (NotSupportedException) {
\r
127 public void TestHasElementType () {
\r
128 // According to the MSDN docs, this member works, but in reality, it
\r
129 // returns a NotSupportedException
\r
130 TypeBuilder tb = module.DefineType (genTypeName ());
\r
132 bool b = tb.HasElementType;
\r
135 catch (NotSupportedException) {
\r
139 public void TestIsAbstract () {
\r
140 TypeBuilder tb = module.DefineType (genTypeName ());
\r
142 false, tb.IsAbstract);
\r
144 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Abstract);
\r
146 true, tb2.IsAbstract);
\r
149 public void TestIsAnsiClass () {
\r
150 TypeBuilder tb = module.DefineType (genTypeName ());
\r
152 true, tb.IsAnsiClass);
\r
154 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass);
\r
156 false, tb2.IsAnsiClass);
\r
159 public void TestIsArray () {
\r
160 // How can a TypeBuilder be an array ?
\r
161 string name = genTypeName ();
\r
162 TypeBuilder tb = module.DefineType (name);
\r
163 AssertEquals ("IsArray works",
\r
164 false, tb.IsArray);
\r
167 public void TestIsAutoClass () {
\r
168 TypeBuilder tb = module.DefineType (genTypeName ());
\r
170 false, tb.IsAutoClass);
\r
172 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.AutoClass);
\r
174 true, tb2.IsAutoClass);
\r
177 public void TestIsAutoLayout () {
\r
178 TypeBuilder tb = module.DefineType (genTypeName ());
\r
179 AssertEquals ("AutoLayout defaults to true",
\r
180 true, tb.IsAutoLayout);
\r
182 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout);
\r
184 false, tb2.IsAutoLayout);
\r
187 public void TestIsByRef () {
\r
188 // How can a TypeBuilder be ByRef ?
\r
189 TypeBuilder tb = module.DefineType (genTypeName ());
\r
190 AssertEquals ("IsByRef works",
\r
191 false, tb.IsByRef);
\r
194 public void TestIsClass () {
\r
195 TypeBuilder tb = module.DefineType (genTypeName ());
\r
196 AssertEquals ("Most types are classes",
\r
199 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
\r
200 AssertEquals ("Interfaces are not classes",
\r
201 false, tb2.IsClass);
\r
203 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));
\r
204 AssertEquals ("value types are not classes",
\r
205 false, tb3.IsClass);
\r
207 TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum));
\r
208 AssertEquals ("enums are not classes",
\r
209 false, tb4.IsClass);
\r
212 public void TestIsCOMObject () {
\r
213 TypeBuilder tb = module.DefineType (genTypeName ());
\r
214 AssertEquals ("Probably not",
\r
215 false, tb.IsCOMObject);
\r
218 public void TestIsContextful () {
\r
219 TypeBuilder tb = module.DefineType (genTypeName ());
\r
221 false, tb.IsContextful);
\r
223 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject));
\r
225 true, tb2.IsContextful);
\r
228 public void TestIsEnum () {
\r
229 TypeBuilder tb = module.DefineType (genTypeName ());
\r
233 // This returns true under both mono and MS .NET ???
\r
234 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ValueType));
\r
235 AssertEquals ("value types are not necessary enums",
\r
236 false, tb2.IsEnum);
\r
238 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (Enum));
\r
239 AssertEquals ("enums are enums",
\r
243 public void TestIsExplicitLayout () {
\r
244 TypeBuilder tb = module.DefineType (genTypeName ());
\r
245 AssertEquals ("ExplicitLayout defaults to false",
\r
246 false, tb.IsExplicitLayout);
\r
248 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout);
\r
250 true, tb2.IsExplicitLayout);
\r
253 public void TestIsImport () {
\r
254 // How can this be true ?
\r
255 TypeBuilder tb = module.DefineType (genTypeName ());
\r
257 false, tb.IsImport);
\r
260 public void TestIsInterface () {
\r
261 TypeBuilder tb = module.DefineType (genTypeName ());
\r
262 AssertEquals ("Most types are not interfaces",
\r
263 false, tb.IsInterface);
\r
265 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
\r
266 AssertEquals ("Interfaces are interfaces",
\r
267 true, tb2.IsInterface);
\r
269 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));
\r
270 AssertEquals ("value types are not interfaces",
\r
271 false, tb3.IsInterface);
\r
274 public void TestIsLayoutSequential () {
\r
275 TypeBuilder tb = module.DefineType (genTypeName ());
\r
276 AssertEquals ("SequentialLayout defaults to false",
\r
277 false, tb.IsLayoutSequential);
\r
279 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SequentialLayout);
\r
281 true, tb2.IsLayoutSequential);
\r
284 public void TestIsMarshalByRef () {
\r
285 TypeBuilder tb = module.DefineType (genTypeName ());
\r
287 false, tb.IsMarshalByRef);
\r
289 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (MarshalByRefObject));
\r
291 true, tb2.IsMarshalByRef);
\r
293 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject));
\r
295 true, tb3.IsMarshalByRef);
\r
298 // TODO: Visibility properties
\r
300 public void TestIsPointer () {
\r
301 // How can this be true?
\r
302 TypeBuilder tb = module.DefineType (genTypeName ());
\r
304 false, tb.IsPointer);
\r
307 public void TestIsPrimitive () {
\r
308 TypeBuilder tb = module.DefineType ("int");
\r
310 false, tb.IsPrimitive);
\r
313 public void IsSealed () {
\r
314 TypeBuilder tb = module.DefineType (genTypeName ());
\r
315 AssertEquals ("Sealed defaults to false",
\r
316 false, tb.IsSealed);
\r
318 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Sealed);
\r
319 AssertEquals ("IsSealed works",
\r
320 true, tb2.IsSealed);
\r
323 public void IsSerializable () {
\r
324 TypeBuilder tb = module.DefineType (genTypeName ());
\r
326 false, tb.IsSerializable);
\r
328 tb.SetCustomAttribute (new CustomAttributeBuilder (typeof (SerializableAttribute).GetConstructors (BindingFlags.Public)[0], null));
\r
330 true, tb.IsSerializable);
\r
333 public void TestIsSpecialName () {
\r
334 TypeBuilder tb = module.DefineType (genTypeName ());
\r
335 AssertEquals ("SpecialName defaults to false",
\r
336 false, tb.IsSpecialName);
\r
338 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SpecialName);
\r
339 AssertEquals ("IsSpecialName works",
\r
340 true, tb2.IsSpecialName);
\r
343 public void TestIsUnicodeClass () {
\r
344 TypeBuilder tb = module.DefineType (genTypeName ());
\r
346 false, tb.IsUnicodeClass);
\r
348 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass);
\r
350 true, tb2.IsUnicodeClass);
\r
353 public void TestIsValueType () {
\r
354 TypeBuilder tb = module.DefineType (genTypeName ());
\r
355 AssertEquals ("Most types are not value types",
\r
356 false, tb.IsValueType);
\r
358 TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
\r
359 AssertEquals ("Interfaces are not value types",
\r
360 false, tb2.IsValueType);
\r
362 TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType));
\r
363 AssertEquals ("value types are value types",
\r
364 true, tb3.IsValueType);
\r
366 TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum));
\r
367 AssertEquals ("enums are value types",
\r
368 true, tb4.IsValueType);
\r
371 public void TestMemberType () {
\r
372 TypeBuilder tb = module.DefineType (genTypeName ());
\r
373 AssertEquals ("A type is a type",
\r
374 MemberTypes.TypeInfo, tb.MemberType);
\r
377 public void TestModule () {
\r
378 TypeBuilder tb = module.DefineType (genTypeName ());
\r
379 AssertEquals ("Module works",
\r
380 module, tb.Module);
\r
383 public void TestName () {
\r
384 TypeBuilder tb = module.DefineType ("A");
\r
388 TypeBuilder tb2 = module.DefineType ("A.B.C.D.E");
\r
392 TypeBuilder tb3 = tb2.DefineNestedType ("A");
\r
396 /* Is .E a valid name ?
\r
397 TypeBuilder tb4 = module.DefineType (".E");
\r
403 public void TestNamespace () {
\r
404 TypeBuilder tb = module.DefineType ("A");
\r
408 TypeBuilder tb2 = module.DefineType ("A.B.C.D.E");
\r
410 "A.B.C.D", tb2.Namespace);
\r
412 TypeBuilder tb3 = tb2.DefineNestedType ("A");
\r
414 "", tb3.Namespace);
\r
416 /* Is .E a valid name ?
\r
417 TypeBuilder tb4 = module.DefineType (".E");
\r
423 public void TestPackingSize () {
\r
424 TypeBuilder tb = module.DefineType (genTypeName ());
\r
426 PackingSize.Unspecified, tb.PackingSize);
\r
428 TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (object),
\r
429 PackingSize.Size16, 16);
\r
431 PackingSize.Size16, tb2.PackingSize);
\r
434 public void TestReflectedType () {
\r
435 // It is the same as DeclaringType, but why?
\r
436 TypeBuilder tb = module.DefineType (genTypeName ());
\r
438 null, tb.ReflectedType);
\r
440 TypeBuilder tb2 = tb.DefineNestedType (genTypeName ());
\r
442 tb, tb2.ReflectedType);
\r
445 public void TestSize () {
\r
447 TypeBuilder tb = module.DefineType (genTypeName ());
\r
456 TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (object),
\r
457 PackingSize.Size16, 32);
\r
463 public void TestTypeHandle () {
\r
464 TypeBuilder tb = module.DefineType (genTypeName ());
\r
466 RuntimeTypeHandle handle = tb.TypeHandle;
\r
469 catch (NotSupportedException) {
\r
473 public void TestTypeInitializer () {
\r
474 // According to the MSDN docs, this works, but it doesn't
\r
476 TypeBuilder tb = module.DefineType (genTypeName ());
\r
478 ConstructorInfo cb = tb.TypeInitializer;
\r
481 catch (NotSupportedException) {
\r
486 public void TestTypeToken () {
\r
487 TypeBuilder tb = module.DefineType (genTypeName ());
\r
488 TypeToken token = tb.TypeToken;
\r
491 public void TestUnderlyingSystemType () {
\r
493 // For non-enum types, UnderlyingSystemType should return itself.
\r
494 // But if I modify the code to do this, I get an exception in mcs.
\r
495 // Reason: the enums created during corlib compilation do not seem
\r
496 // to be an enum according to IsEnum.
\r
500 TypeBuilder tb = module.DefineType (genTypeName ());
\r
501 AssertEquals ("For non-enums this equals itself",
\r
502 tb, tb.UnderlyingSystemType);
\r
505 TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract);
\r
507 tb, tb.UnderlyingSystemType);
\r
510 TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (ValueType));
\r
512 tb, tb.UnderlyingSystemType);
\r
516 TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (Enum));
\r
518 Type t = tb.UnderlyingSystemType;
\r
521 catch (InvalidOperationException) {
\r
524 tb.DefineField ("val", typeof (int), 0);
\r
526 typeof (int), tb.UnderlyingSystemType);
\r