[sre] Handle null values in MarshalAsAttribute CustomAttributeBuilder
[mono-project.git] / mcs / class / corlib / Test / System.Reflection.Emit / CustomAttributeBuilderTest.cs
blob1eb0e9a3040a698fc1dfe8932791a78b0408a471
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 System.Runtime.InteropServices;
13 using NUnit.Framework;
15 namespace MonoTests.System.Reflection.Emit
17 /// <summary>
18 /// TestFixture for CustomAttributeBuilderTest.
19 /// The members to be tested are as follows:
20 /// 4 constructors:
21 /// 1) public CustomAttributeBuilder(ConstructorInfo, object[]);
22 /// 2) public CustomAttributeBuilder(ConstructorInfo, object[], FieldInfo[], object[]);
23 /// 3) public CustomAttributeBuilder(ConstructorInfo, object[], PropertyInfo[], object[]);
24 /// 4) public CustomAttributeBuilder(ConstructorInfo, object[], PropertyInfo[], object[], FieldInfo[], object[]);
25 /// and the exceptions that are thrown.
26 /// In the implementation , it can be seen that the first
27 /// three type of constructors call the 4th type of ctor, which takes 6 args
28 /// by filling args and substituting null as required.
29 /// For testing constructors we have use 4 different test functions,
30 /// Various exceptions have been checked for 4th type of consturctor.
31 /// </summary>
33 [TestFixture]
34 public class CustomAttributeBuilderTest
36 static string tempDir = Path.Combine (Path.GetTempPath (), typeof (CustomAttributeBuilderTest).FullName);
38 // the CustomAttribute class is used for testing and it has to be public
39 //since it will be associated with a class that belongs to another assembly
41 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Class)]
42 public class CustomAttribute: Attribute
44 private string attr1;
45 private string attr2;
46 public string Feild; //used for testing the second type of constructor
48 public CustomAttribute () {}
49 public CustomAttribute (String s1 , String s2)
51 attr1 = s1;
52 attr2=s2;
55 private CustomAttribute (String s1) {}
56 static CustomAttribute () {}
58 public string AttributeOne
60 get { return attr1; }
61 set { attr1 = value; }
64 public string AttributeTwo
66 get { return attr2; }
67 //the set is skipped and is used later in testing
72 private class TempClass
74 //used for testing the ArgumentException
75 public string Field;
76 public string FieldProperty
78 get { return Field; }
79 set { Field = value; }
83 [SetUp]
84 public void SetUp ()
86 Random AutoRand = new Random ();
87 string basePath = tempDir;
88 while (Directory.Exists (tempDir))
89 tempDir = Path.Combine (basePath, AutoRand.Next ().ToString ());
90 Directory.CreateDirectory (tempDir);
93 [TearDown]
94 public void TearDown ()
96 try {
97 // This throws an exception under MS.NET, since the directory contains loaded
98 // assemblies.
99 Directory.Delete (tempDir, true);
100 } catch (Exception) {
104 [Test]
105 public void CtorOneTest ()
107 //test for the constructor with signature--
108 // public CustomAttributeBuilder(ConstructorInfo, object[]);
110 * WE build a imaginary type as follows
111 * class TestType
113 * [CustomAttribute("one","two")]
114 * public string Str;
116 * [CustomAttribute("hello","world")]
117 * public void Print()
118 * {Console.WriteLine("Hello World"); }
121 * And then check for the validity of attributes in the test functions
123 AssemblyName asmName = new AssemblyName ();
124 asmName.Name = "TestAssembly.dll";
126 AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
127 asmName , AssemblyBuilderAccess.Run);
129 ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
131 TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
132 TypeAttributes.Public);
134 Type[] ctorParams = new Type[] { typeof (string),typeof (string) };
136 ConstructorInfo classCtorInfo =
137 typeof (CustomAttribute).GetConstructor (ctorParams);
139 CustomAttributeBuilder feildCABuilder = new CustomAttributeBuilder (
140 classCtorInfo,
141 new object [] { "one","two" }
143 methodCABuilder = new CustomAttributeBuilder (
144 classCtorInfo,
145 new object [] { "hello","world" }
147 //now let's build a feild of type string and associate a attribute with it
148 FieldBuilder fieldBuilder= typeBuilder.DefineField ("Str",
149 typeof (string), FieldAttributes.Public);
150 fieldBuilder.SetCustomAttribute (feildCABuilder);
151 //now build a method
152 MethodBuilder methodBuilder= typeBuilder.DefineMethod ("Print",
153 MethodAttributes.Public, null, null);
154 methodBuilder.SetCustomAttribute (methodCABuilder);
155 ILGenerator methodIL = methodBuilder.GetILGenerator ();
156 methodIL.EmitWriteLine ("Hello, world!");
157 methodIL.Emit (OpCodes.Ret);
159 // create the type
160 Type myType = typeBuilder.CreateType ();
162 //Now check for the validity of the attributes.
163 object testInstance = Activator.CreateInstance (myType);
165 //check the validity of the attribute associated with Print method
167 object [] methodAttrs = myType.GetMember ("Print") [0].GetCustomAttributes (true);
168 Assert.AreEqual (methodAttrs.Length, 1, "#1");
169 CustomAttribute methodAttr = methodAttrs [0] as CustomAttribute;
170 Assert.AreEqual (methodAttr.AttributeOne, "hello", "#2");
171 Assert.AreEqual (methodAttr.AttributeTwo, "world", "#3");
173 //check the validity of the attribute associated with Str feild
175 object [] fieldAttrs = myType.GetField ("Str").GetCustomAttributes (true);
176 Assert.AreEqual(fieldAttrs.Length, 1, "#4");
177 CustomAttribute fieldAttr = fieldAttrs [0] as CustomAttribute;
178 Assert.AreEqual(fieldAttr.AttributeOne, "one", "#5");
179 Assert.AreEqual(fieldAttr.AttributeTwo, "two", "#6");
182 [Test]
183 public void CtorTwoTest ()
185 //test for the constructor with signature--
186 // CustomAttributeBuilder Constructor (ConstructorInfo, Object[], FieldInfo[], Object[]) ;
188 * WE build a imaginary type as follows
189 * [CustomAttribute("Test","Type")]
190 * public class TestType
194 * We also set the "Feild" of class CustomAttribute and the value;
195 * And then check for the validity of attributes in the test functions
198 AssemblyName asmName = new AssemblyName ();
199 asmName.Name = "TestAssembly.dll";
201 AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
202 asmName, AssemblyBuilderAccess.Run);
204 ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
206 TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
207 TypeAttributes.Public);
209 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
211 ConstructorInfo classCtorInfo =
212 typeof (CustomAttribute).GetConstructor (ctorParams);
214 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
215 classCtorInfo,
216 new object [] { "Test","Type" },
217 typeof(CustomAttribute).GetFields(),
218 new object [] { "TestCase" }
221 typeBuilder.SetCustomAttribute (typeCABuilder);
223 // create the type
224 Type myType = typeBuilder.CreateType ();
226 //Now check for the validity of the attributes.
227 object testInstance = Activator.CreateInstance (myType);
229 //check the validity of the attribute associated with Print method
230 object [] customAttrs = myType.GetCustomAttributes (false);
231 Assert.AreEqual (customAttrs.Length, 1, "1");
233 //Custom Attributes of TestType
234 CustomAttribute attr = customAttrs [0] as CustomAttribute;
235 Assert.AreEqual (attr.AttributeOne, "Test", "#2");
236 Assert.AreEqual (attr.AttributeTwo, "Type", "#3");
237 Assert.AreEqual (attr.Feild, "TestCase", "#4");
241 [Test]
242 public void CtorThreeTest ()
244 //test for the constructor with signature--
245 // CustomAttributeBuilder Constructor (ConstructorInfo, Object[], PropertyInfo[], Object[]) ;
247 * WE build a imaginary type as follows
248 * [CustomAttribute()]
249 * public class TestType
253 * We also set the "AttributeOne" of class CustomAttribute by means of the constuctor
254 * And then check for the validity of attribute state
257 AssemblyName asmName = new AssemblyName ();
258 asmName.Name = "TestAssembly.dll";
260 AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
261 asmName, AssemblyBuilderAccess.Run);
263 ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
265 TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
266 TypeAttributes.Public);
268 Type [] ctorParams = new Type [] { };
270 ConstructorInfo classCtorInfo =
271 typeof (CustomAttribute).GetConstructor (ctorParams);
273 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
274 classCtorInfo,
275 new object [] { },
276 new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
277 new object [] { "TestCase" }
280 typeBuilder.SetCustomAttribute (typeCABuilder);
282 // create the type
283 Type myType = typeBuilder.CreateType ();
285 //Now check for the validity of the attributes.
286 object testInstance = Activator.CreateInstance (myType);
288 //check the validity of the attribute associated with Print method
289 object [] customAttrs = myType.GetCustomAttributes (false);
290 Assert.AreEqual (customAttrs.Length , 1, "#1");
292 //Custom Attributes of TestType
293 CustomAttribute attr = customAttrs [0] as CustomAttribute;
294 Assert.AreEqual(attr.AttributeOne, "TestCase", "#2");
297 [Test]
298 public void CtorFourTest ()
300 //test for the constructor with signature--
301 //public CustomAttributeBuilder(ConstructorInfo, object[], PropertyInfo[], object[], FieldInfo[], object[]);
303 * WE build a imaginary type as follows
304 * [CustomAttribute()]
305 * public class TestType
309 * We also set the "AttributeOne" property ,
310 * and "Feild" of class CustomAttribute
311 * by means of the constuctor of CustomAttributeBuilder
312 * And then check for the validity
315 AssemblyName asmName = new AssemblyName ();
316 asmName.Name = "TestAssembly.dll";
318 AssemblyBuilder asmBuilder = Thread.GetDomain ().DefineDynamicAssembly (
319 asmName , AssemblyBuilderAccess.Run);
321 ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule ("TestModule");
323 TypeBuilder typeBuilder = modBuilder.DefineType ("TestType",
324 TypeAttributes.Public);
326 Type [] ctorParams = new Type [] { };
328 ConstructorInfo classCtorInfo =
329 typeof (CustomAttribute).GetConstructor (ctorParams);
331 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder(
332 classCtorInfo,
333 new object [] { },
334 new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
335 new object [] { "TestCase" },
336 typeof(CustomAttribute).GetFields (),
337 new object [] { "FieldValue" }
340 typeBuilder.SetCustomAttribute (typeCABuilder);
342 // create the type
343 Type myType = typeBuilder.CreateType ();
345 //Now check for the validity of the attributes.
346 object testInstance = Activator.CreateInstance (myType);
348 //check the validity of the attribute associated with Print method
349 object [] customAttrs = myType.GetCustomAttributes (false);
350 Assert.AreEqual(customAttrs.Length , 1, "#1");
352 //Custom Attributes of TestType
353 CustomAttribute attr = customAttrs [0] as CustomAttribute;
354 Assert.AreEqual (attr.AttributeOne, "TestCase", "#2");
355 Assert.AreEqual (attr.Feild, "FieldValue", "#3");
359 [Test]
360 [ExpectedException (typeof (ArgumentException))]
361 public void ArgumentExceptionTest_1 ()
363 //here the constructor is static
365 Type [] ctorParams = new Type [] { };
367 ConstructorInfo classCtorInfo =
368 typeof (CustomAttribute).GetConstructor (BindingFlags.Static | BindingFlags.NonPublic,
369 null, ctorParams, null);
371 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
372 classCtorInfo,
373 new object [] { },
374 new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
375 new object [] { "TestCase" },
376 typeof (CustomAttribute).GetFields (),
377 new object [] { "FieldValue" }
382 [Test]
383 [ExpectedException (typeof (ArgumentException))]
384 public void ArgumentExceptionTest_2 ()
386 //here the consturctor is private
388 Type [] ctorParams = new Type[] {typeof(string) };
390 ConstructorInfo classCtorInfo =
391 typeof (CustomAttribute).GetConstructor (BindingFlags.Instance |
392 BindingFlags.NonPublic, null, ctorParams, null);
394 Assert.IsNotNull (classCtorInfo);
396 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
397 classCtorInfo,
398 new object [] { "hello" },
399 new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
400 new object [] { "TestCase" },
401 typeof (CustomAttribute).GetFields (),
402 new object [] { "FieldValue" }
407 [Test]
408 [ExpectedException (typeof (ArgumentException))]
409 public void ArgumentExceptionTest_3 ()
411 // The lengths of the namedProperties and
412 //propertyValues arrays are different.
414 Type [] ctorParams = new Type [] { };
416 ConstructorInfo classCtorInfo =
417 typeof (CustomAttribute).GetConstructor (ctorParams);
419 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
420 classCtorInfo,
421 new object [] { },
422 new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
423 new object [] { "TestCase","extra arg" },//<--here is the error
424 typeof (CustomAttribute).GetFields (),
425 new object [] { "FieldValue" }
430 [Test]
431 [ExpectedException (typeof (ArgumentException))]
432 public void ArgumentExceptionTest_4()
434 //The length of the namedFields and
435 //namedValues are different
437 Type [] ctorParams = new Type [] { };
439 ConstructorInfo classCtorInfo =
440 typeof (CustomAttribute).GetConstructor (ctorParams);
442 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
443 classCtorInfo,
444 new object [] { },
445 new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
446 new object [] { "TestCase" },
447 typeof (CustomAttribute).GetFields (),
448 new object [] { }//<--here is the error
453 [Test]
454 [ExpectedException (typeof (ArgumentException))]
455 public void ArgumentExceptionTest_6 ()
457 //The type of supplied argument does not
458 //match the type of the parameter declared
459 //in the constructor.
461 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
463 ConstructorInfo classCtorInfo =
464 typeof (CustomAttribute).GetConstructor (ctorParams);
466 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
467 classCtorInfo,
468 new object [] { "1", 123 },//<--here is the error,(int instead of string)
469 new PropertyInfo[]{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
470 new object [] { "TestCase" },
471 typeof (CustomAttribute).GetFields (),
472 new object [] { "FeildValue" }
477 [Test]
478 [ExpectedException (typeof (ArgumentException))]
479 public void ArgumentExceptionTest_7 ()
481 //A property has no setter.(CustomAttribute.AttributeTwo)
483 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
485 ConstructorInfo classCtorInfo =
486 typeof (CustomAttribute).GetConstructor (ctorParams);
488 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
489 classCtorInfo,
490 new object [] { "1","2" },
491 new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeTwo") },
492 new object [] { "TestCase" },
493 typeof (CustomAttribute).GetFields (),
494 new object [] { "FeildValue" }
499 [Test]
500 [ExpectedException (typeof (ArgumentException))]
501 public void ArgumentExceptionTest_8 ()
503 //A property doesnot belong to same class
505 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
507 ConstructorInfo classCtorInfo =
508 typeof (CustomAttribute).GetConstructor (ctorParams);
510 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
511 classCtorInfo,
512 new object [] { "1","2" },
513 new PropertyInfo [] { typeof (TempClass).GetProperty ("FieldProperty")}, //here is the error
514 new object [] { "TestCase" },
515 typeof (CustomAttribute).GetFields (),
516 new object [] { "FeildValue" }
521 [Test]
522 [ExpectedException (typeof (ArgumentException))]
523 public void ArgumentExceptionTest_9 ()
525 //A field doesnot belong to same class
527 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
529 ConstructorInfo classCtorInfo =
530 typeof (CustomAttribute).GetConstructor (ctorParams);
532 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
533 classCtorInfo,
534 new object [] { "1","2" },
535 new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
536 new object [] {"TestCase"},
537 typeof (TempClass).GetFields (), //<-- fields of TempClass are passed
538 new object [] { "FeildValue" }
543 [Test]
544 [ExpectedException (typeof (ArgumentException))]
545 public void ArgumentExceptionTest_10 ()
547 //The types of the property values do
548 //not match the types of the named properties.
551 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
553 ConstructorInfo classCtorInfo =
554 typeof (CustomAttribute).GetConstructor (ctorParams);
556 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
557 classCtorInfo,
558 new object [] { "1","2" },
559 new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
560 new object [] { (long)1212121212 }, //<---type mismatch error(long for string)
561 typeof (CustomAttribute).GetFields (),
562 new object [] { "FeildValue" }
567 [Test]
568 [ExpectedException (typeof (ArgumentException))]
569 public void ArgumentExceptionTest_11 ()
571 //The types of the field values do
572 //not match the types of the named properties.
574 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
576 ConstructorInfo classCtorInfo =
577 typeof (CustomAttribute).GetConstructor (ctorParams);
579 Assert.IsNotNull (classCtorInfo);
580 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
581 classCtorInfo,
582 new object [] { "1","2" },
583 new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
584 new object [] { "One" },
585 typeof (CustomAttribute).GetFields (),
586 new object []{ 12.1212 } //<---type mismatch error(double for string)
591 [Test]
592 [ExpectedException (typeof (ArgumentNullException))]
593 public void ArgumentNullException_1 ()
595 //the ctor value array (2nd argument) is null
596 Type [] ctorParams = new Type [] { typeof (string),typeof (string) };
598 ConstructorInfo classCtorInfo =
599 typeof (CustomAttribute).GetConstructor (ctorParams);
601 Assert.IsNotNull (classCtorInfo);
602 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
603 classCtorInfo,
604 null, //<-- here is the error
605 new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
606 new object [] { "One" },
607 typeof (CustomAttribute).GetFields (),
608 new object [] { "feild" }
613 [Test]
614 [ExpectedException (typeof (ArgumentNullException))]
615 public void ArgumentNullException_2 ()
617 //the property value array (4th argument) is null
618 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
620 ConstructorInfo classCtorInfo =
621 typeof (CustomAttribute).GetConstructor (ctorParams);
623 Assert.IsNotNull (classCtorInfo);
624 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
625 classCtorInfo,
626 new object [] { "one","two" },
627 new PropertyInfo []{ typeof (CustomAttribute).GetProperty ("AttributeOne") },
628 null, // <-- here is the error
629 typeof (CustomAttribute).GetFields (),
630 new object [] { "feild" }
635 [Test]
636 [ExpectedException (typeof (ArgumentNullException))]
637 public void ArgumentNullException_3 ()
639 //the field value array (6th argument) is null
640 Type [] ctorParams = new Type [] { typeof (string), typeof (string) };
642 ConstructorInfo classCtorInfo =
643 typeof (CustomAttribute).GetConstructor (ctorParams);
645 Assert.IsNotNull (classCtorInfo);
646 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
647 classCtorInfo,
648 new object [] { "one","two" },
649 new PropertyInfo [] { typeof (CustomAttribute).GetProperty ("AttributeOne") },
650 new object [] {"property"},
651 typeof (CustomAttribute).GetFields (),
652 null // <-- here is the error
656 class C {
657 public C (object i) {
661 [Test]
662 [ExpectedException (typeof (ArgumentException))]
663 public void ObjectParam_UserDefinedClass ()
665 var cab = new CustomAttributeBuilder(
666 typeof (C).GetConstructors ()[0],
667 new object[] { new C (1) });
671 [Test]
672 [ExpectedException (typeof (ArgumentException))]
673 public void ValueTypeParam_Null ()
675 ConstructorInfo classCtorInfo =
676 typeof (CattrD).GetConstructors ()[0];
678 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
679 classCtorInfo, new object [] { null });
682 [Test]
683 [ExpectedException (typeof (ArgumentException))]
684 public void ValueTypeArrayParam_Null ()
686 ConstructorInfo classCtorInfo =
687 typeof (CattrE).GetConstructors ()[0];
689 CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder (
690 classCtorInfo, new object [] { new object[] { null } });
693 public class CattrD : Attribute
695 public CattrD (bool b) {}
698 public class CattrE : Attribute
700 public CattrE (bool[] b) {}
703 public class JaggedAttr : Attribute {
704 public static string[][] Data { get; set; }
706 public JaggedAttr (string[][] data) {
707 Data = data;
711 [Test]
712 public void JaggedArrays () {
713 var ab = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("Foo"), AssemblyBuilderAccess.Save, tempDir);
714 var modb = ab.DefineDynamicModule ("Foo", "Foo.dll");
715 var tb = modb.DefineType ("T");
716 tb.SetCustomAttribute (new
717 CustomAttributeBuilder(typeof (JaggedAttr).GetConstructors ()[0],
718 new object[] { new string[][] { new string[] { "foo" }, new string[] { "bar" } } }));
719 tb.CreateType ();
720 ab.Save ("Foo.dll");
722 string assemblyPath = Path.Combine (tempDir, "Foo.dll");
723 Type t = Assembly.LoadFrom (assemblyPath).GetType ("T");
724 Assert.AreEqual (1, t.GetCustomAttributes (false).Length);
726 string[][] res = JaggedAttr.Data;
727 Assert.AreEqual (2, res.Length);
728 Assert.AreEqual ("foo", res [0][0]);
729 Assert.AreEqual ("bar", res [1][0]);
732 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
733 internal class NonVisibleCustomAttribute : Attribute
735 public NonVisibleCustomAttribute () {}
738 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
739 public class PublicVisibleCustomAttribute : Attribute
741 public PublicVisibleCustomAttribute () {}
744 private static void AddCustomClassAttribute (TypeBuilder typeBuilder, Type customAttrType)
746 var attribCtorParams = new Type[] {};
747 var attribCtorInfo = customAttrType.GetConstructor(attribCtorParams);
748 var attribBuilder = new CustomAttributeBuilder(attribCtorInfo, new object[] { });
749 typeBuilder.SetCustomAttribute(attribBuilder);
752 [Test]
753 public void NonvisibleCustomAttribute () {
755 // We build:
756 // [VisiblePublicCustom]
757 // [VisiblePublicCustom]
758 // [NonVisibleCustom]
759 // [VisiblePublicCustom]
760 // class BuiltType { public BuiltType () { } }
762 // And then we try to get all the attributes.
764 // Regression test for https://bugzilla.xamarin.com/show_bug.cgi?id=43291
765 var assemblyName = new AssemblyName("Repro43291Asm");
766 var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
767 var moduleBuilder = assemblyBuilder.DefineDynamicModule("Repro43291Mod");
769 var typeBuilder = moduleBuilder.DefineType("BuiltType",
770 TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.BeforeFieldInit);
772 AddCustomClassAttribute (typeBuilder, typeof (PublicVisibleCustomAttribute));
773 AddCustomClassAttribute (typeBuilder, typeof (PublicVisibleCustomAttribute));
774 AddCustomClassAttribute (typeBuilder, typeof (NonVisibleCustomAttribute));
775 AddCustomClassAttribute (typeBuilder, typeof (PublicVisibleCustomAttribute));
777 var createdType = typeBuilder.CreateType ();
779 Assert.IsNotNull (createdType);
781 var obj = Activator.CreateInstance (createdType);
783 Assert.IsNotNull (obj);
785 var attrs = obj.GetType ().GetCustomAttributes (typeof (Attribute), true);
787 Assert.IsNotNull (attrs);
789 Assert.AreEqual (3, attrs.Length);
790 Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[0]);
791 Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[1]);
792 Assert.IsInstanceOfType (typeof (PublicVisibleCustomAttribute), attrs[2]);
795 [Test]
796 public void CustomAttributeSameAssembly () {
797 // Regression test for 55681
799 // We build:
800 // class MyAttr : Attr { public MyAttr () { } }
801 // [assembly:MyAttr()]
803 // the important bit is that we pass the ConstructorBuilder to the CustomAttributeBuilder
804 var assemblyName = new AssemblyName ("Repro55681");
805 var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.Save, tempDir);
806 var moduleBuilder = assemblyBuilder.DefineDynamicModule ("Repro55681", "Repro55681.dll");
807 var typeBuilder = moduleBuilder.DefineType ("MyAttr", TypeAttributes.Public, typeof (Attribute));
808 ConstructorBuilder ctor = typeBuilder.DefineDefaultConstructor (MethodAttributes.Public);
809 typeBuilder.CreateType ();
811 assemblyBuilder.SetCustomAttribute (new CustomAttributeBuilder (ctor, new object [] { }));
813 assemblyBuilder.Save ("Repro55681.dll");
816 [Test]
817 public void CustomAttributeAcrossAssemblies () {
818 // Regression test for 55681
820 // We build:
821 // assembly1:
822 // class MyAttr : Attr { public MyAttr () { } }
823 // assembly2:
824 // class Dummy { }
825 // [assembly:MyAttr()]
827 // the important bit is that we pass the ConstructorBuilder to the CustomAttributeBuilder
828 var assemblyName1 = new AssemblyName ("Repro55681-2a");
829 var assemblyBuilder1 = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName1, AssemblyBuilderAccess.Save, tempDir);
830 var moduleBuilder1 = assemblyBuilder1.DefineDynamicModule ("Repro55681-2a", "Repro55681-2a.dll");
831 var typeBuilder1 = moduleBuilder1.DefineType ("MyAttr", TypeAttributes.Public, typeof (Attribute));
832 ConstructorBuilder ctor = typeBuilder1.DefineDefaultConstructor (MethodAttributes.Public);
833 typeBuilder1.CreateType ();
835 var assemblyName2 = new AssemblyName ("Repro55681-2b");
836 var assemblyBuilder2 = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName2, AssemblyBuilderAccess.Save, tempDir);
837 var moduleBuilder2 = assemblyBuilder2.DefineDynamicModule ("Repro55681-2b", "Repro55681-2b.dll");
839 var typeBuilder2 = moduleBuilder2.DefineType ("Dummy", TypeAttributes.Public);
840 typeBuilder2.DefineDefaultConstructor (MethodAttributes.Public);
841 typeBuilder2.CreateType ();
843 assemblyBuilder2.SetCustomAttribute (new CustomAttributeBuilder (ctor, new object [] { }));
845 assemblyBuilder2.Save ("Repro55681-2b.dll");
846 assemblyBuilder1.Save ("Repro55681-2a.dll");
849 [DllImport("SomeLib")]
850 private static extern void MethodForNullStringMarshalAsFields([MarshalAs(UnmanagedType.LPWStr)] string param);
852 [Test]
853 public void NullStringMarshalAsFields () {
854 // Regression test for https://github.com/mono/mono/issues/12747
856 // MarshalAsAttribute goes through
857 // CustomAttributeBuilder.get_umarshal which tries to
858 // build an UnmanagedMarshal value by decoding the CAB's data.
860 // The data decoding needs to handle null string (encoded as 0xFF) properly.
861 var aName = new AssemblyName("Repro12747");
862 var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave, tempDir);
863 var module = assembly.DefineDynamicModule(aName.Name, aName.Name + ".dll");
865 var prototypeMethodName = nameof(MethodForNullStringMarshalAsFields);
866 var someMethod = this.GetType().GetMethod(prototypeMethodName, BindingFlags.Static | BindingFlags.NonPublic);
868 var typeBuilder = module.DefineType("NewType" + module.ToString(), TypeAttributes.Class | TypeAttributes.Public);
869 var methodBuilder = typeBuilder.DefineMethod("NewMethod", MethodAttributes.Public | MethodAttributes.HideBySig, typeof(void), new[] { typeof(string) });
870 var il = methodBuilder.GetILGenerator();
871 il.Emit(OpCodes.Ret);
873 var param = someMethod.GetParameters()[0];
874 var paramBuilder = methodBuilder.DefineParameter(1, param.Attributes, null);
875 MarshalAsAttribute attr = param.GetCustomAttribute<MarshalAsAttribute>();
876 var attrCtor = typeof(MarshalAsAttribute).GetConstructor(new[] { typeof(UnmanagedType) });
877 object[] attrCtorArgs = { attr.Value };
879 // copy over the fields from the real MarshalAsAttribute on the parameter of "MethodForNullStringMarshalAsFields",
880 // including the ones that were initialized to null
881 var srcFields = typeof(MarshalAsAttribute).GetFields(BindingFlags.Public | BindingFlags.Instance);
882 var fieldArguments = new FieldInfo[srcFields.Length];
883 var fieldArgumentValues = new object[srcFields.Length];
884 for(int i = 0; i < srcFields.Length; i++)
886 var field = srcFields[i];
887 fieldArguments[i] = field;
888 fieldArgumentValues[i] = field.GetValue(attr);
891 var attrBuilder = new CustomAttributeBuilder(attrCtor, attrCtorArgs, Array.Empty<PropertyInfo>(), Array.Empty<object>(),
892 fieldArguments, fieldArgumentValues);
893 // this encodes the CustomAttributeBuilder as a data
894 // blob and then tries to decode it using
895 // CustomAttributeBuilder.get_umarshal
896 paramBuilder.SetCustomAttribute(attrBuilder);
898 var finalType = typeBuilder.CreateType();