1 // CustomAttributeBuilderTest.cs
2 //
3 // Author: Vineeth N <nvineeth@yahoo.com>
4 //
5 // (C) 2004 Ximian, Inc. http://www.ximian.com
6 //
7 using System;
8 using System.IO;
9 using System.Reflection;
10 using System.Reflection.Emit;
11 using System.Threading;
12 using NUnit.Framework;
13 
14 namespace MonoTests.System.Reflection.Emit
15 {
16 	/// <summary>
17 	/// TestFixture for CustomAttributeBuilderTest.
18 	/// The members to be tested are as follows:
19 	/// 4 constructors:
20 	/// 1) public CustomAttributeBuilder(ConstructorInfo, object[]);
21 	/// 2) public CustomAttributeBuilder(ConstructorInfo, object[], FieldInfo[], object[]);
22 	/// 3) public CustomAttributeBuilder(ConstructorInfo, object[], PropertyInfo[], object[]);
23 	/// 4) public CustomAttributeBuilder(ConstructorInfo, object[], PropertyInfo[], object[], FieldInfo[], object[]);
24 	/// and the exceptions that are thrown.
25 	/// In the implementation , it can be seen that the first
26 	/// three type of  constructors call the 4th type of ctor, which takes 6 args
27 	/// by filling args and substituting null as required.
28 	/// For testing constructors we have use 4 different test functions,
29 	/// Various exceptions have been checked for 4th type of consturctor.
30 	/// </summary>
31 
32 	[TestFixture]
33 	public class CustomAttributeBuilderTest
34 	{
35 		static string tempDir = Path.Combine (Path.GetTempPath (), typeof (CustomAttributeBuilderTest).FullName);
36 
37 		// the CustomAttribute class is used for testing and it has to be public
38 		//since it will be associated with a class that belongs to another assembly
39 
40 		[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Class)]
41 		public class CustomAttribute: Attribute
42 		{
43 			private string attr1;
44 			private string attr2;
45 			public string Feild; //used for testing the second type of constructor
46 
CustomAttribute()47 			public CustomAttribute () {}
CustomAttribute(String s1 , String s2)48 			public CustomAttribute (String s1 , String s2)
49 			{
50 				attr1 = s1;
51 				attr2=s2;
52                         }
53 
CustomAttribute(String s1)54 			private CustomAttribute (String s1) {}
CustomAttribute()55 			static CustomAttribute () {}
56 
57 			public string AttributeOne
58 			{
59 				get { return attr1; }
60 				set { attr1 = value; }
61 			}
62 
63 			public string AttributeTwo
64 			{
65 				get { return attr2; }
66 				//the set is skipped and is used later in testing
67 			}
68 
69 		}
70 
71 		private class TempClass
72 		{
73 			//used for testing the ArgumentException
74 			public string Field;
75 			public string FieldProperty
76 			{
77 				get { return Field; }
78 				set { Field = value; }
79 			}
80 		}
81 
82 		[SetUp]
SetUp()83 		public void SetUp ()
84 		{
85 			Random AutoRand = new Random ();
86 			string basePath = tempDir;
87 			while (Directory.Exists (tempDir))
88 				tempDir = Path.Combine (basePath, AutoRand.Next ().ToString ());
89 			Directory.CreateDirectory (tempDir);
90 		}
91 
92 		[TearDown]
TearDown()93 		public void TearDown ()
94 		{
95 			try {
96 				// This throws an exception under MS.NET, since the directory contains loaded
97 				// assemblies.
98 				Directory.Delete (tempDir, true);
99 			} catch (Exception) {
100 			}
101 		}
102 
103 		[Test]
CtorOneTest()104 		public void CtorOneTest ()
105 		{
106 			//test for the constructor with signature--
107 			// public CustomAttributeBuilder(ConstructorInfo, object[]);
108 			/*
109 			 * WE build a imaginary type as follows
110 			 * class TestType
111 			 * {
112 			 *	[CustomAttribute("one","two")]
113 			 *	public string Str;
114 			 *
115 			 *	[CustomAttribute("hello","world")]
116 			 *	public void Print()
117 			 *	{Console.WriteLine("Hello World"); }
118 			 *
119 			 * }
120 			 * And then check for the validity of attributes in the test functions
121 			 */
122 			AssemblyName asmName = new AssemblyName ();
123 			asmName.Name = "TestAssembly.dll";
124 
125 			AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
126 				asmName , AssemblyBuilderAccess.Run);
127 
128 			ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
129 
130 			TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
131 				TypeAttributes.Public);
132 
133 			Type[] ctorParams = new Type[] { typeof (string),typeof (string) };
134 
135 			ConstructorInfo classCtorInfo =
136 				typeof (CustomAttribute).GetConstructor (ctorParams);
137 
138 			CustomAttributeBuilder feildCABuilder = new CustomAttributeBuilder (
139 				classCtorInfo,
140 				new object [] { "one","two" }
141 				),
142 				methodCABuilder = new CustomAttributeBuilder (
143 				classCtorInfo,
144 				new object [] { "hello","world" }
145 				);
146 			//now let's build a feild of type string and associate a attribute with it
147 			FieldBuilder fieldBuilder= typeBuilder.DefineField ("Str",
148 				typeof (string), FieldAttributes.Public);
149 			fieldBuilder.SetCustomAttribute (feildCABuilder);
150 			//now build a method
151 			MethodBuilder methodBuilder= typeBuilder.DefineMethod ("Print",
152 				MethodAttributes.Public, null, null);
153 			methodBuilder.SetCustomAttribute (methodCABuilder);
154 			ILGenerator methodIL = methodBuilder.GetILGenerator ();
155 			methodIL.EmitWriteLine ("Hello, world!");
156 			methodIL.Emit (OpCodes.Ret);
157 
158 			// create the type
159 			Type myType = typeBuilder.CreateType ();
160 
161 			//Now check for the validity of the attributes.
162 			object testInstance = Activator.CreateInstance (myType);
163 
164 			//check the validity of the attribute associated with Print method
165 
166 			object [] methodAttrs =  myType.GetMember ("Print") [0].GetCustomAttributes (true);
167 			Assert.AreEqual (methodAttrs.Length, 1, "#1");
168 			CustomAttribute methodAttr = methodAttrs [0] as CustomAttribute;
169 			Assert.AreEqual (methodAttr.AttributeOne, "hello", "#2");
170 			Assert.AreEqual (methodAttr.AttributeTwo, "world", "#3");
171 
172 			//check the validity of the attribute associated with Str feild
173 
174 			object [] fieldAttrs = myType.GetField ("Str").GetCustomAttributes (true);
175 			Assert.AreEqual(fieldAttrs.Length, 1, "#4");
176 			CustomAttribute fieldAttr = fieldAttrs [0] as CustomAttribute;
177 			Assert.AreEqual(fieldAttr.AttributeOne, "one", "#5");
178 			Assert.AreEqual(fieldAttr.AttributeTwo, "two", "#6");
179 		}
180 
181 		[Test]
CtorTwoTest()182 		public void CtorTwoTest ()
183 		{
184 			//test for the constructor with signature--
185 			// CustomAttributeBuilder Constructor (ConstructorInfo, Object[], FieldInfo[], Object[]) ;
186 			/*
187 			 * WE build a imaginary type as follows
188 			 * [CustomAttribute("Test","Type")]
189 			 * public class TestType
190 			 * {
191 			 *
192 			 * }
193 			 * We also set the "Feild" of class CustomAttribute and the value;
194 			 * And then check for the validity of attributes in the test functions
195 			 */
196 
197 			AssemblyName asmName = new AssemblyName ();
198 			asmName.Name = "TestAssembly.dll";
199 
200 			AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
201 				asmName, AssemblyBuilderAccess.Run);
202 
203 			ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
204 
205 			TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
206 				TypeAttributes.Public);
207 
208 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
209 
210 			ConstructorInfo classCtorInfo =
211 				typeof (CustomAttribute).GetConstructor (ctorParams);
212 
213 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
214 				classCtorInfo,
215 				new object [] { "Test","Type" },
216 				typeof(CustomAttribute).GetFields(),
217 				new object [] { "TestCase" }
218 				);
219 
220 			typeBuilder.SetCustomAttribute (typeCABuilder);
221 
222 			// create the type
223 			Type myType = typeBuilder.CreateType ();
224 
225 			//Now check for the validity of the attributes.
226 			object testInstance = Activator.CreateInstance (myType);
227 
228 			//check the validity of the attribute associated with Print method
229 			object [] customAttrs = myType.GetCustomAttributes (false);
230 			Assert.AreEqual (customAttrs.Length, 1, "1");
231 
232 			//Custom Attributes of TestType
233 			CustomAttribute attr = customAttrs [0] as CustomAttribute;
234 			Assert.AreEqual (attr.AttributeOne, "Test", "#2");
235 			Assert.AreEqual (attr.AttributeTwo, "Type", "#3");
236 			Assert.AreEqual (attr.Feild, "TestCase", "#4");
237 
238 		}
239 
240 		[Test]
CtorThreeTest()241 		public void CtorThreeTest ()
242 		{
243 			//test for the constructor with signature--
244 			// CustomAttributeBuilder Constructor (ConstructorInfo, Object[], PropertyInfo[], Object[]) ;
245 			/*
246 			 * WE build a imaginary type as follows
247 			 * [CustomAttribute()]
248 			 * public class TestType
249 			 * {
250 			 *
251 			 * }
252 			 * We also set the "AttributeOne" of class CustomAttribute by means of the constuctor
253 			 * And then check for the validity of attribute state
254 			 */
255 
256 			AssemblyName asmName = new AssemblyName ();
257 			asmName.Name = "TestAssembly.dll";
258 
259 			AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
260 				asmName, AssemblyBuilderAccess.Run);
261 
262 			ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
263 
264 			TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
265 				TypeAttributes.Public);
266 
267 			Type [] ctorParams = new Type [] { };
268 
269 			ConstructorInfo classCtorInfo =
270 				typeof (CustomAttribute).GetConstructor (ctorParams);
271 
272 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
273 				classCtorInfo,
274 				new object [] { },
275 				new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
276 				new object [] { "TestCase" }
277 				);
278 
279 			typeBuilder.SetCustomAttribute (typeCABuilder);
280 
281 			// create the type
282 			Type myType = typeBuilder.CreateType ();
283 
284 			//Now check for the validity of the attributes.
285 			object testInstance = Activator.CreateInstance (myType);
286 
287 			//check the validity of the attribute associated with Print method
288 			object [] customAttrs = myType.GetCustomAttributes (false);
289 			Assert.AreEqual (customAttrs.Length , 1, "#1");
290 
291 			//Custom Attributes of TestType
292 			CustomAttribute attr = customAttrs [0] as CustomAttribute;
293 			Assert.AreEqual(attr.AttributeOne, "TestCase", "#2");
294 		}
295 
296 		[Test]
CtorFourTest()297 		public void CtorFourTest ()
298 		{
299 			//test for the constructor with signature--
300 			//public CustomAttributeBuilder(ConstructorInfo, object[], PropertyInfo[], object[], FieldInfo[], object[]);
301 			/*
302 			 * WE build a imaginary type as follows
303 			 * [CustomAttribute()]
304 			 * public class TestType
305 			 * {
306 			 *
307 			 * }
308 			 * We also set the "AttributeOne" property ,
309 			 * and "Feild" of class CustomAttribute
310 			 * by means of the constuctor of CustomAttributeBuilder
311 			 * And then check for the validity
312 			 */
313 
314 			AssemblyName asmName = new AssemblyName ();
315 			asmName.Name = "TestAssembly.dll";
316 
317 			AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
318 				asmName , AssemblyBuilderAccess.Run);
319 
320 			ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
321 
322 			TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
323 				TypeAttributes.Public);
324 
325 			Type [] ctorParams = new Type [] { };
326 
327 			ConstructorInfo classCtorInfo =
328 				typeof (CustomAttribute).GetConstructor (ctorParams);
329 
330 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder(
331 				classCtorInfo,
332 				new object [] { },
333 				new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
334 				new object [] { "TestCase" },
335 				typeof(CustomAttribute).GetFields (),
336 				new object [] { "FieldValue" }
337 				);
338 
339 			typeBuilder.SetCustomAttribute (typeCABuilder);
340 
341 			// create the type
342 			Type myType = typeBuilder.CreateType ();
343 
344 			//Now check for the validity of the attributes.
345 			object testInstance = Activator.CreateInstance (myType);
346 
347 			//check the validity of the attribute associated with Print method
348 			object [] customAttrs = myType.GetCustomAttributes (false);
349 			Assert.AreEqual(customAttrs.Length , 1, "#1");
350 
351 			//Custom Attributes of TestType
352 			CustomAttribute attr = customAttrs [0] as CustomAttribute;
353 			Assert.AreEqual (attr.AttributeOne, "TestCase", "#2");
354 			Assert.AreEqual (attr.Feild, "FieldValue", "#3");
355 		}
356 
357 
358 		[Test]
359 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_1()360 		public void ArgumentExceptionTest_1 ()
361 		{
362 			//here the constructor is static
363 
364 			Type [] ctorParams = new Type [] { };
365 
366 			ConstructorInfo classCtorInfo =
367 				typeof (CustomAttribute).GetConstructor (BindingFlags.Static | BindingFlags.NonPublic,
368                                                 null, ctorParams, null);
369 
370 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
371 				classCtorInfo,
372 				new object [] { },
373 				new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
374 				new object [] { "TestCase" },
375 				typeof (CustomAttribute).GetFields (),
376 				new object [] { "FieldValue" }
377 				);
378 		}
379 
380 
381 		[Test]
382 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_2()383 		public void ArgumentExceptionTest_2 ()
384 		{
385 			//here the consturctor is private
386 
387 			Type [] ctorParams = new Type[] {typeof(string) };
388 
389 			ConstructorInfo classCtorInfo =
390 				typeof (CustomAttribute).GetConstructor (BindingFlags.Instance |
391                                                 BindingFlags.NonPublic, null, ctorParams, null);
392 
393 			Assert.IsNotNull (classCtorInfo);
394 
395 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
396 				classCtorInfo,
397 				new object [] { "hello" },
398 				new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
399 				new object [] { "TestCase" },
400 				typeof (CustomAttribute).GetFields (),
401 				new object [] { "FieldValue" }
402 				);
403 		}
404 
405 
406 		[Test]
407 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_3()408 		public void ArgumentExceptionTest_3 ()
409 		{
410 			// The lengths of the namedProperties and
411 			//propertyValues arrays are different.
412 
413 			Type [] ctorParams = new Type [] { };
414 
415 			ConstructorInfo classCtorInfo =
416 				typeof (CustomAttribute).GetConstructor (ctorParams);
417 
418 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
419 				classCtorInfo,
420 				new object [] { },
421 				new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
422 				new object [] { "TestCase","extra arg" },//<--here is the error
423 				typeof (CustomAttribute).GetFields (),
424 				new object [] { "FieldValue" }
425 				);
426 		}
427 
428 
429 		[Test]
430 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_4()431 		public void ArgumentExceptionTest_4()
432 		{
433 			//The length of the namedFields and
434 			//namedValues are different
435 
436 			Type [] ctorParams = new Type [] { };
437 
438 			ConstructorInfo classCtorInfo =
439 				typeof (CustomAttribute).GetConstructor (ctorParams);
440 
441 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
442 				classCtorInfo,
443 				new object [] { },
444 				new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
445 				new object [] { "TestCase" },
446 				typeof (CustomAttribute).GetFields (),
447 				new object [] { }//<--here is the error
448 				);
449 		}
450 
451 
452 		[Test]
453 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_6()454 		public void ArgumentExceptionTest_6 ()
455 		{
456 			//The type of supplied argument does not
457 			//match the type of the parameter declared
458 			//in the constructor.
459 
460 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
461 
462 			ConstructorInfo classCtorInfo =
463 				typeof (CustomAttribute).GetConstructor (ctorParams);
464 
465 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
466 				classCtorInfo,
467 				new object [] { "1", 123 },//<--here is the error,(int instead of string)
468 				new PropertyInfo[]{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
469 				new object [] { "TestCase" },
470 				typeof (CustomAttribute).GetFields (),
471 				new object [] { "FeildValue" }
472 				);
473 		}
474 
475 
476 		[Test]
477 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_7()478 		public void ArgumentExceptionTest_7 ()
479 		{
480 			//A property has no setter.(CustomAttribute.AttributeTwo)
481 
482 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
483 
484 			ConstructorInfo classCtorInfo =
485 				typeof (CustomAttribute).GetConstructor (ctorParams);
486 
487 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
488 				classCtorInfo,
489 				new object [] { "1","2" },
490 				new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeTwo") },
491 				new object [] { "TestCase" },
492 				typeof (CustomAttribute).GetFields (),
493 				new object [] { "FeildValue" }
494 				);
495 		}
496 
497 
498 		[Test]
499 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_8()500 		public void ArgumentExceptionTest_8 ()
501 		{
502 			//A property doesnot belong to same class
503 
504 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
505 
506 			ConstructorInfo classCtorInfo =
507 				typeof (CustomAttribute).GetConstructor (ctorParams);
508 
509 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
510 				classCtorInfo,
511 				new object [] { "1","2" },
512 				new PropertyInfo [] { typeof (TempClass).GetProperty ("FieldProperty")}, //here is the error
513 				new object [] { "TestCase" },
514 				typeof (CustomAttribute).GetFields (),
515 				new object [] { "FeildValue" }
516 				);
517 		}
518 
519 
520 		[Test]
521 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_9()522 		public void ArgumentExceptionTest_9 ()
523 		{
524 			//A field doesnot belong to same class
525 
526 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
527 
528 			ConstructorInfo classCtorInfo =
529 				typeof (CustomAttribute).GetConstructor (ctorParams);
530 
531 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
532 				classCtorInfo,
533 				new object [] { "1","2" },
534 				new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
535 				new object [] {"TestCase"},
536 				typeof (TempClass).GetFields (), //<-- fields of TempClass are passed
537 				new object [] { "FeildValue" }
538 				);
539 		}
540 
541 
542 		[Test]
543 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_10()544 		public void ArgumentExceptionTest_10 ()
545 		{
546 			//The types of the property values do
547 			//not match the types of the named properties.
548 
549 
550 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
551 
552 			ConstructorInfo classCtorInfo =
553 				typeof (CustomAttribute).GetConstructor (ctorParams);
554 
555 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
556 				classCtorInfo,
557 				new object [] { "1","2" },
558 				new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
559 				new object [] { (long)1212121212 }, //<---type mismatch error(long for string)
560 				typeof (CustomAttribute).GetFields (),
561 				new object [] { "FeildValue" }
562 				);
563 		}
564 
565 
566 		[Test]
567 		[ExpectedException (typeof (ArgumentException))]
ArgumentExceptionTest_11()568 		public void ArgumentExceptionTest_11 ()
569 		{
570 			//The types of the field values do
571 			//not match the types of the named properties.
572 
573 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
574 
575 			ConstructorInfo classCtorInfo =
576 				typeof (CustomAttribute).GetConstructor (ctorParams);
577 
578 			Assert.IsNotNull (classCtorInfo);
579 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
580 				classCtorInfo,
581 				new object [] { "1","2" },
582 				new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
583 				new object [] { "One" },
584 				typeof (CustomAttribute).GetFields (),
585 				new object []{ 12.1212 } //<---type mismatch error(double for string)
586 				);
587 		}
588 
589 
590 		[Test]
591 		[ExpectedException (typeof (ArgumentNullException))]
ArgumentNullException_1()592 		public void ArgumentNullException_1 ()
593 		{
594 			//the ctor value array (2nd argument) is null
595 			Type [] ctorParams = new Type [] { typeof (string),typeof (string) };
596 
597 			ConstructorInfo classCtorInfo =
598 				typeof (CustomAttribute).GetConstructor (ctorParams);
599 
600 			Assert.IsNotNull (classCtorInfo);
601 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
602 				classCtorInfo,
603 				null, //<-- here is the error
604 				new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
605 				new object [] { "One" },
606 				typeof (CustomAttribute).GetFields (),
607 				new object [] { "feild" }
608 				);
609 		}
610 
611 
612 		[Test]
613 		[ExpectedException (typeof (ArgumentNullException))]
ArgumentNullException_2()614 		public void ArgumentNullException_2 ()
615 		{
616 			//the property value array (4th argument) is null
617 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
618 
619 			ConstructorInfo classCtorInfo =
620 				typeof (CustomAttribute).GetConstructor (ctorParams);
621 
622 			Assert.IsNotNull (classCtorInfo);
623 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
624 				classCtorInfo,
625 				new object [] { "one","two" },
626 				new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
627 				null, // <-- here is the error
628 				typeof (CustomAttribute).GetFields (),
629 				new object [] { "feild" }
630 				);
631 		}
632 
633 
634 		[Test]
635 		[ExpectedException (typeof (ArgumentNullException))]
ArgumentNullException_3()636 		public void ArgumentNullException_3 ()
637 		{
638 			//the field value array (6th argument) is null
639 			Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
640 
641 			ConstructorInfo classCtorInfo =
642 				typeof (CustomAttribute).GetConstructor (ctorParams);
643 
644 			Assert.IsNotNull (classCtorInfo);
645 			CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
646 				classCtorInfo,
647 				new object [] { "one","two" },
648 				new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
649 				new object [] {"property"},
650 				typeof (CustomAttribute).GetFields (),
651 				null // <-- here is the error
652 				);
653 		}
654 
655 		class C {
C(object i)656 			public C (object i) {
657 			}
658 		}
659 
660 		[Test]
661 		[ExpectedException (typeof (ArgumentException))]
ObjectParam_UserDefinedClass()662 		public void ObjectParam_UserDefinedClass ()
663 		{
664 			var cab = new CustomAttributeBuilder(
665 						 typeof (C).GetConstructors ()[0],
666 						 new object[] { new C (1) });
667 		}
668 
669 
670 		[Test]
671 		[ExpectedException (typeof (ArgumentException))]
ValueTypeParam_Null()672 		public void ValueTypeParam_Null ()
673 		{
674 	        ConstructorInfo classCtorInfo =
675 	            typeof (CattrD).GetConstructors ()[0];
676 
677 	        CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
678 	            classCtorInfo, new object [] { null });
679 		}
680 
681 		[Test]
682 		[ExpectedException (typeof (ArgumentException))]
ValueTypeArrayParam_Null()683 		public void ValueTypeArrayParam_Null ()
684 		{
685 	        ConstructorInfo classCtorInfo =
686 	            typeof (CattrE).GetConstructors ()[0];
687 
688 	        CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
689 	            classCtorInfo, new object [] { new object[] { null } });
690 		}
691 
692 		public class CattrD : Attribute
693 		{
CattrD(bool b)694 		    public CattrD (bool b) {}
695 		}
696 
697 		public class CattrE : Attribute
698 		{
CattrE(bool[] b)699 		    public CattrE (bool[] b) {}
700 		}
701 
702 		public class JaggedAttr : Attribute {
703 			public static string[][] Data { get; set; }
704 
JaggedAttr(string[][] data)705 			public JaggedAttr (string[][] data) {
706 				Data = data;
707 			}
708 		}
709 
710 		[Test]
JaggedArrays()711 		public void JaggedArrays () {
712 			var ab = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("Foo"), AssemblyBuilderAccess.Save, tempDir);
713 			var modb = ab.DefineDynamicModule ("Foo", "Foo.dll");
714 			var tb = modb.DefineType ("T");
715 			tb.SetCustomAttribute (new
716 								   CustomAttributeBuilder(typeof (JaggedAttr).GetConstructors ()[0],
717 														  new object[] { new string[][] { new string[] { "foo" }, new string[] { "bar" } } }));
718 			tb.CreateType ();
719 			ab.Save ("Foo.dll");
720 
721 			string assemblyPath = Path.Combine (tempDir, "Foo.dll");
722 			Type t = Assembly.LoadFrom (assemblyPath).GetType ("T");
723 			Assert.AreEqual (1, t.GetCustomAttributes (false).Length);
724 
725 			string[][] res = JaggedAttr.Data;
726 			Assert.AreEqual (2, res.Length);
727 			Assert.AreEqual ("foo", res [0][0]);
728 			Assert.AreEqual ("bar", res [1][0]);
729 		}
730 
731 		[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
732 		internal class NonVisibleCustomAttribute : Attribute
733 		{
NonVisibleCustomAttribute()734 			public NonVisibleCustomAttribute () {}
735 		}
736 
737 		[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
738 		public class PublicVisibleCustomAttribute : Attribute
739 		{
PublicVisibleCustomAttribute()740 			public PublicVisibleCustomAttribute () {}
741 		}
742 
AddCustomClassAttribute(TypeBuilder typeBuilder, Type customAttrType)743 		private static void AddCustomClassAttribute (TypeBuilder typeBuilder, Type customAttrType)
744 		{
745 			var attribCtorParams = new Type[] {};
746 			var attribCtorInfo = customAttrType.GetConstructor(attribCtorParams);
747 			var attribBuilder = new CustomAttributeBuilder(attribCtorInfo, new object[] { });
748 			typeBuilder.SetCustomAttribute(attribBuilder);
749 		}
750 
751 		[Test]
NonvisibleCustomAttribute()752 		public void NonvisibleCustomAttribute () {
753 			//
754 			// We build:
755 			//  [VisiblePublicCustom]
756 			//  [VisiblePublicCustom]
757 			//  [NonVisibleCustom]
758 			//  [VisiblePublicCustom]
759 			//  class BuiltType { public BuiltType () { } }
760 			//
761 			// And then we try to get all the attributes.
762 			//
763 			// Regression test for https://bugzilla.xamarin.com/show_bug.cgi?id=43291
764 						var assemblyName = new AssemblyName("Repro43291Asm");
765 			var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
766 			var moduleBuilder = assemblyBuilder.DefineDynamicModule("Repro43291Mod");
767 
768 			var typeBuilder = moduleBuilder.DefineType("BuiltType",
769 				TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.BeforeFieldInit);
770 
771 			AddCustomClassAttribute (typeBuilder, typeof (PublicVisibleCustomAttribute));
772 			AddCustomClassAttribute (typeBuilder, typeof (PublicVisibleCustomAttribute));
773 			AddCustomClassAttribute (typeBuilder, typeof (NonVisibleCustomAttribute));
774 			AddCustomClassAttribute (typeBuilder, typeof (PublicVisibleCustomAttribute));
775 
776 			var createdType = typeBuilder.CreateType ();
777 
778 			Assert.IsNotNull (createdType);
779 
780 			var obj = Activator.CreateInstance (createdType);
781 
782 			Assert.IsNotNull (obj);
783 
784 			var attrs = obj.GetType ().GetCustomAttributes (typeof (Attribute), true);
785 
786 			Assert.IsNotNull (attrs);
787 
788 			Assert.AreEqual (3, attrs.Length);
789 			Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[0]);
790 			Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[1]);
791 			Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[2]);
792 		}
793 
794 		[Test]
CustomAttributeSameAssembly()795 		public void CustomAttributeSameAssembly () {
796 			// Regression test for 55681
797 			//
798 			// We build:
799 			// class MyAttr : Attr { public MyAttr () { } }
800 			// [assembly:MyAttr()]
801 			//
802 			// the important bit is that we pass the ConstructorBuilder to the CustomAttributeBuilder
803 			var assemblyName = new AssemblyName ("Repro55681");
804 			var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.Save, tempDir);
805 			var moduleBuilder = assemblyBuilder.DefineDynamicModule ("Repro55681", "Repro55681.dll");
806 			var typeBuilder = moduleBuilder.DefineType ("MyAttr", TypeAttributes.Public, typeof (Attribute));
807 			ConstructorBuilder ctor = typeBuilder.DefineDefaultConstructor (MethodAttributes.Public);
808 			typeBuilder.CreateType ();
809 
810 			assemblyBuilder.SetCustomAttribute (new CustomAttributeBuilder (ctor, new object [] { }));
811 
812 			assemblyBuilder.Save ("Repro55681.dll");
813 		}
814 
815 		[Test]
CustomAttributeAcrossAssemblies()816 		public void CustomAttributeAcrossAssemblies () {
817 			// Regression test for 55681
818 			//
819 			// We build:
820 			// assembly1:
821 			//   class MyAttr : Attr { public MyAttr () { } }
822 			// assembly2:
823 			//   class Dummy { }
824 			//   [assembly:MyAttr()]
825 			//
826  			// the important bit is that we pass the ConstructorBuilder to the CustomAttributeBuilder
827 			var assemblyName1 = new AssemblyName ("Repro55681-2a");
828 			var assemblyBuilder1 = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName1, AssemblyBuilderAccess.Save, tempDir);
829 			var moduleBuilder1 = assemblyBuilder1.DefineDynamicModule ("Repro55681-2a", "Repro55681-2a.dll");
830 			var typeBuilder1 = moduleBuilder1.DefineType ("MyAttr", TypeAttributes.Public, typeof (Attribute));
831 			ConstructorBuilder ctor = typeBuilder1.DefineDefaultConstructor (MethodAttributes.Public);
832 			typeBuilder1.CreateType ();
833 
834 			var assemblyName2 = new AssemblyName ("Repro55681-2b");
835 			var assemblyBuilder2 = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName2, AssemblyBuilderAccess.Save, tempDir);
836 			var moduleBuilder2 = assemblyBuilder2.DefineDynamicModule ("Repro55681-2b", "Repro55681-2b.dll");
837 
838 			var typeBuilder2 = moduleBuilder2.DefineType ("Dummy", TypeAttributes.Public);
839 			typeBuilder2.DefineDefaultConstructor (MethodAttributes.Public);
840 			typeBuilder2.CreateType ();
841 
842 			assemblyBuilder2.SetCustomAttribute (new CustomAttributeBuilder (ctor, new object [] { }));
843 
844 			assemblyBuilder2.Save ("Repro55681-2b.dll");
845 			assemblyBuilder1.Save ("Repro55681-2a.dll");
846 		}
847 
848 	}
849 }
850 
851