2 // GenericTypeParameterBuilderTest.cs - NUnit Test Cases for GenericTypeParameterBuilder
4 // Rodrigo Kumpera <rkumpera@novell.com>
6 // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
10 using System.Collections;
11 using System.Threading;
12 using System.Reflection;
13 using System.Reflection.Emit;
15 using System.Security;
16 using System.Security.Permissions;
17 using System.Runtime.InteropServices;
18 using NUnit.Framework;
19 using System.Runtime.CompilerServices;
21 using System.Collections.Generic;
23 namespace MonoTests.System.Reflection.Emit
26 public class GenericTypeParameterBuilderTest
28 AssemblyBuilder assembly;
30 static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
33 protected void SetUp ()
35 SetUp (AssemblyBuilderAccess.RunAndSave);
38 protected void SetUp (AssemblyBuilderAccess mode)
40 AssemblyName assemblyName = new AssemblyName ();
41 assemblyName.Name = ASSEMBLY_NAME;
44 Thread.GetDomain ().DefineDynamicAssembly (
45 assemblyName, mode, Path.GetTempPath ());
47 module = assembly.DefineDynamicModule ("module1");
51 public void PropertiesValue ()
53 TypeBuilder tb = module.DefineType ("ns.type", TypeAttributes.Public);
54 var gparam = tb.DefineGenericParameters ("A", "B")[1];
56 Assert.AreEqual (assembly, gparam.Assembly, "#1");
57 Assert.AreEqual (null, gparam.AssemblyQualifiedName, "#2");
58 Assert.AreEqual (null, gparam.BaseType, "#3");
59 Assert.AreEqual (null, gparam.FullName, "#4");
60 Assert.AreEqual (module, gparam.Module, "#5");
61 Assert.AreEqual (null, gparam.Namespace, "#6");
62 Assert.AreEqual (gparam, gparam.UnderlyingSystemType, "#7");
63 Assert.AreEqual ("B", gparam.Name, "#8");
66 object x = gparam.GUID;
68 } catch (NotSupportedException) {}
71 object x = gparam.TypeHandle;
73 } catch (NotSupportedException) {}
76 object x = gparam.StructLayoutAttribute;
78 } catch (NotSupportedException) {}
80 Assert.AreEqual (TypeAttributes.Public, gparam.Attributes, "#12");
81 Assert.IsFalse (gparam.HasElementType, "#13");
82 Assert.IsFalse (gparam.IsArray, "#14");
83 Assert.IsFalse (gparam.IsByRef, "#15");
84 Assert.IsFalse (gparam.IsCOMObject, "#16");
85 Assert.IsFalse (gparam.IsPointer, "#17");
86 Assert.IsFalse (gparam.IsPrimitive, "#18");
91 public void Methods ()
93 TypeBuilder tb = module.DefineType ("ns.type", TypeAttributes.Public);
94 var gparam = tb.DefineGenericParameters ("A", "B")[1];
97 gparam.GetInterface ("foo", true);
99 } catch (NotSupportedException) {
104 gparam.GetInterfaces ();
106 } catch (NotSupportedException) {
111 gparam.GetElementType ();
113 } catch (NotSupportedException) {
118 gparam.GetEvent ("foo", BindingFlags.Public);
120 } catch (NotSupportedException) {
125 gparam.GetEvents (BindingFlags.Public);
127 } catch (NotSupportedException) {
132 gparam.GetField ("foo", BindingFlags.Public);
134 } catch (NotSupportedException) {
139 gparam.GetFields (BindingFlags.Public);
141 } catch (NotSupportedException) {
146 gparam.GetMembers (BindingFlags.Public);
148 } catch (NotSupportedException) {
153 gparam.GetMethod ("Sort");
155 } catch (NotSupportedException) {
160 gparam.GetMethods (BindingFlags.Public);
162 } catch (NotSupportedException) {
167 gparam.GetNestedType ("bla", BindingFlags.Public);
169 } catch (NotSupportedException) {
174 gparam.GetNestedTypes (BindingFlags.Public);
176 } catch (NotSupportedException) {
181 gparam.GetProperties (BindingFlags.Public);
183 } catch (NotSupportedException) {
188 gparam.GetProperty ("Length");
190 } catch (NotSupportedException) {
195 gparam.GetConstructor (new Type[] { typeof (int) });
197 } catch (NotSupportedException) {
202 gparam.GetArrayRank ();
204 } catch (NotSupportedException) {
209 gparam.GetConstructors (BindingFlags.Public);
211 } catch (NotSupportedException) {}
214 gparam.InvokeMember ("GetLength", BindingFlags.Public, null, null, null);
216 } catch (NotSupportedException) {}
219 gparam.IsSubclassOf (gparam);
221 } catch (NotSupportedException) {}
224 gparam.IsAssignableFrom (gparam);
226 } catch (NotSupportedException) {}
229 gparam.GetInterfaceMap (typeof (IEnumerable));
231 } catch (NotSupportedException) {}
234 gparam.IsInstanceOfType (new object());
236 } catch (NotSupportedException) {}
240 public void MakeGenericType ()
242 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public);
243 var gparam = tb.DefineGenericParameters ("A", "B")[1];
245 gparam.MakeGenericType (new Type[] { typeof (string) });
247 } catch (InvalidOperationException) {}
252 public void GenericParameterAttributes ()
254 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public);
255 var gparam = tb.DefineGenericParameters ("A", "B")[1];
257 object attr = gparam.GenericParameterAttributes;
259 } catch (NotSupportedException) {}
263 public void MakeArrayType ()
265 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public);
266 var gparam = tb.DefineGenericParameters ("A", "B")[1];
267 Type res = gparam.MakeArrayType ();
268 Assert.IsNotNull (res, "#1");
269 Assert.IsTrue (res.IsArray, "#2");
271 res = gparam.MakeArrayType (2);
272 Assert.IsNotNull (res, "#3");
273 Assert.IsTrue (res.IsArray, "#4");
277 public void MakeByRefType ()
279 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public);
280 var gparam = tb.DefineGenericParameters ("A", "B")[1];
281 Type res = gparam.MakeByRefType ();
283 Assert.IsNotNull (res, "#1");
284 Assert.IsTrue (res.IsByRef, "#2");
288 public void MakePointerType ()
290 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public);
291 var gparam = tb.DefineGenericParameters ("A", "B")[1];
292 Type res = gparam.MakePointerType ();
294 Assert.IsNotNull (res, "#1");
295 Assert.IsTrue (res.IsPointer, "#2");
299 public void SetBaseTypeConstraintWithNull ()
301 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public);
302 var gparam = tb.DefineGenericParameters ("A", "B")[1];
304 Assert.IsNull (gparam.BaseType, "#1");
305 gparam.SetBaseTypeConstraint (null);
306 Assert.AreEqual (typeof (object), gparam.BaseType, "#2");
310 public void GenericTypeMembers ()
312 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public);
313 var gparam = tb.DefineGenericParameters ("A", "B")[1];
316 gparam.GetGenericArguments ();
318 } catch (InvalidOperationException) {}
321 gparam.GetGenericParameterConstraints ();
323 } catch (InvalidOperationException) {}
326 gparam.GetGenericTypeDefinition ();
328 } catch (InvalidOperationException) {}
330 Assert.IsTrue (gparam.ContainsGenericParameters, "#4");
332 var x = gparam.GenericParameterAttributes;
334 } catch (NotSupportedException) {}
336 Assert.AreEqual (1, gparam.GenericParameterPosition, "#6");
338 Assert.IsTrue (gparam.ContainsGenericParameters, "#7");
340 Assert.IsTrue (gparam.IsGenericParameter, "#8");
341 Assert.IsFalse (gparam.IsGenericType, "#9");
342 Assert.IsFalse (gparam.IsGenericTypeDefinition, "#10");
346 // CompilerContext no longer supported
347 [Category ("NotWorking")]
348 public void GetAttributeFlagsImpl ()
350 SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800);
351 TypeBuilder tb = module.DefineType ("ns.type", TypeAttributes.Public);
352 var gparam = tb.DefineGenericParameters ("A", "B")[1];
354 Assert.AreEqual (TypeAttributes.Public, gparam.Attributes, "#1");
358 public void ActionConstructorInfoTest ()
360 // Regression test for https://bugzilla.xamarin.com/show_bug.cgi?id=58454
362 // Need to check that GenericTypeParameterBuilderTest:InternalResolve() passes the declaring type to GetMethodFromHandle()
366 public class Store<TState> {
367 public Action<TSelection> Subscribe<TSelection> (TState state) {
368 return new Action<TSelection> (Foo<TSelection>);
370 public static void Foo<X> (X x) { }
373 ... and then: new Store<string>().Subscribe<int>("x");
376 SetUp (AssemblyBuilderAccess.Run);
378 var tb = module.DefineType ("Store");
379 var tparsStore = tb.DefineGenericParameters ("TState");
381 tb.DefineDefaultConstructor (MethodAttributes.Public);
383 var methFoo = tb.DefineMethod ("Foo", MethodAttributes.Public | MethodAttributes.Static);
384 var tparsFoo = methFoo.DefineGenericParameters ("X");
385 methFoo.SetReturnType (typeof(void));
386 methFoo.SetParameters (tparsFoo[0]);
387 methFoo.GetILGenerator().Emit (OpCodes.Ret);
389 var methSub = tb.DefineMethod ("Subscribe", MethodAttributes.Public | MethodAttributes.Static);
390 var tparsSub = methSub.DefineGenericParameters ("TSelection");
391 var actOfSel = typeof(Action<>).MakeGenericType (tparsSub[0]); // Action<TSelection>
392 methSub.SetReturnType (actOfSel);
393 methSub.SetParameters (tparsStore[0]); // TState
394 var ilg = methSub.GetILGenerator ();
395 ilg.Emit (OpCodes.Ldnull); // instance == null
396 ilg.Emit (OpCodes.Ldftn, methFoo.MakeGenericMethod (tparsSub[0])); // ldftn void class Store`1<!TState>::Foo<!!0> (!!0)
397 var aaa = TypeBuilder.GetConstructor (actOfSel, typeof(Action<>).GetConstructors()[0]);
398 ilg.Emit (OpCodes.Newobj, aaa); // new Action<TSelection> (Foo<TSelection>);
399 ilg.Emit (OpCodes.Ret);
401 var tgen = tb.CreateType (); // TState`1
403 var t = tgen.MakeGenericType(typeof(string));
404 var x = t.GetConstructor(Type.EmptyTypes).Invoke (null); // x = new Store<string> ()
405 var mgen = t.GetMethod("Subscribe");
406 var m = mgen.MakeGenericMethod (typeof (int)); // Action<int> Store<string>.Subscribe<int> (string)
407 var y = m.Invoke (x, new object[] {"hello"}); // x.Subscribte<int> ("hello")
408 Assert.IsNotNull (y);