Merge pull request #337 from robwilkens/IdleThreadsFixes
[mono.git] / mcs / class / corlib / Test / System.Reflection / MonoGenericClassTest.cs
1 //
2 // MonoGenericClassTest.cs - NUnit Test Cases for MonoGenericClassTest
3 //
4 // Rodrigo Kumpera <rkumpera@novell.com>
5 //
6 // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
7 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
8 //
9
10 using System;
11 using System.Collections;
12 using System.Collections.Generic;
13 using System.Collections.ObjectModel;
14 using System.Threading;
15 using System.Reflection;
16 using System.Reflection.Emit;
17 using System.IO;
18 using System.Security;
19 using System.Security.Permissions;
20 using System.Runtime.InteropServices;
21 using NUnit.Framework;
22 using System.Runtime.CompilerServices;
23
24 namespace MonoTests.System.Reflection.Emit
25 {
26         [TestFixture]
27         public class MonoGenericClassTest
28         {
29                 AssemblyBuilder assembly;
30                 ModuleBuilder module;
31                 int typeCount;
32                 static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.MonoGenericClassTest";
33
34                 string MakeName ()
35                 {
36                         return "internal__type"+ typeCount++;
37                 }
38
39                 [SetUp]
40                 public void SetUp ()
41                 {
42                         SetUp (AssemblyBuilderAccess.RunAndSave);
43                 }
44                 
45                 void SetUp (AssemblyBuilderAccess access)
46                 {
47                         AssemblyName assemblyName = new AssemblyName ();
48                         assemblyName.Name = ASSEMBLY_NAME;
49
50                         assembly =
51                                 Thread.GetDomain ().DefineDynamicAssembly (
52                                         assemblyName, access, Path.GetTempPath ());
53
54                         module = assembly.DefineDynamicModule ("module1");
55                         typeCount = 0;
56                 }
57
58
59                 [Test]
60                 public void TestNameMethods ()
61                 {
62                         TypeBuilder tb = module.DefineType ("foo.type");
63                         tb.DefineGenericParameters ("T", "K");
64
65                         Type inst = tb.MakeGenericType (typeof (double), typeof (string));
66
67                         Assert.AreEqual ("type", inst.Name, "#1");
68                         Assert.AreEqual ("foo", inst.Namespace, "#2");
69 #if NET_4_0
70                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", inst.FullName, "#3");
71                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], MonoTests.System.Reflection.Emit.MonoGenericClassTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", inst.AssemblyQualifiedName, "#4");
72 #elif NET_2_1
73                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]", inst.FullName, "#3");
74                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], MonoTests.System.Reflection.Emit.MonoGenericClassTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", inst.AssemblyQualifiedName, "#4");
75 #else
76                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", inst.FullName, "#3");
77                         Assert.AreEqual ("foo.type[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], MonoTests.System.Reflection.Emit.MonoGenericClassTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", inst.AssemblyQualifiedName, "#4");
78 #endif
79                         Assert.AreEqual ("foo.type[System.Double,System.String]", inst.ToString (), "#5");
80                 }
81
82                 static void CheckInst (string prefix, Type inst, int a, int b)
83                 {
84                         var resA = inst.GetMethods (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
85                         var resB = inst.GetMethods (BindingFlags.Public | BindingFlags.Instance);
86
87                         Assert.AreEqual (a, resA.Length, prefix + 1);
88                         Assert.AreEqual (b, resB.Length, prefix + 2);
89                 }
90
91                 [Test]
92                 public void MethodsThatRaiseNotSupported ()
93                 {
94                         var tb = module.DefineType ("foo.type");
95                         tb.DefineGenericParameters ("T");
96
97                         var ginst = tb.MakeGenericType (typeof (double));
98
99                         try {
100                                 ginst.GetElementType ();
101                                 Assert.Fail ("#1");
102                         } catch (NotSupportedException) {  }
103                         try {
104                                 ginst.GetInterface ("foo", true);
105                                 Assert.Fail ("#2");
106                         } catch (NotSupportedException) {  }
107                         try {
108                                 ginst.GetEvent ("foo", BindingFlags.Public | BindingFlags.Instance);
109                                 Assert.Fail ("#3");
110                         } catch (NotSupportedException) {  }
111                         try {
112                                 ginst.GetField ("foo", BindingFlags.Public | BindingFlags.Instance);
113                                 Assert.Fail ("#4");
114                         } catch (NotSupportedException) {  }
115                         try {
116                                 ginst.GetMembers (BindingFlags.Public | BindingFlags.Instance);
117                                 Assert.Fail ("#5");
118                         } catch (NotSupportedException) {  }
119                         try {
120                                 ginst.GetMethod ("Foo");
121                                 Assert.Fail ("#6");
122                         } catch (NotSupportedException) {  }
123                         try {
124                                 ginst.GetNestedType ("foo", BindingFlags.Public | BindingFlags.Instance);
125                                 Assert.Fail ("#7");
126                         } catch (NotSupportedException) {  }
127                         try {
128                                 ginst.GetProperty ("foo");
129                                 Assert.Fail ("#8");
130                         } catch (NotSupportedException) {  }
131                         try {
132                                 var x = ginst.TypeInitializer;
133                                 Assert.Fail ("#9");
134                         } catch (NotSupportedException) {  }
135                         try {
136                                 var x = ginst.InvokeMember ("foo", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, null, null);
137                                 Assert.Fail ("#10");
138                         } catch (NotSupportedException) {  }
139                         try {
140                                 ginst.IsDefined (typeof (int), true);
141                                 Assert.Fail ("#11");
142                         } catch (NotSupportedException) {  }
143                         try {
144                                 ginst.GetCustomAttributes (true);
145                                 Assert.Fail ("#12");
146                         } catch (NotSupportedException) {  }
147                         try {
148                                 ginst.GetCustomAttributes (typeof (int), true);
149                                 Assert.Fail ("#13");
150                         } catch (NotSupportedException) {  }
151                         try {
152                                 ginst.IsAssignableFrom (ginst);
153                                 Assert.Fail ("#14");
154                         } catch (NotSupportedException) {  }
155                         try {
156                                 ginst.GetNestedTypes (BindingFlags.Public);
157                                 Assert.Fail ("#14");
158                         } catch (NotSupportedException) {  }
159                 }
160
161                 [Test]
162                 public void ClassMustNotBeRegisteredAfterTypeBuilderIsFinished ()
163                 {
164                         TypeBuilder tb = module.DefineType ("foo.type");
165                         tb.DefineGenericParameters ("T");
166
167                         var c = tb.CreateType ();
168
169                         var sreInst = tb.MakeGenericType (typeof (int));
170                         var rtInst = c.MakeGenericType (typeof (int));
171
172                         Assert.AreNotSame (sreInst, rtInst, "#1");
173
174                         /*This must not throw*/
175                         rtInst.IsDefined (typeof (int), true);
176                 }
177
178                 public class Bar<T> {
179                         public class Foo<T> {}
180                 }
181
182                 [Test]
183                 public void DeclaringTypeMustReturnNonInflatedType ()
184                 {
185                         var ut = new TypeDelegator (typeof (int));
186                         var ut2 = typeof(Bar<>.Foo<>);
187                         var t = ut2.MakeGenericType (ut, ut);
188                         Assert.AreSame (typeof (Bar<>), t.DeclaringType, "#1");
189                 }
190
191                 public class Base<T> {}
192                 public class SubClass<K> : Base<K> {}
193
194                 [Test]
195                 public void BaseTypeMustReturnNonInflatedType ()
196                 {
197                         var ut = new TypeDelegator (typeof (int));
198                         var ut2 = typeof(SubClass<>);
199                         var t = ut2.MakeGenericType (ut);
200                         //This is Base<K> where K is SubClass::K
201                         var expected = typeof (Base<>).MakeGenericType (typeof (SubClass<>).GetGenericArguments ()[0]);
202                         Assert.AreSame (expected, t.BaseType, "#1");
203                         
204                 }
205         }
206 }