2 // MonoGenericClassTest.cs - NUnit Test Cases for MonoGenericClassTest
4 // Rodrigo Kumpera <rkumpera@novell.com>
6 // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
7 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
10 #if !MONOTOUCH && !FULL_AOT_RUNTIME
13 using System
.Collections
;
14 using System
.Collections
.Generic
;
15 using System
.Collections
.ObjectModel
;
16 using System
.Threading
;
17 using System
.Reflection
;
18 using System
.Reflection
.Emit
;
20 using System
.Security
;
21 using System
.Security
.Permissions
;
22 using System
.Runtime
.InteropServices
;
23 using NUnit
.Framework
;
24 using System
.Runtime
.CompilerServices
;
26 namespace MonoTests
.System
.Reflection
.Emit
29 public class MonoGenericClassTest
31 AssemblyBuilder assembly
;
34 static string ASSEMBLY_NAME
= "MonoTests.System.Reflection.Emit.MonoGenericClassTest";
38 return "internal__type"+ typeCount
++;
44 SetUp (AssemblyBuilderAccess
.RunAndSave
);
47 void SetUp (AssemblyBuilderAccess access
)
49 AssemblyName assemblyName
= new AssemblyName ();
50 assemblyName
.Name
= ASSEMBLY_NAME
;
53 Thread
.GetDomain ().DefineDynamicAssembly (
54 assemblyName
, access
, Path
.GetTempPath ());
56 module
= assembly
.DefineDynamicModule ("module1");
62 public void TestNameMethods ()
64 TypeBuilder tb
= module
.DefineType ("foo.type");
65 tb
.DefineGenericParameters ("T", "K");
67 Type inst
= tb
.MakeGenericType (typeof (double), typeof (string));
69 Assert
.AreEqual ("type", inst
.Name
, "#1");
70 Assert
.AreEqual ("foo", inst
.Namespace
, "#2");
72 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");
73 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");
74 #elif MOBILE || MOBILE
75 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");
76 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");
77 Assert
.AreEqual ("foo.type[System.Double,System.String]", inst
.ToString (), "#5");
81 static void CheckInst (string prefix
, Type inst
, int a
, int b
)
83 var resA
= inst
.GetMethods (BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
);
84 var resB
= inst
.GetMethods (BindingFlags
.Public
| BindingFlags
.Instance
);
86 Assert
.AreEqual (a
, resA
.Length
, prefix
+ 1);
87 Assert
.AreEqual (b
, resB
.Length
, prefix
+ 2);
91 public void MethodsThatRaiseNotSupported ()
93 var tb
= module
.DefineType ("foo.type");
94 tb
.DefineGenericParameters ("T");
96 var ginst
= tb
.MakeGenericType (typeof (double));
99 ginst
.GetElementType ();
101 } catch (NotSupportedException
) { }
103 ginst
.GetInterface ("foo", true);
105 } catch (NotSupportedException
) { }
107 ginst
.GetEvent ("foo", BindingFlags
.Public
| BindingFlags
.Instance
);
109 } catch (NotSupportedException
) { }
111 ginst
.GetField ("foo", BindingFlags
.Public
| BindingFlags
.Instance
);
113 } catch (NotSupportedException
) { }
115 ginst
.GetMembers (BindingFlags
.Public
| BindingFlags
.Instance
);
117 } catch (NotSupportedException
) { }
119 ginst
.GetMethod ("Foo");
121 } catch (NotSupportedException
) { }
123 ginst
.GetNestedType ("foo", BindingFlags
.Public
| BindingFlags
.Instance
);
125 } catch (NotSupportedException
) { }
127 ginst
.GetProperty ("foo");
129 } catch (NotSupportedException
) { }
131 var x
= ginst
.TypeInitializer
;
133 } catch (NotSupportedException
) { }
135 var x
= ginst
.InvokeMember ("foo", BindingFlags
.InvokeMethod
| BindingFlags
.Public
| BindingFlags
.Instance
, null, null, null);
137 } catch (NotSupportedException
) { }
139 ginst
.IsDefined (typeof (int), true);
141 } catch (NotSupportedException
) { }
143 ginst
.GetCustomAttributes (true);
145 } catch (NotSupportedException
) { }
147 ginst
.GetCustomAttributes (typeof (int), true);
149 } catch (NotSupportedException
) { }
151 ginst
.IsAssignableFrom (ginst
);
153 } catch (NotSupportedException
) { }
155 ginst
.GetNestedTypes (BindingFlags
.Public
);
157 } catch (NotSupportedException
) { }
161 public void ClassMustNotBeRegisteredAfterTypeBuilderIsFinished ()
163 TypeBuilder tb
= module
.DefineType ("foo.type");
164 tb
.DefineGenericParameters ("T");
166 var c
= tb
.CreateType ();
168 var sreInst
= tb
.MakeGenericType (typeof (int));
169 var rtInst
= c
.MakeGenericType (typeof (int));
171 Assert
.AreNotSame (sreInst
, rtInst
, "#1");
173 /*This must not throw*/
174 rtInst
.IsDefined (typeof (int), true);
177 public class Bar
<T
> {
178 public class Foo
<U
> {}
182 public void DeclaringTypeMustReturnNonInflatedType ()
184 var ut
= new TypeDelegator (typeof (int));
185 var ut2
= typeof(Bar
<>.Foo
<>);
186 var t
= ut2
.MakeGenericType (ut
, ut
);
187 Assert
.AreSame (typeof (Bar
<>), t
.DeclaringType
, "#1");
190 public class Base
<T
> {}
191 public class SubClass
<K
> : Base
<K
> {}
194 public void BaseTypeMustReturnNonInflatedType ()
196 var ut
= new TypeDelegator (typeof (int));
197 var ut2
= typeof(SubClass
<>);
198 var t
= ut2
.MakeGenericType (ut
);
199 //This is Base<K> where K is SubClass::K
200 var expected
= typeof (Base
<>).MakeGenericType (typeof (SubClass
<>).GetGenericArguments ()[0]);
201 Assert
.AreSame (expected
, t
.BaseType
, "#1");
206 public void GenericClassFromStaleTypeBuilderDoesNotClassInit ()
208 // interface JJJ<T> {
209 // abstract void W (x : T)
211 MethodInfo winfo
= null;
212 TypeBuilder ib
= null;
214 Type icreated
= null;
216 ib
= module
.DefineType ("Foo.JJJ`1",
217 TypeAttributes
.Public
218 | TypeAttributes
.Interface
219 | TypeAttributes
.Abstract
);
220 String
[] gens
= { "T" }
;
221 GenericTypeParameterBuilder
[] gbs
= ib
.DefineGenericParameters (gens
);
223 winfo
= ib
.DefineMethod ("W",
224 MethodAttributes
.Public
|
225 MethodAttributes
.Abstract
|
226 MethodAttributes
.Virtual
,
227 CallingConventions
.HasThis
,
230 icreated
= ib
.CreateType();
234 // class SSS : JJJ<char> {
236 // void JJJ.W (x : T) { wasCalled = true; return; }
238 TypeBuilder tb
= null;
239 MethodBuilder mb
= null;
241 tb
= module
.DefineType ("Foo.SSS",
242 TypeAttributes
.Public
,
244 new Type
[]{ icreated.MakeGenericType(typeof(char)) }
);
245 var wasCalledField
= tb
.DefineField ("wasCalled",
247 FieldAttributes
.Public
);
248 mb
= tb
.DefineMethod ("W_impl",
249 MethodAttributes
.Public
| MethodAttributes
.Virtual
,
250 CallingConventions
.HasThis
,
252 new Type
[] { typeof (char) }
);
254 var il
= mb
.GetILGenerator ();
255 il
.Emit (OpCodes
.Ldarg_0
); // this
256 il
.Emit (OpCodes
.Ldc_I4_1
);
257 il
.Emit (OpCodes
.Stfld
, wasCalledField
); // this.wasCalled = true
258 il
.Emit (OpCodes
.Ret
);
262 ic
= ib
.MakeGenericType(typeof (char)); // this is a MonoGenericMethod
263 var mintf
= TypeBuilder
.GetMethod(ic
, winfo
);
264 // the next line causes mono_class_init() to
265 // be called on JJJ<char> when we try to setup
266 // the vtable for SSS
267 tb
.DefineMethodOverride(mb
, mintf
);
269 var result
= tb
.CreateType();
272 object o
= Activator
.CreateInstance(result
);
273 Assert
.IsNotNull(o
, "#1");
275 // ((JJJ<char>)o).W('a');
276 var m
= icreated
.MakeGenericType(typeof(char)).GetMethod("W", BindingFlags
.Public
| BindingFlags
.Instance
);
277 Assert
.IsNotNull(m
, "#2");
278 m
.Invoke(o
, new object[] {'a'}
);
280 var f
= result
.GetField("wasCalled", BindingFlags
.Public
| BindingFlags
.Instance
);
281 Assert
.IsNotNull(f
, "#3");
282 var wasCalledVal
= f
.GetValue(o
);
283 Assert
.IsNotNull(wasCalledVal
, "#4");
284 Assert
.AreEqual (wasCalledVal
.GetType(), typeof(Boolean
), "#5");
285 Assert
.AreEqual (wasCalledVal
, true, "#6");