Merge pull request #3262 from lindenlab/add_continuations_test
[mono.git] / mcs / class / Facades / System.Reflection.TypeExtensions / TypeExtensions.CoreCLR.cs
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 // NOTE: These are extension methods in the contract, but plain static methods
6 // in this implementation. This is done to avoid confusion around what would 
7 // look like infinite recursion in the implementation. Callers compiled against
8 // the contract will still be able to invoke them as extension methods and get
9 // source compatibility with classic reflection code.
10 //
11 // However, this does not apply if there is no 1:1 correspondence with an instance
12 // in mscorlib. New extension methods should be marked with 'this'.
13
14 namespace System.Reflection
15 {
16     public static class TypeExtensions
17     {
18         public static ConstructorInfo GetConstructor(Type type, Type[] types)
19         {
20             Requires.NotNull(type, nameof(type));
21             return type.GetConstructor(types);
22         }
23
24         public static ConstructorInfo[] GetConstructors(Type type)
25         {
26             Requires.NotNull(type, nameof(type));
27             return type.GetConstructors();
28         }
29
30         public static ConstructorInfo[] GetConstructors(Type type, BindingFlags bindingAttr)
31         {
32             Requires.NotNull(type, nameof(type));
33             return type.GetConstructors(bindingAttr);
34         }
35
36         public static MemberInfo[] GetDefaultMembers(Type type)
37         {
38             Requires.NotNull(type, nameof(type));
39             return type.GetDefaultMembers();
40         }
41
42         public static EventInfo GetEvent(Type type, string name)
43         {
44             Requires.NotNull(type, nameof(type));
45             return type.GetEvent(name);
46         }
47
48         public static EventInfo GetEvent(Type type, string name, BindingFlags bindingAttr)
49         {
50             Requires.NotNull(type, nameof(type));
51             return type.GetEvent(name, bindingAttr);
52         }
53
54         public static EventInfo[] GetEvents(Type type)
55         {
56             Requires.NotNull(type, nameof(type));
57             return type.GetEvents();
58         }
59
60         public static EventInfo[] GetEvents(Type type, BindingFlags bindingAttr)
61         {
62             Requires.NotNull(type, nameof(type));
63             return type.GetEvents(bindingAttr);
64         }
65
66         public static FieldInfo GetField(Type type, string name)
67         {
68             Requires.NotNull(type, nameof(type));
69             return type.GetField(name);
70         }
71
72         public static FieldInfo GetField(Type type, string name, BindingFlags bindingAttr)
73         {
74             Requires.NotNull(type, nameof(type));
75             return type.GetField(name, bindingAttr);
76         }
77
78         public static FieldInfo[] GetFields(Type type)
79         {
80             Requires.NotNull(type, nameof(type));
81             return type.GetFields();
82         }
83
84         public static FieldInfo[] GetFields(Type type, BindingFlags bindingAttr)
85         {
86             Requires.NotNull(type, nameof(type));
87             return type.GetFields(bindingAttr);
88         }
89
90         public static Type[] GetGenericArguments(Type type)
91         {
92             Requires.NotNull(type, nameof(type));
93             return type.GetGenericArguments();
94         }
95
96         public static Type[] GetInterfaces(Type type)
97         {
98             Requires.NotNull(type, nameof(type));
99             return type.GetInterfaces();
100         }
101
102         public static MemberInfo[] GetMember(Type type, string name)
103         {
104             Requires.NotNull(type, nameof(type));
105             return type.GetMember(name);
106         }
107
108         public static MemberInfo[] GetMember(Type type, string name, BindingFlags bindingAttr)
109         {
110             Requires.NotNull(type, nameof(type));
111             return type.GetMember(name, bindingAttr);
112         }
113
114         public static MemberInfo[] GetMembers(Type type)
115         {
116             Requires.NotNull(type, nameof(type));
117             return type.GetMembers();
118         }
119
120         public static MemberInfo[] GetMembers(Type type, BindingFlags bindingAttr)
121         {
122             Requires.NotNull(type, nameof(type));
123             return type.GetMembers(bindingAttr);
124         }
125
126         public static MethodInfo GetMethod(Type type, string name)
127         {
128             Requires.NotNull(type, nameof(type));
129             return type.GetMethod(name);
130         }
131
132         public static MethodInfo GetMethod(Type type, string name, BindingFlags bindingAttr)
133         {
134             Requires.NotNull(type, nameof(type));
135             return type.GetMethod(name, bindingAttr);
136         }
137
138         public static MethodInfo GetMethod(Type type, string name, Type[] types)
139         {
140             Requires.NotNull(type, nameof(type));
141             return type.GetMethod(name, types);
142         }
143
144         public static MethodInfo[] GetMethods(Type type)
145         {
146             Requires.NotNull(type, nameof(type));
147             return type.GetMethods();
148         }
149
150         public static MethodInfo[] GetMethods(Type type, BindingFlags bindingAttr)
151         {
152             Requires.NotNull(type, nameof(type));
153             return type.GetMethods(bindingAttr);
154         }
155
156         public static Type GetNestedType(Type type, string name, BindingFlags bindingAttr)
157         {
158             Requires.NotNull(type, nameof(type));
159             return type.GetNestedType(name, bindingAttr);
160         }
161
162         public static Type[] GetNestedTypes(Type type, BindingFlags bindingAttr)
163         {
164             Requires.NotNull(type, nameof(type));
165             return type.GetNestedTypes(bindingAttr);
166         }
167
168         public static PropertyInfo[] GetProperties(Type type)
169         {
170             Requires.NotNull(type, nameof(type));
171             return type.GetProperties();
172         }
173
174         public static PropertyInfo[] GetProperties(Type type, BindingFlags bindingAttr)
175         {
176             Requires.NotNull(type, nameof(type));
177             return type.GetProperties(bindingAttr);
178         }
179
180         public static PropertyInfo GetProperty(Type type, string name)
181         {
182             Requires.NotNull(type, nameof(type));
183             return type.GetProperty(name);
184         }
185
186         public static PropertyInfo GetProperty(Type type, string name, BindingFlags bindingAttr)
187         {
188             Requires.NotNull(type, nameof(type));
189             return type.GetProperty(name, bindingAttr);
190         }
191
192         public static PropertyInfo GetProperty(Type type, string name, Type returnType)
193         {
194             Requires.NotNull(type, nameof(type));
195             return type.GetProperty(name, returnType);
196         }
197
198         public static PropertyInfo GetProperty(Type type, string name, Type returnType, Type[] types)
199         {
200             Requires.NotNull(type, nameof(type));
201             return type.GetProperty(name, returnType, types);
202         }
203
204         public static bool IsAssignableFrom(Type type, Type c)
205         {
206             Requires.NotNull(type, nameof(type));
207             return type.IsAssignableFrom(c);
208         }
209
210         public static bool IsInstanceOfType(Type type, object o)
211         {
212             Requires.NotNull(type, nameof(type));
213             return type.IsInstanceOfType(o);
214         }
215     }
216
217     public static class AssemblyExtensions
218     {
219         public static Type[] GetExportedTypes(Assembly assembly)
220         {
221             Requires.NotNull(assembly, nameof(assembly));
222             return assembly.GetExportedTypes();
223         }
224
225         public static Module[] GetModules(Assembly assembly)
226         {
227             Requires.NotNull(assembly, nameof(assembly));
228             return assembly.GetModules();
229         }
230
231         public static Type[] GetTypes(Assembly assembly)
232         {
233             Requires.NotNull(assembly, nameof(assembly));
234             return assembly.GetTypes();
235         }
236     }
237
238     public static class EventInfoExtensions
239     {
240         public static MethodInfo GetAddMethod(EventInfo eventInfo)
241         {
242             Requires.NotNull(eventInfo, nameof(eventInfo));
243             return eventInfo.GetAddMethod();
244         }
245
246         public static MethodInfo GetAddMethod(EventInfo eventInfo, bool nonPublic)
247         {
248             Requires.NotNull(eventInfo, nameof(eventInfo));
249             return eventInfo.GetAddMethod(nonPublic);
250         }
251
252         public static MethodInfo GetRaiseMethod(EventInfo eventInfo)
253         {
254             Requires.NotNull(eventInfo, nameof(eventInfo));
255             return eventInfo.GetRaiseMethod();
256         }
257
258         public static MethodInfo GetRaiseMethod(EventInfo eventInfo, bool nonPublic)
259         {
260             Requires.NotNull(eventInfo, nameof(eventInfo));
261             return eventInfo.GetRaiseMethod(nonPublic);
262         }
263
264         public static MethodInfo GetRemoveMethod(EventInfo eventInfo)
265         {
266             Requires.NotNull(eventInfo, nameof(eventInfo));
267             return eventInfo.GetRemoveMethod();
268         }
269
270         public static MethodInfo GetRemoveMethod(EventInfo eventInfo, bool nonPublic)
271         {
272             Requires.NotNull(eventInfo, nameof(eventInfo));
273             return eventInfo.GetRemoveMethod(nonPublic);
274         }
275     }
276
277     public static class MemberInfoExtensions
278     {
279
280         /// <summary>
281         /// Determines if there is a metadata token available for the given member.
282         /// <see cref="GetMetadataToken(MemberInfo)"/> throws <see cref="InvalidOperationException"/> otherwise.
283         /// </summary>
284         /// <remarks>This maybe</remarks>
285         public static bool HasMetadataToken(this MemberInfo member)
286         {
287             Requires.NotNull(member, nameof(member));
288
289             try
290             {
291                 return GetMetadataTokenOrZeroOrThrow(member) != 0;
292             }
293             catch (InvalidOperationException)
294             {
295                 // Thrown for unbaked ref-emit members/types. 
296                 // Other cases such as typeof(byte[]).MetadataToken will be handled by comparison to zero above.
297                 return false;
298             }
299         }
300
301         /// <summary>
302         /// Gets a metadata token for the given member if available. The returned token is never nil.
303         /// </summary>
304         /// <exception cref="InvalidOperationException">
305         /// There is no metadata token available. <see cref="HasMetadataToken(MemberInfo)"/> returns false in this case.
306         /// </exception>
307         public static int GetMetadataToken(this MemberInfo member)
308         {
309             Requires.NotNull(member, nameof(member));
310
311             int token = GetMetadataTokenOrZeroOrThrow(member); 
312
313             if (token == 0)
314             {
315                 throw new InvalidOperationException(SR.NoMetadataTokenAvailable);
316             }
317
318             return token;
319         }
320
321         private static int GetMetadataTokenOrZeroOrThrow(MemberInfo member)
322         {
323             int token = member.MetadataToken;
324
325             // Tokens have MSB = table index, 3 LSBs = row index
326             // row index of 0 is a nil token 
327             const int rowMask = 0x00FFFFFF;
328             if ((token & rowMask) == 0)
329             {
330                 // Nil token is returned for edge cases like typeof(byte[]).MetadataToken.
331                 return 0;
332             }
333
334             return token;
335          }
336     }
337
338     public static class MethodInfoExtensions
339     {
340         public static MethodInfo GetBaseDefinition(MethodInfo method)
341         {
342             Requires.NotNull(method, nameof(method));
343             return method.GetBaseDefinition();
344         }
345     }
346
347     public static class ModuleExtensions
348     {
349         public static bool HasModuleVersionId(this Module module)
350         {
351             Requires.NotNull(module, nameof(module));
352             return true; // not expected to fail on platforms with Module.ModuleVersionId built-in.
353         }
354
355         public static Guid GetModuleVersionId(this Module module)
356         {
357             Requires.NotNull(module, nameof(module));
358             return module.ModuleVersionId;
359         }
360     }
361
362     public static class PropertyInfoExtensions
363     {
364         public static MethodInfo[] GetAccessors(PropertyInfo property)
365         {
366             Requires.NotNull(property, nameof(property));
367             return property.GetAccessors();
368         }
369
370         public static MethodInfo[] GetAccessors(PropertyInfo property, bool nonPublic)
371         {
372             Requires.NotNull(property, nameof(property));
373             return property.GetAccessors(nonPublic);
374         }
375
376         public static MethodInfo GetGetMethod(PropertyInfo property)
377         {
378             Requires.NotNull(property, nameof(property));
379             return property.GetGetMethod();
380         }
381
382         public static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic)
383         {
384             Requires.NotNull(property, nameof(property));
385             return property.GetGetMethod(nonPublic);
386         }
387
388         public static MethodInfo GetSetMethod(PropertyInfo property)
389         {
390             Requires.NotNull(property, nameof(property));
391             return property.GetSetMethod();
392         }
393
394         public static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic)
395         {
396             Requires.NotNull(property, nameof(property));
397             return property.GetSetMethod(nonPublic);
398         }
399     }
400 }