// // TypeBuilderTest.cs - NUnit Test Cases for the TypeBuilder class // // Zoltan Varga (vargaz@freemail.hu) // // (C) Ximian, Inc. http://www.ximian.com // // TODO: // - implement a mechnanism for easier testing of null argument exceptions // - with overloaded methods like DefineNestedType (), check the defaults // on the shorter versions. // - ToString on enums with the flags attribute set should print all // values which match, e.g. 0 == AutoLayou,AnsiClass,NotPublic // using System; using System.Threading; using System.Reflection; using System.Reflection.Emit; using System.IO; using System.Security; using System.Security.Permissions; using System.Runtime.InteropServices; using NUnit.Framework; namespace MonoTests.System.Reflection.Emit { [TestFixture] public class TypeBuilderTest : Assertion { private interface AnInterface { } interface Foo { } interface Bar : Foo { } interface Baz : Bar { } private AssemblyBuilder assembly; private ModuleBuilder module; static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest"; [SetUp] protected void SetUp () { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = ASSEMBLY_NAME; assembly = Thread.GetDomain().DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.RunAndSave, Path.GetTempPath ()); module = assembly.DefineDynamicModule("module1"); } static int typeIndexer = 0; // Return a unique type name private string genTypeName () { return "t" + (typeIndexer ++); } private string nullName () { return String.Format ("{0}", (char)0); } [Test] public void TestAssembly () { TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public); AssertEquals ("Assembly works", tb.Assembly, assembly); } [Test] public void TestAssemblyQualifiedName () { TypeBuilder tb = module.DefineType ("A.B.C.D", TypeAttributes.Public); AssertEquals ("AssemblyQualifiedName works", tb.AssemblyQualifiedName, "A.B.C.D, " + assembly.GetName ().FullName); } [Test] public void TestAttributes () { TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.BeforeFieldInit; TypeBuilder tb = module.DefineType (genTypeName (), attrs); AssertEquals ("Attributes works", tb.Attributes, attrs); } [Test] public void TestBaseTypeClass () { TypeAttributes attrs = TypeAttributes.Public; TypeBuilder tb = module.DefineType (genTypeName (), attrs); AssertEquals ("BaseType defaults to Object", tb.BaseType, typeof (object)); TypeBuilder tb2 = module.DefineType (genTypeName (), attrs, tb); AssertEquals ("BaseType works", tb2.BaseType, tb); } [Test] public void TestBaseTypeInterface () // See bug: 71301 { TypeBuilder tb3 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); AssertEquals ("Interfaces should default to no base type", null, tb3.BaseType); } [Test] public void TestDeclaringType () { TypeAttributes attrs = 0; TypeBuilder tb = module.DefineType (genTypeName (), attrs); AssertEquals ("Has no declaring type", null, tb.DeclaringType); attrs = TypeAttributes.NestedPublic; TypeBuilder tb2 = tb.DefineNestedType (genTypeName (), attrs); TypeBuilder tb3 = tb2.DefineNestedType (genTypeName (), attrs); AssertEquals ("DeclaringType works", tb, tb3.DeclaringType.DeclaringType); } [Test] public void TestFullName () { string name = genTypeName (); TypeAttributes attrs = 0; TypeBuilder tb = module.DefineType (name, attrs); AssertEquals ("FullName works", name, tb.FullName); string name2 = genTypeName (); attrs = TypeAttributes.NestedPublic; TypeBuilder tb2 = tb.DefineNestedType (name2, attrs); string name3 = genTypeName (); attrs = TypeAttributes.NestedPublic; TypeBuilder tb3 = tb2.DefineNestedType (name3, attrs); AssertEquals ("FullName works on nested types", name + "+" + name2 + "+" + name3, tb3.FullName); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGUIDIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); Guid g = tb.GUID; } [Test] [Category("NotWorking")] // See bug: 71302 public void TestGUIDComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.CreateType (); Assert(tb.GUID != Guid.Empty); } [Test] [Category("NotWorking")] public void TestFixedGUIDComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); Guid guid = Guid.NewGuid (); ConstructorInfo guidCtor = typeof(GuidAttribute).GetConstructor( new Type[] {typeof(string)}); CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (guidCtor, new object[] { guid.ToString("D") }, new FieldInfo[0], new object[0]); tb.SetCustomAttribute (caBuilder); tb.CreateType (); AssertEquals (guid, tb.GUID); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestHasElementType () { // According to the MSDN docs, this member works, but in reality, it // returns a NotSupportedException TypeBuilder tb = module.DefineType (genTypeName ()); bool b = tb.HasElementType; } [Test] public void TestIsAbstract () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("", false, tb.IsAbstract); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Abstract); AssertEquals ("", true, tb2.IsAbstract); } [Test] public void TestIsAnsiClass () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("", true, tb.IsAnsiClass); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass); AssertEquals ("", false, tb2.IsAnsiClass); } [Test] public void TestIsArray () { // How can a TypeBuilder be an array ? string name = genTypeName (); TypeBuilder tb = module.DefineType (name); AssertEquals ("IsArray works", false, tb.IsArray); } [Test] public void TestIsAutoClass () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("", false, tb.IsAutoClass); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.AutoClass); AssertEquals ("", true, tb2.IsAutoClass); } [Test] public void TestIsAutoLayout () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("AutoLayout defaults to true", true, tb.IsAutoLayout); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout); AssertEquals ("", false, tb2.IsAutoLayout); } [Test] public void TestIsByRef () { // How can a TypeBuilder be ByRef ? TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("IsByRef works", false, tb.IsByRef); } [Test] public void TestIsClass () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("Most types are classes", true, tb.IsClass); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); AssertEquals ("Interfaces are not classes", false, tb2.IsClass); TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType)); AssertEquals ("value types are not classes", false, tb3.IsClass); TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum)); AssertEquals ("enums are not classes", false, tb4.IsClass); } [Test] [Category("NotWorking")] // See bug: 71304 public void TestIsCOMObject () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("Probably not", false, tb.IsCOMObject); tb = module.DefineType (genTypeName (), TypeAttributes.Import); AssertEquals ("type with Import attribute is COM object", true, tb.IsCOMObject); } [Test] public void TestIsContextful () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (false, tb.IsContextful); TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject)); AssertEquals (true, tb2.IsContextful); } [Test] public void TestIsEnum () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (false, tb.IsEnum); // This returns true under both mono and MS .NET ??? TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (ValueType)); AssertEquals ("value types are not necessary enums", false, tb2.IsEnum); TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (Enum)); AssertEquals ("enums are enums", true, tb3.IsEnum); } [Test] public void TestIsExplicitLayout () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("ExplicitLayout defaults to false", false, tb.IsExplicitLayout); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.ExplicitLayout); AssertEquals (true, tb2.IsExplicitLayout); } [Test] public void TestIsImport () { // How can this be true ? TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (false, tb.IsImport); } [Test] public void TestIsInterface () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("Most types are not interfaces", false, tb.IsInterface); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); AssertEquals ("Interfaces are interfaces", true, tb2.IsInterface); TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType)); AssertEquals ("value types are not interfaces", false, tb3.IsInterface); } [Test] public void TestIsLayoutSequential () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("SequentialLayout defaults to false", false, tb.IsLayoutSequential); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SequentialLayout); AssertEquals (true, tb2.IsLayoutSequential); } [Test] public void TestIsMarshalByRef () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (false, tb.IsMarshalByRef); TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (MarshalByRefObject)); AssertEquals (true, tb2.IsMarshalByRef); TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ContextBoundObject)); AssertEquals (true, tb3.IsMarshalByRef); } // TODO: Visibility properties [Test] public void TestIsPointer () { // How can this be true? TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (false, tb.IsPointer); } [Test] public void TestIsPrimitive () { TypeBuilder tb = module.DefineType ("int"); AssertEquals (false, tb.IsPrimitive); } [Test] public void IsSealed () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("Sealed defaults to false", false, tb.IsSealed); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Sealed); AssertEquals ("IsSealed works", true, tb2.IsSealed); } static string CreateTempAssembly () { FileStream f = null; string path; Random rnd; int num = 0; rnd = new Random (); do { num = rnd.Next (); num++; path = Path.Combine (Path.GetTempPath(), "tmp" + num.ToString("x") + ".dll"); try { f = new FileStream (path, FileMode.CreateNew); } catch {} } while (f == null); f.Close(); return "tmp" + num.ToString("x") + ".dll"; } [Test] public void IsSerializable () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (false, tb.IsSerializable); ConstructorInfo[] ctors = typeof (SerializableAttribute).GetConstructors (BindingFlags.Instance | BindingFlags.Public); Assert ("SerializableAttribute should have more than 0 public instance ctors", ctors.Length > 0); tb.SetCustomAttribute (new CustomAttributeBuilder (ctors[0], new object[0])); Type createdType = tb.CreateType (); string an = CreateTempAssembly (); assembly.Save (an); AssertEquals (true, createdType.IsSerializable); File.Delete (Path.Combine (Path.GetTempPath (), an)); } [Test] public void TestIsSpecialName () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("SpecialName defaults to false", false, tb.IsSpecialName); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.SpecialName); AssertEquals ("IsSpecialName works", true, tb2.IsSpecialName); } [Test] public void TestIsUnicodeClass () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (false, tb.IsUnicodeClass); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.UnicodeClass); AssertEquals (true, tb2.IsUnicodeClass); } [Test] public void TestIsValueType () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("Most types are not value types", false, tb.IsValueType); TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); AssertEquals ("Interfaces are not value types", false, tb2.IsValueType); TypeBuilder tb3 = module.DefineType (genTypeName (), 0, typeof (ValueType)); AssertEquals ("value types are value types", true, tb3.IsValueType); TypeBuilder tb4 = module.DefineType (genTypeName (), 0, typeof (Enum)); AssertEquals ("enums are value types", true, tb4.IsValueType); } [Test] public void TestMemberType () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("A type is a type", MemberTypes.TypeInfo, tb.MemberType); } [Test] public void TestModule () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("Module works", module, tb.Module); } [Test] public void TestName () { TypeBuilder tb = module.DefineType ("A"); AssertEquals ("A", tb.Name); TypeBuilder tb2 = module.DefineType ("A.B.C.D.E"); AssertEquals ("E", tb2.Name); TypeBuilder tb3 = tb2.DefineNestedType ("A"); AssertEquals ("A", tb3.Name); /* Is .E a valid name ? TypeBuilder tb4 = module.DefineType (".E"); AssertEquals ("", "E", tb4.Name); */ } [Test] public void TestNamespace () { TypeBuilder tb = module.DefineType ("A"); AssertEquals ("", tb.Namespace); TypeBuilder tb2 = module.DefineType ("A.B.C.D.E"); AssertEquals ("A.B.C.D", tb2.Namespace); TypeBuilder tb3 = tb2.DefineNestedType ("A"); AssertEquals ("", tb3.Namespace); /* Is .E a valid name ? TypeBuilder tb4 = module.DefineType (".E"); AssertEquals ("", "E", tb4.Name); */ } [Test] public void TestPackingSize () { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (PackingSize.Unspecified, tb.PackingSize); TypeBuilder tb2 = module.DefineType (genTypeName (), 0, typeof (object), PackingSize.Size16, 16); AssertEquals (PackingSize.Size16, tb2.PackingSize); } [Test] public void TestReflectedType () { // It is the same as DeclaringType, but why? TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (null, tb.ReflectedType); TypeBuilder tb2 = tb.DefineNestedType (genTypeName ()); AssertEquals (tb, tb2.ReflectedType); } [Test] [ExpectedException (typeof(ArgumentNullException))] public void TestSetParentNull () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.SetParent (null); } [Test] public void TestSetParentIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.SetParent (typeof(Attribute)); AssertEquals (typeof(Attribute), tb.BaseType); } [Test] [ExpectedException (typeof(InvalidOperationException))] public void TestSetParentComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.CreateType (); tb.SetParent (typeof(Attribute)); } [Test] public void TestSize () { { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals (0, tb.Size); tb.CreateType (); AssertEquals (0, tb.Size); } { TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (object), PackingSize.Size16, 32); AssertEquals (32, tb.Size); } } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestTypeHandle () { TypeBuilder tb = module.DefineType (genTypeName ()); RuntimeTypeHandle handle = tb.TypeHandle; } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestTypeInitializerIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); ConstructorInfo cb = tb.TypeInitializer; } [Test] public void TestTypeInitializerComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.CreateType (); ConstructorInfo cb = tb.TypeInitializer; } [Test] public void TestTypeToken () { TypeBuilder tb = module.DefineType (genTypeName ()); TypeToken token = tb.TypeToken; } [Test] [Category("NotWorking")] public void TestUnderlyingSystemType () { { TypeBuilder tb = module.DefineType (genTypeName ()); AssertEquals ("For non-enums this equals itself", tb, tb.UnderlyingSystemType); } { TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); AssertEquals (tb, tb.UnderlyingSystemType); } { TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (ValueType)); AssertEquals (tb, tb.UnderlyingSystemType); } { TypeBuilder tb = module.DefineType (genTypeName (), 0, typeof (Enum)); try { Type t = tb.UnderlyingSystemType; Fail (); } catch (InvalidOperationException) { } tb.DefineField ("val", typeof (int), 0); AssertEquals (typeof (int), tb.UnderlyingSystemType); } } [Test] public void TestAddInterfaceImplementation () { TypeBuilder tb = module.DefineType (genTypeName ()); try { tb.AddInterfaceImplementation (null); Fail (); } catch (ArgumentNullException) { } tb.AddInterfaceImplementation (typeof (AnInterface)); tb.AddInterfaceImplementation (typeof (AnInterface)); Type t = tb.CreateType (); AssertEquals ("Should merge identical interfaces", tb.GetInterfaces ().Length, 1); // Can not be called on a created type try { tb.AddInterfaceImplementation (typeof (AnInterface)); Fail (); } catch (InvalidOperationException) { } } [Test] [Category("NotWorking")] public void TestCreateType () { // TODO: LOTS OF TEST SHOULD GO THERE TypeBuilder tb = module.DefineType (genTypeName ()); tb.CreateType (); // Can not be called on a created type try { tb.CreateType (); Fail (); } catch (InvalidOperationException) { } } [Test] public void TestDefineConstructor () { TypeBuilder tb = module.DefineType (genTypeName ()); ConstructorBuilder cb = tb.DefineConstructor (0, 0, null); cb.GetILGenerator ().Emit (OpCodes.Ret); tb.CreateType (); // Can not be called on a created type try { tb.DefineConstructor (0, 0, null); Fail (); } catch (InvalidOperationException) { } } [Test] public void TestDefineDefaultConstructor () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineDefaultConstructor (0); tb.CreateType (); // Can not be called on a created type, altough the MSDN docs does not mention this try { tb.DefineDefaultConstructor (0); Fail (); } catch (InvalidOperationException) { } } [Test] [ExpectedException (typeof(InvalidOperationException))] public void TestDefineDefaultConstructorParent () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(string) }); Type type = tb.CreateType (); // create TypeBuilder for type that derived from the // previously created type (which has no default ctor) tb = module.DefineType (genTypeName (), TypeAttributes.Class | TypeAttributes.Public, type); // you cannot create a type with a default ctor that // derives from a type without a default ctor tb.CreateType (); } [Test] public void TestDefineEvent () { TypeBuilder tb = module.DefineType (genTypeName ()); // Test invalid arguments try { tb.DefineEvent (null, 0, typeof (int)); Fail (); } catch (ArgumentNullException) { } try { tb.DefineEvent ("FOO", 0, null); Fail (); } catch (ArgumentNullException) { } try { tb.DefineEvent ("", 0, typeof (int)); Fail (); } catch (ArgumentException) { } tb.CreateType (); // Can not be called on a created type try { tb.DefineEvent ("BAR", 0, typeof (int)); Fail (); } catch (InvalidOperationException) { } } [Test] public void TestDefineField () { TypeBuilder tb = module.DefineType (genTypeName ()); // Check invalid arguments try { tb.DefineField (null, typeof (int), 0); Fail (); } catch (ArgumentNullException) { } try { tb.DefineField ("", typeof (int), 0); Fail (); } catch (ArgumentException) { } try { // Strangely, 'A' is accepted... string name = String.Format ("{0}", (char)0); tb.DefineField (name, typeof (int), 0); Fail ("Names with embedded nulls should be rejected"); } catch (ArgumentException) { } try { tb.DefineField ("A", typeof (void), 0); Fail (); } catch (ArgumentException) { } tb.CreateType (); // Can not be called on a created type try { tb.DefineField ("B", typeof (int), 0); Fail (); } catch (InvalidOperationException) { } } [Test] public void TestDefineInitializedData () { TypeBuilder tb = module.DefineType (genTypeName ()); // Check invalid arguments try { tb.DefineInitializedData (null, new byte[1], 0); Fail (); } catch (ArgumentNullException) { } try { tb.DefineInitializedData ("FOO", null, 0); Fail (); } catch (ArgumentNullException) { } try { tb.DefineInitializedData ("", new byte[1], 0); Fail (); } catch (ArgumentException) { } // The size of the data is less than or equal to zero ??? try { tb.DefineInitializedData ("BAR", new byte[0], 0); Fail (); } catch (ArgumentException) { } try { string name = String.Format ("{0}", (char)0); tb.DefineInitializedData (name, new byte[1], 0); Fail ("Names with embedded nulls should be rejected"); } catch (ArgumentException) { } tb.CreateType (); // Can not be called on a created type, altough the MSDN docs does not mention this try { tb.DefineInitializedData ("BAR2", new byte[1], 0); Fail (); } catch (InvalidOperationException) { } } [Test] public void DefineUninitializedDataInvalidArgs () { TypeBuilder tb = module.DefineType (genTypeName ()); try { tb.DefineUninitializedData (null, 1, 0); Fail (); } catch (ArgumentNullException) { } try { tb.DefineUninitializedData ("", 1, 0); Fail (); } catch (ArgumentException) { } // The size of the data is less than or equal to zero ??? try { tb.DefineUninitializedData ("BAR", 0, 0); Fail (); } catch (ArgumentException) { } try { string name = String.Format ("{0}", (char)0); tb.DefineUninitializedData (name, 1, 0); Fail ("Names with embedded nulls should be rejected"); } catch (ArgumentException) { } } [Test] [ExpectedException (typeof (InvalidOperationException))] public void DefineUninitializedDataAlreadyCreated () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.CreateType (); tb.DefineUninitializedData ("BAR2", 1, 0); } [Test] public void DefineUninitializedData () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineUninitializedData ("foo", 4, FieldAttributes.Public); Type t = tb.CreateType (); object o = Activator.CreateInstance (t); FieldInfo fi = t.GetField ("foo"); object fieldVal = fi.GetValue (o); IntPtr ptr = Marshal.AllocHGlobal (4); Marshal.StructureToPtr (fieldVal, ptr, true); Marshal.FreeHGlobal (ptr); } [Test] public void TestDefineMethod () { TypeBuilder tb = module.DefineType (genTypeName ()); // Check invalid arguments try { tb.DefineMethod (null, 0, null, null); Fail (); } catch (ArgumentNullException) { } try { tb.DefineMethod ("", 0, null, null); Fail (); } catch (ArgumentException) { } // Check non-virtual methods on an interface TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); try { tb2.DefineMethod ("FOO", MethodAttributes.Abstract, null, null); Fail (); } catch (ArgumentException) { } // Check static methods on an interface tb2.DefineMethod ("BAR", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes); tb.CreateType (); // Can not be called on a created type try { tb.DefineMethod ("bar", 0, null, null); Fail (); } catch (InvalidOperationException) { } } // TODO: DefineMethodOverride [Test] public void TestDefineNestedType () { TypeBuilder tb = module.DefineType (genTypeName ()); // Check invalid arguments try { tb.DefineNestedType (null); Fail ("Should reject null name"); } catch (ArgumentNullException) { } try { tb.DefineNestedType (""); Fail ("Should reject empty name"); } catch (ArgumentException) { } try { tb.DefineNestedType (nullName ()); Fail ("Should reject name with embedded 0s"); } catch (ArgumentException) { } // If I fix the code so this works then mcs breaks -> how can mcs // works under MS .NET in the first place ??? /* try { tb.DefineNestedType ("AA", TypeAttributes.Public, null, null); Fail ("Nested visibility must be specified."); } catch (ArgumentException) { } */ try { tb.DefineNestedType ("BB", TypeAttributes.NestedPublic, null, new Type[1]); Fail ("Should reject empty interface"); } catch (ArgumentException) { } // I think this should reject non-interfaces, but it does not tb.DefineNestedType ("BB", TypeAttributes.NestedPublic, null, new Type[1] { typeof (object) }); // Normal invocation tb.DefineNestedType ("Nest"); tb.CreateType (); // According to the MSDN docs, this cannnot be called after the type // is created, but it works. tb.DefineNestedType ("Nest2"); // According to the MSDN docs, a Sealed class can't contain nested // types, but this is not true TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Sealed); tb2.DefineNestedType ("AA"); // According to the MSDN docs, interfaces can only contain interfaces, // but this is not true TypeBuilder tb3 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); tb3.DefineNestedType ("AA"); // Check shorter versions { TypeBuilder nested = tb.DefineNestedType ("N1"); AssertEquals (nested.Name, "N1"); AssertEquals (nested.BaseType, typeof (object)); AssertEquals (nested.Attributes, TypeAttributes.NestedPrivate); AssertEquals (nested.GetInterfaces ().Length, 0); } // TODO: } [Test] public void TestDefinePInvokeMethod () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefinePInvokeMethod ("A", "B", "C", 0, 0, null, null, 0, 0); // Try invalid parameters try { tb.DefinePInvokeMethod (null, "B", "C", 0, 0, null, null, 0, 0); Fail (); } catch (ArgumentNullException) { } // etc... // Try invalid attributes try { tb.DefinePInvokeMethod ("A2", "B", "C", MethodAttributes.Abstract, 0, null, null, 0, 0); } catch (ArgumentException) { } // Try an interface parent TypeBuilder tb2 = module.DefineType (genTypeName (), TypeAttributes.Interface | TypeAttributes.Abstract); try { tb2.DefinePInvokeMethod ("A", "B", "C", 0, 0, null, null, 0, 0); } catch (ArgumentException) { } } [Test] public void TestDefineProperty () { TypeBuilder tb = module.DefineType (genTypeName ()); // Check null parameter types try { tb.DefineProperty ("A", 0, null, new Type[1]); } catch (ArgumentNullException) { } } [Test] [ExpectedException (typeof(NotSupportedException))] [Category("NotWorking")] public void TestIsDefinedIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.IsDefined (typeof (int), true); } [Test] public void TestIsDefinedComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); ConstructorInfo obsoleteCtor = typeof(ObsoleteAttribute).GetConstructor( new Type[] {typeof(string)}); CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (obsoleteCtor, new object[] { "obsolete message" }, new FieldInfo[0], new object[0]); tb.SetCustomAttribute (caBuilder); tb.CreateType (); AssertEquals (true, tb.IsDefined (typeof(ObsoleteAttribute), false)); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetCustomAttributesIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetCustomAttributes (false); } [Test] public void TestGetCustomAttributesComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); ConstructorInfo guidCtor = typeof(GuidAttribute).GetConstructor ( new Type[] { typeof(string) }); CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (guidCtor, new object[] { Guid.NewGuid ().ToString ("D") }, new FieldInfo[0], new object[0]); tb.SetCustomAttribute (caBuilder); tb.CreateType (); AssertEquals (1, tb.GetCustomAttributes (false).Length); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetCustomAttributesOfTypeIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetCustomAttributes (typeof(ObsoleteAttribute), false); } [Test] public void TestGetCustomAttributesOfTypeComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); ConstructorInfo guidCtor = typeof(GuidAttribute).GetConstructor ( new Type[] { typeof(string) }); CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (guidCtor, new object[] { Guid.NewGuid ().ToString ("D") }, new FieldInfo[0], new object[0]); tb.SetCustomAttribute (caBuilder); tb.CreateType (); AssertEquals (1, tb.GetCustomAttributes (typeof(GuidAttribute), false).Length); AssertEquals (0, tb.GetCustomAttributes (typeof(ObsoleteAttribute), false).Length); } [Test] [ExpectedException (typeof(ArgumentNullException))] public void TestGetCustomAttributesOfNullTypeComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.CreateType (); tb.GetCustomAttributes (null, false); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetEventsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetEvents (); } [Test] public void TestGetEventsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); MethodBuilder onclickMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public, typeof(void), new Type[] { typeof(Object) }); onclickMethod.GetILGenerator ().Emit (OpCodes.Ret); // create public event EventBuilder eventbuilder = tb.DefineEvent ("Change", EventAttributes.None, typeof(ResolveEventHandler)); eventbuilder.SetRaiseMethod (onclickMethod); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetEvents ().Length); AssertEquals (tb.GetEvents ().Length, emittedType.GetEvents ().Length); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetEventsFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetEvents (BindingFlags.Public); } [Test] public void TestGetEventsFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); MethodBuilder onchangeMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public, typeof(void), new Type[] { typeof(Object) }); onchangeMethod.GetILGenerator ().Emit (OpCodes.Ret); // create public event EventBuilder changeEvent = tb.DefineEvent ("Change", EventAttributes.None, typeof(ResolveEventHandler)); changeEvent.SetRaiseMethod (onchangeMethod); // create non-public event EventBuilder redoChangeEvent = tb.DefineEvent ("RedoChange", EventAttributes.None, typeof(ResolveEventHandler)); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetEvents (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (1, tb.GetEvents (BindingFlags.Instance | BindingFlags.NonPublic).Length); AssertEquals (2, tb.GetEvents (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length); AssertEquals (tb.GetEvents (BindingFlags.Instance | BindingFlags.Public).Length, emittedType.GetEvents (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (tb.GetEvents (BindingFlags.Instance | BindingFlags.NonPublic).Length, emittedType.GetEvents (BindingFlags.Instance | BindingFlags.NonPublic).Length); AssertEquals (tb.GetEvents (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length, emittedType.GetEvents (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Length); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetEventIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetEvent ("FOO"); } [Test] public void TestGetEventComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); MethodBuilder onclickMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public, typeof(void), new Type[] { typeof(Object) }); onclickMethod.GetILGenerator ().Emit (OpCodes.Ret); EventBuilder eventbuilder = tb.DefineEvent ("Change", EventAttributes.None, typeof(ResolveEventHandler)); eventbuilder.SetRaiseMethod (onclickMethod); Type emittedType = tb.CreateType (); AssertNotNull (tb.GetEvent ("Change")); AssertEquals (tb.GetEvent ("Change"), emittedType.GetEvent ("Change")); AssertNull (tb.GetEvent ("NotChange")); AssertEquals (tb.GetEvent ("NotChange"), emittedType.GetEvent ("NotChange")); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetEventFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetEvent ("FOO", BindingFlags.Public); } [Test] public void TestGetEventFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); MethodBuilder onclickMethod = tb.DefineMethod ("OnChange", MethodAttributes.Public, typeof(void), new Type[] { typeof(Object) }); onclickMethod.GetILGenerator ().Emit (OpCodes.Ret); EventBuilder eventbuilder = tb.DefineEvent ("Change", EventAttributes.None, typeof(ResolveEventHandler)); eventbuilder.SetRaiseMethod (onclickMethod); Type emittedType = tb.CreateType (); AssertNotNull (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.Public)); AssertEquals (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.Public), emittedType.GetEvent ("Change", BindingFlags.Instance | BindingFlags.Public)); AssertNull (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.NonPublic)); AssertEquals (tb.GetEvent ("Change", BindingFlags.Instance | BindingFlags.NonPublic), emittedType.GetEvent ("Change", BindingFlags.Instance | BindingFlags.NonPublic)); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetFieldsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetFields (); } [Test] public void TestGetFieldsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineField ("TestField", typeof(int), FieldAttributes.Public); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetFields ().Length); AssertEquals (tb.GetFields ().Length, emittedType.GetFields().Length); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetFieldsFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetFields (BindingFlags.Instance | BindingFlags.Public); } [Test] public void TestGetFieldsFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineField ("TestField", typeof(int), FieldAttributes.Public); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetFields (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (tb.GetFields (BindingFlags.Instance | BindingFlags.Public).Length, emittedType.GetFields (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (0, tb.GetFields (BindingFlags.Instance | BindingFlags.NonPublic).Length); AssertEquals (tb.GetFields (BindingFlags.Instance | BindingFlags.NonPublic).Length, emittedType.GetFields (BindingFlags.Instance | BindingFlags.NonPublic).Length); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetFieldIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetField ("test"); } [Test] public void TestGetFieldComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineField ("TestField", typeof(int), FieldAttributes.Public); Type emittedType = tb.CreateType (); AssertNotNull (tb.GetField ("TestField")); AssertEquals (tb.GetField ("TestField").Name, emittedType.GetField ("TestField").Name); //AssertNull (tb.GetField ("TestOtherField")); //AssertEquals (tb.GetField ("TestOtherField").Name, // emittedType.GetField ("TestOtherField").Name); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetFieldFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetField ("test", BindingFlags.Public); } [Test] public void TestGetFieldFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineField ("TestField", typeof(int), FieldAttributes.Public); Type emittedType = tb.CreateType (); AssertNotNull (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.Public)); AssertEquals (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.Public).Name, emittedType.GetField ("TestField", BindingFlags.Instance | BindingFlags.Public).Name); AssertNull (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.NonPublic)); AssertEquals (tb.GetField ("TestField", BindingFlags.Instance | BindingFlags.NonPublic), emittedType.GetField ("TestField", BindingFlags.Instance | BindingFlags.NonPublic)); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetPropertiesIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetProperties (); } [Test] public void TestGetPropertiesComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetProperties ().Length); AssertEquals (tb.GetProperties ().Length, emittedType.GetProperties ().Length); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetPropertiesFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetProperties (BindingFlags.Public); } [Test] public void TestGetPropertiesFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetProperties (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (tb.GetProperties (BindingFlags.Instance | BindingFlags.Public).Length, emittedType.GetProperties (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (0, tb.GetProperties (BindingFlags.Instance | BindingFlags.NonPublic).Length); AssertEquals (tb.GetProperties (BindingFlags.Instance | BindingFlags.NonPublic).Length, emittedType.GetProperties (BindingFlags.Instance | BindingFlags.NonPublic).Length); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetPropertyIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetProperty ("test"); } [Test] public void TestGetPropertyComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public); Type emittedType = tb.CreateType (); AssertNotNull (emittedType.GetProperty ("CustomerName")); AssertNull (emittedType.GetProperty ("OtherCustomerName")); try { tb.GetProperty ("CustomerName"); Fail (); } catch (NotSupportedException) {} } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetPropertyFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetProperty ("test", BindingFlags.Public); } [Test] public void TestGetPropertyFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); DefineStringProperty (tb, "CustomerName", "customerName", MethodAttributes.Public); Type emittedType = tb.CreateType (); AssertNotNull (emittedType.GetProperty ("CustomerName", BindingFlags.Instance | BindingFlags.Public)); AssertNull (emittedType.GetProperty ("CustomerName", BindingFlags.Instance | BindingFlags.NonPublic)); try { tb.GetProperty ("CustomerName", BindingFlags.Instance | BindingFlags.Public); Fail (); } catch (NotSupportedException) { } } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetMethodsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetMethods (); } [Test] [Category("NotWorking")] public void TestGetMethodsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); MethodBuilder helloMethod = tb.DefineMethod ("HelloMethod", MethodAttributes.Public, typeof(string), new Type[0]); ILGenerator helloMethodIL = helloMethod.GetILGenerator (); helloMethodIL.Emit (OpCodes.Ldstr, "Hi! "); helloMethodIL.Emit (OpCodes.Ldarg_1); MethodInfo infoMethod = typeof(string).GetMethod ("Concat", new Type[] { typeof(string), typeof(string) }); helloMethodIL.Emit (OpCodes.Call, infoMethod); helloMethodIL.Emit (OpCodes.Ret); Type emittedType = tb.CreateType (); AssertEquals (typeof(object).GetMethods (BindingFlags.Public | BindingFlags.Instance).Length + 1, tb.GetMethods ().Length); AssertEquals (tb.GetMethods ().Length, emittedType.GetMethods ().Length); } [Test] [ExpectedException (typeof(NotSupportedException))] [Ignore("mcs depends on this")] public void TestGetMethodsFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetMethods (BindingFlags.Public); } [Test] public void TestGetMethodsFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); MethodBuilder helloMethod = tb.DefineMethod ("HelloMethod", MethodAttributes.Public, typeof(string), new Type[0]); ILGenerator helloMethodIL = helloMethod.GetILGenerator (); helloMethodIL.Emit (OpCodes.Ldstr, "Hi! "); helloMethodIL.Emit (OpCodes.Ldarg_1); MethodInfo infoMethod = typeof(string).GetMethod ("Concat", new Type[] { typeof(string), typeof(string) }); helloMethodIL.Emit (OpCodes.Call, infoMethod); helloMethodIL.Emit (OpCodes.Ret); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetMethods (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Length); AssertEquals (tb.GetMethods (BindingFlags.Instance | BindingFlags.Public).Length, emittedType.GetMethods (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (0, tb.GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly).Length); AssertEquals (tb.GetMethods (BindingFlags.Instance | BindingFlags.NonPublic).Length, emittedType.GetMethods (BindingFlags.Instance | BindingFlags.NonPublic).Length); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetMemberIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetMember ("FOO", MemberTypes.All, BindingFlags.Public); } [Test] public void TestGetMemberComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineField ("FOO", typeof(int), FieldAttributes.Private); Type emittedType = tb.CreateType (); AssertEquals (1, tb.GetMember ("FOO", MemberTypes.Field, BindingFlags.Instance | BindingFlags.NonPublic).Length); AssertEquals (0, tb.GetMember ("FOO", MemberTypes.Field, BindingFlags.Instance | BindingFlags.Public).Length); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetMembersIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetMembers (); } [Test] public void TestGetMembersComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); Type emittedType = tb.CreateType (); AssertEquals (tb.GetMembers ().Length, emittedType.GetMembers ().Length); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetMembersFlagsIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetMembers (BindingFlags.Public); } [Test] public void TestGetMembersFlagsComplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.DefineField ("FOO", typeof(int), FieldAttributes.Public); Type emittedType = tb.CreateType (); Assert (tb.GetMembers (BindingFlags.Instance | BindingFlags.Public).Length != 0); AssertEquals (tb.GetMembers (BindingFlags.Instance | BindingFlags.Public).Length, emittedType.GetMembers (BindingFlags.Instance | BindingFlags.Public).Length); AssertEquals (tb.GetMembers (BindingFlags.Instance | BindingFlags.NonPublic).Length, emittedType.GetMembers (BindingFlags.Instance | BindingFlags.NonPublic).Length); } [Test] [ExpectedException (typeof(NotSupportedException))] public void TestGetInterfaceIncomplete () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.GetInterface ("FOO", true); } [Test] public void TestGetInterfaces () { TypeBuilder tb = module.DefineType (genTypeName ()); Type[] interfaces = tb.GetInterfaces (); AssertEquals (0, interfaces.Length); TypeBuilder tbInterface = module.DefineType (genTypeName (), TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); Type emittedInterface = tbInterface.CreateType (); tb = module.DefineType (genTypeName (), TypeAttributes.Public, typeof(object), new Type[] { emittedInterface }); interfaces = tb.GetInterfaces (); AssertEquals (1, interfaces.Length); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void TestAddDeclarativeSecurityAlreadyCreated () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.CreateType (); PermissionSet set = new PermissionSet (PermissionState.Unrestricted); tb.AddDeclarativeSecurity (SecurityAction.Demand, set); } [Test] [ExpectedException (typeof (ArgumentNullException))] public void TestAddDeclarativeSecurityNullPermissionSet () { TypeBuilder tb = module.DefineType (genTypeName ()); tb.AddDeclarativeSecurity (SecurityAction.Demand, null); } [Test] public void TestAddDeclarativeSecurityInvalidAction () { TypeBuilder tb = module.DefineType (genTypeName ()); SecurityAction[] actions = new SecurityAction [] { SecurityAction.RequestMinimum, SecurityAction.RequestOptional, SecurityAction.RequestRefuse }; PermissionSet set = new PermissionSet (PermissionState.Unrestricted); foreach (SecurityAction action in actions) { try { tb.AddDeclarativeSecurity (action, set); Fail (); } catch (ArgumentOutOfRangeException) { } } } [Test] [ExpectedException (typeof (InvalidOperationException))] public void TestAddDeclarativeSecurityDuplicateAction () { TypeBuilder tb = module.DefineType (genTypeName ()); PermissionSet set = new PermissionSet (PermissionState.Unrestricted); tb.AddDeclarativeSecurity (SecurityAction.Demand, set); tb.AddDeclarativeSecurity (SecurityAction.Demand, set); } [Test] public void TestEnums () { TypeAttributes typeAttrs = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed; TypeBuilder enumToCreate = module.DefineType(genTypeName (), typeAttrs, typeof(Enum)); enumToCreate.SetCustomAttribute (new CustomAttributeBuilder (typeof (FlagsAttribute).GetConstructors ()[0], new Type [0])); // add value__ field, see DefineEnum method of ModuleBuilder enumToCreate.DefineField("value__", typeof(Int32), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); // add enum entries FieldBuilder fb = enumToCreate.DefineField("A", enumToCreate, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); fb.SetConstant((Int32) 0); fb = enumToCreate.DefineField("B", enumToCreate, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); fb.SetConstant((Int32) 1); fb = enumToCreate.DefineField("C", enumToCreate, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); fb.SetConstant((Int32) 2); Type enumType = enumToCreate.CreateType(); object enumVal = Enum.ToObject(enumType, (Int32) 3); AssertEquals ("B, C", enumVal.ToString ()); AssertEquals (3, (Int32)enumVal); } [Test] public void DefineEnum () { TypeBuilder typeBuilder = module.DefineType (genTypeName (), TypeAttributes.Public); EnumBuilder enumBuilder = module.DefineEnum (genTypeName (), TypeAttributes.Public, typeof(int)); typeBuilder.DefineField ("myField", enumBuilder, FieldAttributes.Private); enumBuilder.CreateType(); typeBuilder.CreateType(); } [Test] [ExpectedException(typeof(TypeLoadException))] [Category("NotWorking")] public void DefineEnumThrowIfTypeBuilderCalledBeforeEnumBuilder () { TypeBuilder typeBuilder = module.DefineType (genTypeName (), TypeAttributes.Public); EnumBuilder enumBuilder = module.DefineEnum (genTypeName (), TypeAttributes.Public, typeof(int)); typeBuilder.DefineField ("myField", enumBuilder, FieldAttributes.Private); typeBuilder.CreateType(); enumBuilder.CreateType(); } private void DefineStringProperty (TypeBuilder tb, string propertyName, string fieldName, MethodAttributes methodAttribs) { // define the field holding the property value FieldBuilder fieldBuilder = tb.DefineField (fieldName, typeof(string), FieldAttributes.Private); PropertyBuilder propertyBuilder = tb.DefineProperty ( propertyName, PropertyAttributes.HasDefault, typeof(string), new Type[] { typeof(string) }); // First, we'll define the behavior of the "get" property for CustomerName as a method. MethodBuilder getMethodBuilder = tb.DefineMethod ("Get" + propertyName, methodAttribs, typeof(string), new Type[] { }); ILGenerator getIL = getMethodBuilder.GetILGenerator (); getIL.Emit (OpCodes.Ldarg_0); getIL.Emit (OpCodes.Ldfld, fieldBuilder); getIL.Emit (OpCodes.Ret); // Now, we'll define the behavior of the "set" property for CustomerName. MethodBuilder setMethodBuilder = tb.DefineMethod ("Set" + propertyName, methodAttribs, null, new Type[] { typeof(string) }); ILGenerator setIL = setMethodBuilder.GetILGenerator (); setIL.Emit (OpCodes.Ldarg_0); setIL.Emit (OpCodes.Ldarg_1); setIL.Emit (OpCodes.Stfld, fieldBuilder); setIL.Emit (OpCodes.Ret); // Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. propertyBuilder.SetGetMethod (getMethodBuilder); propertyBuilder.SetSetMethod (setMethodBuilder); } static int handler_called = 0; [Test] public void TestTypeResolve () { string typeName = genTypeName (); ResolveEventHandler handler = new ResolveEventHandler (TypeResolve); AppDomain.CurrentDomain.TypeResolve += handler; handler_called = 0; Type t = Type.GetType (typeName); AssertEquals (typeName, t.Name); AssertEquals (1, handler_called); AppDomain.CurrentDomain.TypeResolve -= handler; } Assembly TypeResolve (object sender, ResolveEventArgs args) { TypeBuilder tb = module.DefineType (args.Name, TypeAttributes.Public); tb.CreateType (); handler_called ++; return tb.Assembly; } [Test] public void TestIsAssignableTo () { Type icomparable = typeof (IComparable); TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public, null, new Type[] { icomparable, typeof (Bar) }); Assert ("01", icomparable.IsAssignableFrom (tb)); Assert ("02", !tb.IsAssignableFrom (icomparable)); Assert ("03", typeof (Bar).IsAssignableFrom (tb)); Assert ("04", !typeof (Baz).IsAssignableFrom (tb)); Assert ("05", tb.IsAssignableFrom (tb)); Assert ("06", !tb.IsAssignableFrom (typeof (IDisposable))); tb.AddInterfaceImplementation (typeof (IDisposable)); // Fails under .net, so we don't support it either //Assert ("07", tb.IsAssignableFrom (typeof (IDisposable))); } [Test] [Category("NotDotNet")] public void TestIsAssignableTo_NotDotNet () { Type icomparable = typeof (IComparable); TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public, null, new Type[] { icomparable, typeof (Bar) }); Assert ("01", typeof (Foo).IsAssignableFrom (tb)); tb.AddInterfaceImplementation (typeof (IDisposable)); // bug #73469 Assert ("02", typeof (Bar[]).IsAssignableFrom (module.GetType (tb.FullName + "[]"))); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void EmptyMethodBody () { TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public); tb.DefineMethod ("foo", MethodAttributes.Public, typeof (void), new Type [] {}); tb.CreateType (); } [Test] [ExpectedException (typeof (InvalidOperationException))] public void EmptyCtorBody () { TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public); tb.DefineConstructor (0, CallingConventions.Standard, null); tb.CreateType (); } #if NET_2_0 [Test] public void GenericType () { TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public); tb.DefineGenericParameters ("T"); Assert ("01", tb.IsGenericType); Assert ("02", tb.IsGenericTypeDefinition); Assert ("03", tb.ContainsGenericParameters); Assert ("04", !tb.IsGenericParameter); Type[] args = tb.GetGenericArguments (); Assert ("a01", !args [0].IsGenericType); Assert ("a02", !args [0].IsGenericTypeDefinition); Assert ("a03", args [0].ContainsGenericParameters); Assert ("a04", args [0].IsGenericParameter); } #endif } }