1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using System.Globalization; 7 using System.Linq; 8 using Xunit; 9 10 namespace System.Reflection.Tests 11 { 12 public static class BindingFlagsDoNotWrapTests 13 { 14 [Fact] MethodInvoke()15 public static void MethodInvoke() 16 { 17 MethodInfo m = typeof(TestClass).GetMethod(nameof(TestClass.Moo), BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); 18 TestDoNotWrap<MyException1>((bf) => m.Invoke(null, bf, null, Array.Empty<object>(), null)); 19 } 20 21 [Fact] ConstructorInvoke()22 public static void ConstructorInvoke() 23 { 24 ConstructorInfo c = typeof(TestClass).GetConstructor(BindingFlags.Public|BindingFlags.Instance, null, Array.Empty<Type>(), null); 25 TestDoNotWrap<MyException2>((bf) => c.Invoke(bf, null, Array.Empty<object>(), null)); 26 } 27 28 [Fact] ConstructorInvokeStringCtor()29 public static void ConstructorInvokeStringCtor() 30 { 31 // Code coverage: Project N - String constructors go through a separate code path. 32 ConstructorInfo c = typeof(string).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(char[]), typeof(int), typeof(int) }, null); 33 TestDoNotWrap<ArgumentNullException>((bf) => c.Invoke(bf, null, new object[] { null, 0, 0 }, null)); 34 } 35 36 [Fact] ConstructorInvokeUsingMethodInfoInvoke()37 public static void ConstructorInvokeUsingMethodInfoInvoke() 38 { 39 ConstructorInfo c = typeof(TestClass).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Array.Empty<Type>(), null); 40 TestDoNotWrap<MyException2>((bf) => c.Invoke(new TestClass(0), bf, null, Array.Empty<object>(), null)); 41 } 42 43 [Fact] PropertyGet()44 public static void PropertyGet() 45 { 46 PropertyInfo p = typeof(TestClass).GetProperty(nameof(TestClass.MyProperty)); 47 TestDoNotWrap<MyException3>((bf) => p.GetValue(null, bf, null, null, null)); 48 } 49 50 [Fact] PropertySet()51 public static void PropertySet() 52 { 53 PropertyInfo p = typeof(TestClass).GetProperty(nameof(TestClass.MyProperty)); 54 TestDoNotWrap<MyException4>((bf) => p.SetValue(null, 42, bf, null, null, null)); 55 } 56 57 [Fact] InvokeMember_Method()58 public static void InvokeMember_Method() 59 { 60 Type t = typeof(TestClass); 61 const BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.InvokeMethod; 62 TestDoNotWrap<MyException1>((bf) => t.InvokeMember(nameof(TestClass.Moo), bf | flags, null, null, Array.Empty<object>(), null, null, null)); 63 } 64 65 [Fact] InvokeMember_PropertyGet()66 public static void InvokeMember_PropertyGet() 67 { 68 Type t = typeof(TestClass); 69 const BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.GetProperty; 70 TestDoNotWrap<MyException3>((bf) => t.InvokeMember(nameof(TestClass.MyProperty), bf | flags, null, null, Array.Empty<object>(), null, null, null)); 71 } 72 73 [Fact] InvokeMember_PropertySet()74 public static void InvokeMember_PropertySet() 75 { 76 Type t = typeof(TestClass); 77 const BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.SetProperty; 78 TestDoNotWrap<MyException4>((bf) => t.InvokeMember(nameof(TestClass.MyProperty), bf | flags, null, null, new object[] { 42 }, null, null, null)); 79 } 80 81 [Fact] ActivatorCreateInstance()82 public static void ActivatorCreateInstance() 83 { 84 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; 85 TestDoNotWrap<MyException2>((bf) => Activator.CreateInstance(typeof(TestClass), bf | flags, null, Array.Empty<object>(), null, null)); 86 } 87 88 [Fact] ActivatorCreateInstanceOneArgument()89 public static void ActivatorCreateInstanceOneArgument() 90 { 91 // For code coverage on CoreCLR: Activator.CreateInstance with parameters uses different code path from one without parameters. 92 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; 93 TestDoNotWrap<MyException5>((bf) => Activator.CreateInstance(typeof(TestClass), bf | flags, null, new object[] { "Hello" }, null, null)); 94 } 95 96 [Fact] ActivatorCreateInstanceCaching()97 public static void ActivatorCreateInstanceCaching() 98 { 99 // For code coverage on CoreCLR: Activator.CreateInstance - second call after non-throwing call goes through a different path 100 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; 101 TestClassConditional.ThrowInConstructor = true; 102 TestDoNotWrap<MyException6>((bf) => Activator.CreateInstance(typeof(TestClassConditional), bf | flags, null, Array.Empty<object>(), null, null)); 103 104 TestClassConditional.ThrowInConstructor = false; 105 Assert.True(Activator.CreateInstance(typeof(TestClassConditional), flags, null, Array.Empty<object>(), null, null) is TestClassConditional); 106 107 TestClassConditional.ThrowInConstructor = true; 108 TestDoNotWrap<MyException6>((bf) => Activator.CreateInstance(typeof(TestClassConditional), bf | flags, null, Array.Empty<object>(), null, null)); 109 } 110 111 [Fact] ActivatorCreateInstance_BadCCtor()112 public static void ActivatorCreateInstance_BadCCtor() 113 { 114 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; 115 TestDoNotWrap<TypeInitializationException>((bf) => Activator.CreateInstance(typeof(TestClassBadCCtor), bf | flags, null, Array.Empty<object>(), null, null)); 116 } 117 118 [Fact] AssemblyCreateInstance()119 public static void AssemblyCreateInstance() 120 { 121 Assembly a = typeof(TestClass).Assembly; 122 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; 123 TestDoNotWrap<MyException2>((bf) => a.CreateInstance(typeof(TestClass).FullName, false, bf | flags, null, Array.Empty<object>(), null, null)); 124 } 125 126 [Fact] AssemblyCreateInstance_BadCCtor()127 public static void AssemblyCreateInstance_BadCCtor() 128 { 129 Assembly a = typeof(TestClass).Assembly; 130 const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; 131 TestDoNotWrap<TypeInitializationException>((bf) => a.CreateInstance(typeof(TestClassBadCCtor).FullName, false, bf | flags, null, Array.Empty<object>(), null, null)); 132 } 133 134 private static void TestDoNotWrap<T>(Action<BindingFlags> action) where T : Exception 135 { 136 Assert.Throws<T>(() => action(BindingFlags.DoNotWrapExceptions)); 137 TargetInvocationException tie = Assert.Throws<TargetInvocationException>(() => action(default(BindingFlags))); 138 Assert.Equal(typeof(T), tie.InnerException.GetType()); 139 } 140 141 private sealed class TestClass 142 { TestClass()143 public TestClass() => throw new MyException2(); TestClass(int _)144 public TestClass(int _) { } TestClass(string s)145 public TestClass(string s) => throw new MyException5(); Moo()146 public static void Moo() => throw new MyException1(); 147 public static int MyProperty { get { throw new MyException3(); } set { throw new MyException4(); } } 148 } 149 150 public sealed class TestClassBadCCtor 151 { TestClassBadCCtor()152 public TestClassBadCCtor() { } 153 TestClassBadCCtor()154 static TestClassBadCCtor() 155 { 156 throw new MyException1(); 157 } 158 } 159 160 private sealed class TestClassConditional 161 { TestClassConditional()162 public TestClassConditional() { if (ThrowInConstructor) throw new MyException6(); } 163 164 public static bool ThrowInConstructor; 165 } 166 167 private sealed class MyException1 : Exception { } 168 private sealed class MyException2 : Exception { } 169 private sealed class MyException3 : Exception { } 170 private sealed class MyException4 : Exception { } 171 private sealed class MyException5 : Exception { } 172 private sealed class MyException6 : Exception { } 173 } 174 } 175