1 // 2 // GenericTypeParameterBuilderTest.cs - NUnit Test Cases for GenericTypeParameterBuilder 3 // 4 // Rodrigo Kumpera <rkumpera@novell.com> 5 // 6 // Copyright (C) 2009 Novell, Inc (http://www.novell.com) 7 // 8 9 using System; 10 using System.Collections; 11 using System.Threading; 12 using System.Reflection; 13 using System.Reflection.Emit; 14 using System.IO; 15 using System.Security; 16 using System.Security.Permissions; 17 using System.Runtime.InteropServices; 18 using NUnit.Framework; 19 using System.Runtime.CompilerServices; 20 21 using System.Collections.Generic; 22 23 namespace MonoTests.System.Reflection.Emit 24 { 25 [TestFixture] 26 public class GenericTypeParameterBuilderTest 27 { 28 AssemblyBuilder assembly; 29 ModuleBuilder module; 30 static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest"; 31 32 [SetUp] SetUp()33 protected void SetUp () 34 { 35 SetUp (AssemblyBuilderAccess.RunAndSave); 36 } 37 SetUp(AssemblyBuilderAccess mode)38 protected void SetUp (AssemblyBuilderAccess mode) 39 { 40 AssemblyName assemblyName = new AssemblyName (); 41 assemblyName.Name = ASSEMBLY_NAME; 42 43 assembly = 44 Thread.GetDomain ().DefineDynamicAssembly ( 45 assemblyName, mode, Path.GetTempPath ()); 46 47 module = assembly.DefineDynamicModule ("module1"); 48 } 49 50 [Test] PropertiesValue()51 public void PropertiesValue () 52 { 53 TypeBuilder tb = module.DefineType ("ns.type", TypeAttributes.Public); 54 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 55 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"); 64 65 try { 66 object x = gparam.GUID; 67 Assert.Fail ("#9"); 68 } catch (NotSupportedException) {} 69 70 try { 71 object x = gparam.TypeHandle; 72 Assert.Fail ("#10"); 73 } catch (NotSupportedException) {} 74 75 try { 76 object x = gparam.StructLayoutAttribute; 77 Assert.Fail ("#11"); 78 } catch (NotSupportedException) {} 79 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"); 87 88 } 89 90 [Test] Methods()91 public void Methods () 92 { 93 TypeBuilder tb = module.DefineType ("ns.type", TypeAttributes.Public); 94 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 95 96 try { 97 gparam.GetInterface ("foo", true); 98 Assert.Fail ("#1"); 99 } catch (NotSupportedException) { 100 101 } 102 103 try { 104 gparam.GetInterfaces (); 105 Assert.Fail ("#2"); 106 } catch (NotSupportedException) { 107 108 } 109 110 try { 111 gparam.GetElementType (); 112 Assert.Fail ("#3"); 113 } catch (NotSupportedException) { 114 115 } 116 117 try { 118 gparam.GetEvent ("foo", BindingFlags.Public); 119 Assert.Fail ("#4"); 120 } catch (NotSupportedException) { 121 122 } 123 124 try { 125 gparam.GetEvents (BindingFlags.Public); 126 Assert.Fail ("#5"); 127 } catch (NotSupportedException) { 128 129 } 130 131 try { 132 gparam.GetField ("foo", BindingFlags.Public); 133 Assert.Fail ("#6"); 134 } catch (NotSupportedException) { 135 136 } 137 138 try { 139 gparam.GetFields (BindingFlags.Public); 140 Assert.Fail ("#7"); 141 } catch (NotSupportedException) { 142 143 } 144 145 try { 146 gparam.GetMembers (BindingFlags.Public); 147 Assert.Fail ("#8"); 148 } catch (NotSupportedException) { 149 150 } 151 152 try { 153 gparam.GetMethod ("Sort"); 154 Assert.Fail ("#9"); 155 } catch (NotSupportedException) { 156 157 } 158 159 try { 160 gparam.GetMethods (BindingFlags.Public); 161 Assert.Fail ("#9"); 162 } catch (NotSupportedException) { 163 164 } 165 166 try { 167 gparam.GetNestedType ("bla", BindingFlags.Public); 168 Assert.Fail ("#10"); 169 } catch (NotSupportedException) { 170 171 } 172 173 try { 174 gparam.GetNestedTypes (BindingFlags.Public); 175 Assert.Fail ("#11"); 176 } catch (NotSupportedException) { 177 178 } 179 180 try { 181 gparam.GetProperties (BindingFlags.Public); 182 Assert.Fail ("#12"); 183 } catch (NotSupportedException) { 184 185 } 186 187 try { 188 gparam.GetProperty ("Length"); 189 Assert.Fail ("#13"); 190 } catch (NotSupportedException) { 191 192 } 193 194 try { 195 gparam.GetConstructor (new Type[] { typeof (int) }); 196 Assert.Fail ("#14"); 197 } catch (NotSupportedException) { 198 199 } 200 201 try { 202 gparam.GetArrayRank (); 203 Assert.Fail ("#15"); 204 } catch (NotSupportedException) { 205 206 } 207 208 try { 209 gparam.GetConstructors (BindingFlags.Public); 210 Assert.Fail ("#16"); 211 } catch (NotSupportedException) {} 212 213 try { 214 gparam.InvokeMember ("GetLength", BindingFlags.Public, null, null, null); 215 Assert.Fail ("#17"); 216 } catch (NotSupportedException) {} 217 218 try { 219 gparam.IsSubclassOf (gparam); 220 Assert.Fail ("#18"); 221 } catch (NotSupportedException) {} 222 223 try { 224 gparam.IsAssignableFrom (gparam); 225 Assert.Fail ("#19"); 226 } catch (NotSupportedException) {} 227 228 try { 229 gparam.GetInterfaceMap (typeof (IEnumerable)); 230 Assert.Fail ("#20"); 231 } catch (NotSupportedException) {} 232 233 try { 234 gparam.IsInstanceOfType (new object()); 235 Assert.Fail ("#21"); 236 } catch (NotSupportedException) {} 237 } 238 239 [Test] MakeGenericType()240 public void MakeGenericType () 241 { 242 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public); 243 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 244 try { 245 gparam.MakeGenericType (new Type[] { typeof (string) }); 246 Assert.Fail ("#1"); 247 } catch (InvalidOperationException) {} 248 } 249 250 251 [Test] GenericParameterAttributes()252 public void GenericParameterAttributes () 253 { 254 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public); 255 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 256 try { 257 object attr = gparam.GenericParameterAttributes; 258 Assert.Fail ("#1"); 259 } catch (NotSupportedException) {} 260 } 261 262 [Test] MakeArrayType()263 public void MakeArrayType () 264 { 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"); 270 271 res = gparam.MakeArrayType (2); 272 Assert.IsNotNull (res, "#3"); 273 Assert.IsTrue (res.IsArray, "#4"); 274 } 275 276 [Test] MakeByRefType()277 public void MakeByRefType () 278 { 279 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public); 280 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 281 Type res = gparam.MakeByRefType (); 282 283 Assert.IsNotNull (res, "#1"); 284 Assert.IsTrue (res.IsByRef, "#2"); 285 } 286 287 [Test] MakePointerType()288 public void MakePointerType () 289 { 290 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public); 291 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 292 Type res = gparam.MakePointerType (); 293 294 Assert.IsNotNull (res, "#1"); 295 Assert.IsTrue (res.IsPointer, "#2"); 296 } 297 298 [Test] SetBaseTypeConstraintWithNull()299 public void SetBaseTypeConstraintWithNull () 300 { 301 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public); 302 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 303 304 Assert.IsNull (gparam.BaseType, "#1"); 305 gparam.SetBaseTypeConstraint (null); 306 Assert.AreEqual (typeof (object), gparam.BaseType, "#2"); 307 } 308 309 [Test] GenericTypeMembers()310 public void GenericTypeMembers () 311 { 312 TypeBuilder tb = module.DefineType ("dd.test", TypeAttributes.Public); 313 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 314 315 try { 316 gparam.GetGenericArguments (); 317 Assert.Fail ("#1"); 318 } catch (InvalidOperationException) {} 319 320 try { 321 gparam.GetGenericParameterConstraints (); 322 Assert.Fail ("#2"); 323 } catch (InvalidOperationException) {} 324 325 try { 326 gparam.GetGenericTypeDefinition (); 327 Assert.Fail ("#3"); 328 } catch (InvalidOperationException) {} 329 330 Assert.IsTrue (gparam.ContainsGenericParameters, "#4"); 331 try { 332 var x = gparam.GenericParameterAttributes; 333 Assert.Fail ("#5"); 334 } catch (NotSupportedException) {} 335 336 Assert.AreEqual (1, gparam.GenericParameterPosition, "#6"); 337 338 Assert.IsTrue (gparam.ContainsGenericParameters, "#7"); 339 340 Assert.IsTrue (gparam.IsGenericParameter, "#8"); 341 Assert.IsFalse (gparam.IsGenericType, "#9"); 342 Assert.IsFalse (gparam.IsGenericTypeDefinition, "#10"); 343 } 344 345 [Test] 346 // CompilerContext no longer supported 347 [Category ("NotWorking")] GetAttributeFlagsImpl()348 public void GetAttributeFlagsImpl () 349 { 350 SetUp (AssemblyBuilderAccess.RunAndSave | (AssemblyBuilderAccess)0x800); 351 TypeBuilder tb = module.DefineType ("ns.type", TypeAttributes.Public); 352 var gparam = tb.DefineGenericParameters ("A", "B")[1]; 353 354 Assert.AreEqual (TypeAttributes.Public, gparam.Attributes, "#1"); 355 } 356 357 [Test] ActionConstructorInfoTest()358 public void ActionConstructorInfoTest () 359 { 360 // Regression test for https://bugzilla.xamarin.com/show_bug.cgi?id=58454 361 // 362 // Need to check that GenericTypeParameterBuilderTest:InternalResolve() passes the declaring type to GetMethodFromHandle() 363 // 364 /* Want to generate: 365 366 public class Store<TState> { 367 public Action<TSelection> Subscribe<TSelection> (TState state) { 368 return new Action<TSelection> (Foo<TSelection>); 369 } 370 public static void Foo<X> (X x) { } 371 } 372 373 ... and then: new Store<string>().Subscribe<int>("x"); 374 */ 375 376 SetUp (AssemblyBuilderAccess.Run); 377 378 var tb = module.DefineType ("Store"); 379 var tparsStore = tb.DefineGenericParameters ("TState"); 380 381 tb.DefineDefaultConstructor (MethodAttributes.Public); 382 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); 388 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); 400 401 var tgen = tb.CreateType (); // TState`1 402 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); 409 } 410 411 } 412 } 413