/Runtime/Microsoft.Dynamic/Utils/ReflectionUtils.cs
C# | 1924 lines | 1475 code | 315 blank | 134 comment | 421 complexity | df3aab61498b713c845676ba6b43ae56 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
Large files files are truncated, but you can click here to view the full file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Apache License, Version 2.0, please send an email to
- * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Apache License, Version 2.0.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
- #if FEATURE_METADATA_READER
- using Microsoft.Scripting.Metadata;
- #endif
- #if !FEATURE_TYPE_INFO
- using TypeInfo = System.Type;
- #endif
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Diagnostics;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Runtime.CompilerServices;
- using System.Security;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.Dynamic;
- using System.Linq.Expressions;
- using Microsoft.Scripting.Generation;
- using Microsoft.Scripting.Runtime;
- using Microsoft.Scripting.Utils;
- #if WIN8 || WP75 || NETSTANDARD
- namespace System.Runtime.CompilerServices {
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event)]
- public sealed class SpecialNameAttribute : Attribute {
- public SpecialNameAttribute() {
- }
- }
- }
- #endif
- #if WIN8
- namespace System {
- public enum TypeCode {
- Empty,
- Object,
- DBNull,
- Boolean,
- Char,
- SByte,
- Byte,
- Int16,
- UInt16,
- Int32,
- UInt32,
- Int64,
- UInt64,
- Single,
- Double,
- Decimal,
- DateTime,
- String = 18
- }
- }
- namespace System.Reflection {
- [Flags]
- public enum BindingFlags {
- /// <summary>Specifies that instance members are to be included in the search.</summary>
- Instance = 4,
- /// <summary>Specifies that static members are to be included in the search.</summary>
- Static = 8,
- /// <summary>Specifies that public members are to be included in the search.</summary>
- Public = 16,
- /// <summary>Specifies that non-public members are to be included in the search.</summary>
- NonPublic = 32
- }
- }
- #elif !CLR45
- namespace System.Reflection {
- public static class RuntimeReflectionExtensions {
- public static MethodInfo GetRuntimeBaseDefinition(this MethodInfo method) {
- return method.GetBaseDefinition();
- }
- public static IEnumerable<MethodInfo> GetRuntimeMethods(this Type type) {
- return type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
- }
- #if !FEATURE_GET_METHOD_INFO
- public static MethodInfo GetMethodInfo(this Delegate d) {
- return d.Method;
- }
- #endif
- #if !FEATURE_TYPE_INFO
- public static InterfaceMapping GetRuntimeInterfaceMap(this Type typeInfo, Type interfaceType) {
- return typeInfo.GetInterfaceMap(interfaceType);
- }
- #endif
- }
- }
- #endif
- namespace Microsoft.Scripting.Utils {
- // CF doesn't support DefaultParameterValue attribute. Define our own, but not in System.Runtime.InteropServices namespace as that would
- // make C# compiler emit the parameter's default value metadata not the attribute itself. The default value metadata are not accessible on CF.
- #if !FEATURE_DEFAULT_PARAMETER_VALUE
- /// <summary>
- /// The Default Parameter Value Attribute.
- /// </summary>
- public sealed class DefaultParameterValueAttribute : Attribute
- {
- private readonly object _value;
- public object Value
- {
- get { return _value; }
- }
- /// <summary>
- /// The constructor
- /// </summary>
- /// <param name="value">The value.</param>
- public DefaultParameterValueAttribute(object value)
- {
- _value = value;
- }
- }
- #if !ANDROID
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false), ComVisible(true)]
- public sealed class OptionalAttribute : Attribute {
- }
- #endif
- #endif
- public static class ReflectionUtils {
- #region Accessibility
- public static BindingFlags AllMembers = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
- public static bool IsPublic(this PropertyInfo property) {
- return property.GetGetMethod(nonPublic: false) != null
- || property.GetSetMethod(nonPublic: false) != null;
- }
- public static bool IsStatic(this PropertyInfo property) {
- var getter = property.GetGetMethod(nonPublic: true);
- var setter = property.GetSetMethod(nonPublic: true);
- return getter != null && getter.IsStatic
- || setter != null && setter.IsStatic;
- }
- public static bool IsStatic(this EventInfo evnt) {
- var add = evnt.GetAddMethod(nonPublic: true);
- var remove = evnt.GetRemoveMethod(nonPublic: true);
- return add != null && add.IsStatic
- || remove != null && remove.IsStatic;
- }
- public static bool IsPrivate(this PropertyInfo property) {
- var getter = property.GetGetMethod(nonPublic: true);
- var setter = property.GetSetMethod(nonPublic: true);
- return (getter == null || getter.IsPrivate)
- && (setter == null || setter.IsPrivate);
- }
- public static bool IsPrivate(this EventInfo evnt) {
- var add = evnt.GetAddMethod(nonPublic: true);
- var remove = evnt.GetRemoveMethod(nonPublic: true);
- return (add == null || add.IsPrivate)
- && (remove == null || remove.IsPrivate);
- }
- private static bool MatchesFlags(ConstructorInfo member, BindingFlags flags) {
- return
- ((member.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) & flags) != 0 &&
- ((member.IsStatic ? BindingFlags.Static : BindingFlags.Instance) & flags) != 0;
- }
- private static bool MatchesFlags(MethodInfo member, BindingFlags flags) {
- return
- ((member.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) & flags) != 0 &&
- ((member.IsStatic ? BindingFlags.Static : BindingFlags.Instance) & flags) != 0;
- }
- private static bool MatchesFlags(FieldInfo member, BindingFlags flags) {
- return
- ((member.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic) & flags) != 0 &&
- ((member.IsStatic ? BindingFlags.Static : BindingFlags.Instance) & flags) != 0;
- }
- private static bool MatchesFlags(PropertyInfo member, BindingFlags flags) {
- return
- ((member.IsPublic() ? BindingFlags.Public : BindingFlags.NonPublic) & flags) != 0 &&
- ((member.IsStatic() ? BindingFlags.Static : BindingFlags.Instance) & flags) != 0;
- }
- private static bool MatchesFlags(EventInfo member, BindingFlags flags) {
- var add = member.GetAddMethod();
- var remove = member.GetRemoveMethod();
- var raise = member.GetRaiseMethod();
- bool isPublic = add != null && add.IsPublic || remove != null && remove.IsPublic || raise != null && raise.IsPublic;
- bool isStatic = add != null && add.IsStatic || remove != null && remove.IsStatic || raise != null && raise.IsStatic;
- return
- ((isPublic ? BindingFlags.Public : BindingFlags.NonPublic) & flags) != 0 &&
- ((isStatic ? BindingFlags.Static : BindingFlags.Instance) & flags) != 0;
- }
- private static bool MatchesFlags(TypeInfo member, BindingFlags flags) {
- // Static/Instance are ignored
- return (((member.IsPublic || member.IsNestedPublic) ? BindingFlags.Public : BindingFlags.NonPublic) & flags) != 0;
- }
- private static bool MatchesFlags(MemberInfo member, BindingFlags flags) {
- ConstructorInfo ctor;
- MethodInfo method;
- FieldInfo field;
- EventInfo evnt;
- PropertyInfo property;
- if ((method = member as MethodInfo) != null) {
- return MatchesFlags(method, flags);
- }
- if ((field = member as FieldInfo) != null) {
- return MatchesFlags(field, flags);
- }
- if ((ctor = member as ConstructorInfo) != null) {
- return MatchesFlags(ctor, flags);
- }
- if ((evnt = member as EventInfo) != null) {
- return MatchesFlags(evnt, flags);
- }
- if ((property = member as PropertyInfo) != null) {
- return MatchesFlags(property, flags);
- }
- return MatchesFlags((TypeInfo)member, flags);
- }
- private static IEnumerable<T> WithBindingFlags<T>(this IEnumerable<T> members, Func<T, BindingFlags, bool> matchFlags, BindingFlags flags)
- where T : MemberInfo {
- return members.Where(member => matchFlags(member, flags));
- }
- public static IEnumerable<MemberInfo> WithBindingFlags(this IEnumerable<MemberInfo> members, BindingFlags flags) {
- return members.WithBindingFlags(MatchesFlags, flags);
- }
- public static IEnumerable<MethodInfo> WithBindingFlags(this IEnumerable<MethodInfo> members, BindingFlags flags) {
- return members.WithBindingFlags(MatchesFlags, flags);
- }
- public static IEnumerable<ConstructorInfo> WithBindingFlags(this IEnumerable<ConstructorInfo> members, BindingFlags flags) {
- return members.WithBindingFlags(MatchesFlags, flags);
- }
- public static IEnumerable<FieldInfo> WithBindingFlags(this IEnumerable<FieldInfo> members, BindingFlags flags) {
- return members.WithBindingFlags(MatchesFlags, flags);
- }
- public static IEnumerable<PropertyInfo> WithBindingFlags(this IEnumerable<PropertyInfo> members, BindingFlags flags) {
- return members.WithBindingFlags(MatchesFlags, flags);
- }
- public static IEnumerable<EventInfo> WithBindingFlags(this IEnumerable<EventInfo> members, BindingFlags flags) {
- return members.WithBindingFlags(MatchesFlags, flags);
- }
- public static IEnumerable<TypeInfo> WithBindingFlags(this IEnumerable<TypeInfo> members, BindingFlags flags) {
- return members.WithBindingFlags(MatchesFlags, flags);
- }
- public static MemberInfo WithBindingFlags(this MemberInfo member, BindingFlags flags) {
- return member != null && MatchesFlags(member, flags) ? member : null;
- }
- public static MethodInfo WithBindingFlags(this MethodInfo member, BindingFlags flags) {
- return member != null && MatchesFlags(member, flags) ? member : null;
- }
- public static ConstructorInfo WithBindingFlags(this ConstructorInfo member, BindingFlags flags) {
- return member != null && MatchesFlags(member, flags) ? member : null;
- }
- public static FieldInfo WithBindingFlags(this FieldInfo member, BindingFlags flags) {
- return member != null && MatchesFlags(member, flags) ? member : null;
- }
- public static PropertyInfo WithBindingFlags(this PropertyInfo member, BindingFlags flags) {
- return member != null && MatchesFlags(member, flags) ? member : null;
- }
- public static EventInfo WithBindingFlags(this EventInfo member, BindingFlags flags) {
- return member != null && MatchesFlags(member, flags) ? member : null;
- }
- public static TypeInfo WithBindingFlags(this TypeInfo member, BindingFlags flags) {
- return member != null && MatchesFlags(member, flags) ? member : null;
- }
- #endregion
- #region Signatures
- public static IEnumerable<MethodInfo> WithSignature(this IEnumerable<MethodInfo> members, Type[] parameterTypes) {
- return members.Where(c => {
- var ps = c.GetParameters();
- if (ps.Length != parameterTypes.Length) {
- return false;
- }
- for (int i = 0; i < ps.Length; i++) {
- if (parameterTypes[i] != ps[i].ParameterType) {
- return false;
- }
- }
- return true;
- });
- }
- public static IEnumerable<ConstructorInfo> WithSignature(this IEnumerable<ConstructorInfo> members, Type[] parameterTypes) {
- return members.Where(c => {
- var ps = c.GetParameters();
- if (ps.Length != parameterTypes.Length) {
- return false;
- }
- for (int i = 0; i < ps.Length; i++) {
- if (parameterTypes[i] != ps[i].ParameterType) {
- return false;
- }
- }
- return true;
- });
- }
-
- #endregion
- #region Member Inheritance
- // CLI specification, partition I, 8.10.4: Hiding, overriding, and layout
- // ----------------------------------------------------------------------
- // While hiding applies to all members of a type, overriding deals with object layout and is applicable only to instance fields
- // and virtual methods. The CTS provides two forms of member overriding, new slot and expect existing slot. A member of a derived
- // type that is marked as a new slot will always get a new slot in the object’s layout, guaranteeing that the base field or method
- // is available in the object by using a qualified reference that combines the name of the base type with the name of the member
- // and its type or signature. A member of a derived type that is marked as expect existing slot will re-use (i.e., share or override)
- // a slot that corresponds to a member of the same kind (field or method), name, and type if one already exists from the base type;
- // if no such slot exists, a new slot is allocated and used.
- //
- // The general algorithm that is used for determining the names in a type and the layout of objects of the type is roughly as follows:
- // - Flatten the inherited names (using the hide by name or hide by name-and-signature rule) ignoring accessibility rules.
- // - For each new member that is marked “expect existing slot”, look to see if an exact match on kind (i.e., field or method),
- // name, and signature exists and use that slot if it is found, otherwise allocate a new slot.
- // - After doing this for all new members, add these new member-kind/name/signatures to the list of members of this type
- // - Finally, remove any inherited names that match the new members based on the hide by name or hide by name-and-signature rules.
-
- // NOTE: Following GetXxx only implement overriding, not hiding specified by hide-by-name or hide-by-name-and-signature flags.
- public static IEnumerable<MethodInfo> GetInheritedMethods(this Type type, string name = null, bool flattenHierarchy = false) {
- while (type.IsGenericParameter) {
- type = type.GetBaseType();
- }
- var baseDefinitions = new HashSet<MethodInfo>(ReferenceEqualityComparer<MethodInfo>.Instance);
- foreach (var ancestor in type.Ancestors()) {
- foreach (var declaredMethod in ancestor.GetDeclaredMethods(name)) {
- if (declaredMethod != null && IncludeMethod(declaredMethod, type, baseDefinitions, flattenHierarchy)) {
- yield return declaredMethod;
- }
- }
- }
- }
- private static bool IncludeMethod(MethodInfo member, Type reflectedType, HashSet<MethodInfo> baseDefinitions, bool flattenHierarchy) {
- if (member.IsVirtual) {
- if (baseDefinitions.Add(RuntimeReflectionExtensions.GetRuntimeBaseDefinition(member))) {
- return true;
- }
- } else if (member.DeclaringType == reflectedType) {
- return true;
- } else if (!member.IsPrivate && (!member.IsStatic || flattenHierarchy)) {
- return true;
- }
- return false;
- }
- public static IEnumerable<PropertyInfo> GetInheritedProperties(this Type type, string name = null, bool flattenHierarchy = false) {
- while (type.IsGenericParameter) {
- type = type.GetBaseType();
- }
- var baseDefinitions = new HashSet<MethodInfo>(ReferenceEqualityComparer<MethodInfo>.Instance);
- foreach (var ancestor in type.Ancestors()) {
- if (name != null) {
- var declaredProperty = ancestor.GetDeclaredProperty(name);
- if (declaredProperty != null && IncludeProperty(declaredProperty, type, baseDefinitions, flattenHierarchy)) {
- yield return declaredProperty;
- }
- } else {
- foreach (var declaredProperty in ancestor.GetDeclaredProperties()) {
- if (IncludeProperty(declaredProperty, type, baseDefinitions, flattenHierarchy)) {
- yield return declaredProperty;
- }
- }
- }
- }
- }
- // CLI spec 22.34 Properties
- // -------------------------
- // [Note: The CLS (see Partition I) refers to instance, virtual, and static properties.
- // The signature of a property (from the Type column) can be used to distinguish a static property,
- // since instance and virtual properties will have the “HASTHIS” bit set in the signature (§23.2.1)
- // while a static property will not. The distinction between an instance and a virtual property
- // depends on the signature of the getter and setter methods, which the CLS requires to be either
- // both virtual or both instance. end note]
- private static bool IncludeProperty(PropertyInfo member, Type reflectedType, HashSet<MethodInfo> baseDefinitions, bool flattenHierarchy) {
- var getter = member.GetGetMethod(nonPublic: true);
- var setter = member.GetSetMethod(nonPublic: true);
- MethodInfo virtualAccessor;
- if (getter != null && getter.IsVirtual) {
- virtualAccessor = getter;
- } else if (setter != null && setter.IsVirtual) {
- virtualAccessor = setter;
- } else {
- virtualAccessor = null;
- }
- if (virtualAccessor != null) {
- if (baseDefinitions.Add(RuntimeReflectionExtensions.GetRuntimeBaseDefinition(virtualAccessor))) {
- return true;
- }
- } else if (member.DeclaringType == reflectedType) {
- return true;
- } else if (!member.IsPrivate() && (!member.IsStatic() || flattenHierarchy)) {
- return true;
- }
- return false;
- }
- public static IEnumerable<EventInfo> GetInheritedEvents(this Type type, string name = null, bool flattenHierarchy = false) {
- while (type.IsGenericParameter) {
- type = type.GetBaseType();
- }
- var baseDefinitions = new HashSet<MethodInfo>(ReferenceEqualityComparer<MethodInfo>.Instance);
- foreach (var ancestor in type.Ancestors()) {
- if (name != null) {
- var declaredEvent = ancestor.GetDeclaredEvent(name);
- if (declaredEvent != null && IncludeEvent(declaredEvent, type, baseDefinitions, flattenHierarchy)) {
- yield return declaredEvent;
- }
- } else {
- foreach (var declaredEvent in ancestor.GetDeclaredEvents()) {
- if (IncludeEvent(declaredEvent, type, baseDefinitions, flattenHierarchy)) {
- yield return declaredEvent;
- }
- }
- }
- }
- }
- private static bool IncludeEvent(EventInfo member, Type reflectedType, HashSet<MethodInfo> baseDefinitions, bool flattenHierarchy) {
- var add = member.GetAddMethod(nonPublic: true);
- var remove = member.GetRemoveMethod(nonPublic: true);
- // TOOD: fire method?
- MethodInfo virtualAccessor;
- if (add != null && add.IsVirtual) {
- virtualAccessor = add;
- } else if (remove != null && remove.IsVirtual) {
- virtualAccessor = remove;
- } else {
- virtualAccessor = null;
- }
- if (virtualAccessor != null) {
- if (baseDefinitions.Add(RuntimeReflectionExtensions.GetRuntimeBaseDefinition(virtualAccessor))) {
- return true;
- }
- } else if (member.DeclaringType == reflectedType) {
- return true;
- } else if (!member.IsPrivate() && (!member.IsStatic() || flattenHierarchy)) {
- return true;
- }
- return false;
- }
- public static IEnumerable<FieldInfo> GetInheritedFields(this Type type, string name = null, bool flattenHierarchy = false) {
- while (type.IsGenericParameter) {
- type = type.GetBaseType();
- }
- foreach (var ancestor in type.Ancestors()) {
- if (name != null) {
- var declaredField = ancestor.GetDeclaredField(name);
- if (declaredField != null && IncludeField(declaredField, type, flattenHierarchy)) {
- yield return declaredField;
- }
- } else {
- foreach (var declaredField in ancestor.GetDeclaredFields()) {
- if (IncludeField(declaredField, type, flattenHierarchy)) {
- yield return declaredField;
- }
- }
- }
- }
- }
-
- private static bool IncludeField(FieldInfo member, Type reflectedType, bool flattenHierarchy) {
- if (member.DeclaringType == reflectedType) {
- return true;
- } else if (!member.IsPrivate && (!member.IsStatic || flattenHierarchy)) {
- return true;
- }
- return false;
- }
- public static IEnumerable<MemberInfo> GetInheritedMembers(this Type type, string name = null, bool flattenHierarchy = false) {
- var result =
- type.GetInheritedMethods(name, flattenHierarchy).Cast<MethodInfo, MemberInfo>().Concat(
- type.GetInheritedProperties(name, flattenHierarchy).Cast<PropertyInfo, MemberInfo>().Concat(
- type.GetInheritedEvents(name, flattenHierarchy).Cast<EventInfo, MemberInfo>().Concat(
- type.GetInheritedFields(name, flattenHierarchy).Cast<FieldInfo, MemberInfo>())));
- if (name == null) {
- return result.Concat<MemberInfo>(
- type.GetDeclaredConstructors().Cast<ConstructorInfo, MemberInfo>().Concat(
- type.GetDeclaredNestedTypes().Cast<TypeInfo, MemberInfo>()));
- }
- var nestedType = type.GetDeclaredNestedType(name);
- return (nestedType != null) ? result.Concat(new[] { nestedType }) : result;
- }
- #endregion
- #region Declared Members
- public static IEnumerable<ConstructorInfo> GetDeclaredConstructors(this Type type) {
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().DeclaredConstructors;
- #else
- return type.GetConstructors(BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- #if WIN8
- public static ConstructorInfo GetConstructor(this Type type, Type[] parameterTypes) {
- return type.GetDeclaredConstructors().Where(ci => !ci.IsStatic && ci.IsPublic).WithSignature(parameterTypes).SingleOrDefault();
- }
- #endif
- public static IEnumerable<MethodInfo> GetDeclaredMethods(this Type type, string name = null) {
- #if FEATURE_TYPE_INFO
- if (name == null) {
- return type.GetTypeInfo().DeclaredMethods;
- } else {
- return type.GetTypeInfo().GetDeclaredMethods(name);
- }
- #else
- if (name == null) {
- return type.GetMethods(BindingFlags.DeclaredOnly | AllMembers);
- } else {
- return type.GetMember(name, MemberTypes.Method, BindingFlags.DeclaredOnly | AllMembers).OfType<MethodInfo>();
- }
- #endif
- }
- public static IEnumerable<PropertyInfo> GetDeclaredProperties(this Type type) {
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().DeclaredProperties;
- #else
- return type.GetProperties(BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static PropertyInfo GetDeclaredProperty(this Type type, string name) {
- Debug.Assert(name != null);
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().GetDeclaredProperty(name);
- #else
- return type.GetProperty(name, BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static IEnumerable<EventInfo> GetDeclaredEvents(this Type type) {
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().DeclaredEvents;
- #else
- return type.GetEvents(BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static EventInfo GetDeclaredEvent(this Type type, string name) {
- Debug.Assert(name != null);
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().GetDeclaredEvent(name);
- #else
- return type.GetEvent(name, BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static IEnumerable<FieldInfo> GetDeclaredFields(this Type type) {
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().DeclaredFields;
- #else
- return type.GetFields(BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static FieldInfo GetDeclaredField(this Type type, string name) {
- Debug.Assert(name != null);
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().GetDeclaredField(name);
- #else
- return type.GetField(name, BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static IEnumerable<TypeInfo> GetDeclaredNestedTypes(this Type type) {
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().DeclaredNestedTypes;
- #else
- return type.GetNestedTypes(BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static TypeInfo GetDeclaredNestedType(this Type type, string name) {
- Debug.Assert(name != null);
- #if FEATURE_TYPE_INFO
- return type.GetTypeInfo().GetDeclaredNestedType(name);
- #else
- return type.GetNestedType(name, BindingFlags.DeclaredOnly | AllMembers);
- #endif
- }
- public static IEnumerable<MemberInfo> GetDeclaredMembers(this Type type, string name = null) {
- #if WIN8
- var info = type.GetTypeInfo();
- if (name == null) {
- return info.DeclaredMembers;
- } else {
- return GetDeclaredMembersWithName(info, name);
- }
- #else
- if (name == null) {
- return type.GetMembers(BindingFlags.DeclaredOnly | AllMembers);
- } else {
- return type.GetMember(name, BindingFlags.DeclaredOnly | AllMembers);
- }
- #endif
- }
- #if WIN8
- private static IEnumerable<MemberInfo> GetDeclaredMembersWithName(TypeInfo info, string name) {
- MemberInfo member;
- if ((member = info.GetDeclaredMethod(name)) != null) {
- yield return member;
- }
- if ((member = info.GetDeclaredField(name)) != null) {
- yield return member;
- }
- if ((member = info.GetDeclaredProperty(name)) != null) {
- yield return member;
- }
- if ((member = info.GetDeclaredEvent(name)) != null) {
- yield return member;
- }
- if ((member = info.GetDeclaredNestedType(name)) != null) {
- yield return member;
- }
- }
- #endif
- #endregion
- #region Win8
- #if WIN8
- public static TypeCode GetTypeCode(this Enum e) {
- return GetTypeCode(Enum.GetUnderlyingType(e.GetType()));
- }
- // TODO: reduce to numeric types?
- public static TypeCode GetTypeCode(this Type type) {
- if (type == typeof(int)) {
- return TypeCode.Int32;
- }
- if (type == typeof(sbyte)) {
- return TypeCode.SByte;
- }
- if (type == typeof(short)) {
- return TypeCode.Int16;
- }
- if (type == typeof(long)) {
- return TypeCode.Int64;
- }
- if (type == typeof(uint)) {
- return TypeCode.UInt32;
- }
- if (type == typeof(byte)) {
- return TypeCode.Byte;
- }
- if (type == typeof(ushort)) {
- return TypeCode.UInt16;
- }
- if (type == typeof(ulong)) {
- return TypeCode.UInt64;
- }
- if (type == typeof(bool)) {
- return TypeCode.Boolean;
- }
- if (type == typeof(char)) {
- return TypeCode.Char;
- }
- // TODO: do we need this?
- if (type == typeof(string)) {
- return TypeCode.String;
- }
- if (type == typeof(bool)) {
- return TypeCode.Boolean;
- }
- if (type == typeof(double)) {
- return TypeCode.Double;
- }
- if (type == typeof(float)) {
- return TypeCode.Single;
- }
- if (type == typeof(decimal)) {
- return TypeCode.Decimal;
- }
- if (type == typeof(DateTime)) {
- return TypeCode.DateTime;
- }
- return TypeCode.Object;
- }
- public static IEnumerable<Type> GetImplementedInterfaces(this Type type) {
- return type.GetTypeInfo().ImplementedInterfaces;
- }
- #if !NETSTANDARD
- public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo, bool nonPublic = false) {
- var accessor = propertyInfo.GetMethod;
- return nonPublic || accessor == null || accessor.IsPublic ? accessor : null;
- }
- public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo, bool nonPublic = false) {
- var accessor = propertyInfo.SetMethod;
- return nonPublic || accessor == null || accessor.IsPublic ? accessor : null;
- }
- public static MethodInfo GetAddMethod(this EventInfo eventInfo, bool nonPublic = false) {
- var accessor = eventInfo.AddMethod;
- return nonPublic || accessor == null || accessor.IsPublic ? accessor : null;
- }
- public static MethodInfo GetRemoveMethod(this EventInfo eventInfo, bool nonPublic = false) {
- var accessor = eventInfo.RemoveMethod;
- return nonPublic || accessor == null || accessor.IsPublic ? accessor : null;
- }
- public static MethodInfo GetRaiseMethod(this EventInfo eventInfo, bool nonPublic = false) {
- var accessor = eventInfo.RaiseMethod;
- return nonPublic || accessor == null || accessor.IsPublic ? accessor : null;
- }
- public static MethodInfo GetMethod(this Type type, string name) {
- return type.GetTypeInfo().GetDeclaredMethod(name);
- }
- // TODO: FlattenHierarchy
- // TODO: inherited!
- public static MethodInfo GetMethod(this Type type, string name, Type[] parameterTypes) {
- return type.GetTypeInfo().GetDeclaredMethods(name).WithSignature(parameterTypes).Single();
- }
- public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags) {
- return type.GetMethods(name, bindingFlags).Single();
- }
- #endif
- private static IEnumerable<MethodInfo> GetMethods(this Type type, string name, BindingFlags bindingFlags) {
- return type.GetTypeInfo().GetDeclaredMethods(name).WithBindingFlags(bindingFlags);
- }
- public static Type CreateType(this TypeBuilder builder) {
- return builder.CreateTypeInfo().AsType();
- }
- #if !NETSTANDARD
- public static object GetRawConstantValue(this FieldInfo field) {
- return ((dynamic)field).GetRawConstantValue();
- }
- public static int GetMetadataToken(this MemberInfo member) {
- return ((dynamic)member).MetadataToken;
- }
- #endif
- public static Module GetModule(this MemberInfo member) {
- return member.Module;
- }
- #if !NETSTANDARD
- public static Type[] GetGenericArguments(this Type type) {
- return type.GetTypeInfo().GenericTypeArguments;
- }
- public static bool IsAssignableFrom(this Type type, Type other) {
- return type.GetTypeInfo().IsAssignableFrom(other.GetTypeInfo());
- }
- #endif
- public static Type[] GetGenericParameterConstraints(this Type type) {
- return type.GetTypeInfo().GetGenericParameterConstraints();
- }
- public static bool IsSubclassOf(this Type type, Type other) {
- return type.GetTypeInfo().IsSubclassOf(other);
- }
- #if !NETSTANDARD
- public static IEnumerable<Type> GetInterfaces(this Type type) {
- return type.GetTypeInfo().ImplementedInterfaces;
- }
- #endif
- public static Type[] GetRequiredCustomModifiers(this ParameterInfo parameter) {
- return EmptyTypes;
- }
- public static Type[] GetOptionalCustomModifiers(this ParameterInfo parameter) {
- return EmptyTypes;
- }
- public static IEnumerable<Module> GetModules(this Assembly assembly) {
- return assembly.Modules;
- }
- private static string GetDefaultMemberName(this Type type) {
- foreach (var ancestor in type.Ancestors()) {
- var attr = ancestor.GetTypeInfo().GetCustomAttributes<DefaultMemberAttribute>().SingleOrDefault();
- if (attr != null) {
- return attr.MemberName;
- }
- }
- return null;
- }
- #if !NETSTANDARD
- public static IEnumerable<MemberInfo> GetDefaultMembers(this Type type) {
- string defaultMemberName = type.GetDefaultMemberName();
- if (defaultMemberName != null) {
- return type.GetInheritedMembers(defaultMemberName).WithBindingFlags(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
- }
- return Enumerable.Empty<MemberInfo>();
- }
- #endif
- #else
- public static IEnumerable<Module> GetModules(this Assembly assembly) {
- return assembly.GetModules();
- }
- public static IEnumerable<Type> GetImplementedInterfaces(this Type type) {
- return type.GetInterfaces();
- }
- public static TypeCode GetTypeCode(this Type type) {
- return Type.GetTypeCode(type);
- }
- public static int GetMetadataToken(this MemberInfo member) {
- return member.MetadataToken;
- }
- public static Module GetModule(this MemberInfo member) {
- return member.Module;
- }
- public static bool IsDefined(this Assembly assembly, Type attributeType) {
- return assembly.IsDefined(attributeType, false);
- }
- #if !CLR45
- public static T GetCustomAttribute<T>(this Assembly assembly, bool inherit = false) where T : Attribute {
- return (T)Attribute.GetCustomAttribute(assembly, typeof(T), inherit);
- }
- public static T GetCustomAttribute<T>(this MemberInfo member, bool inherit = false) where T : Attribute {
- return (T)Attribute.GetCustomAttribute(member, typeof(T), inherit);
- }
- public static IEnumerable<T> GetCustomAttributes<T>(this Assembly assembly, bool inherit = false) where T : Attribute {
- return Attribute.GetCustomAttributes(assembly, typeof(T), inherit).Cast<T>();
- }
- public static IEnumerable<T> GetCustomAttributes<T>(this MemberInfo member, bool inherit = false) where T : Attribute {
- return Attribute.GetCustomAttributes(member, typeof(T), inherit).Cast<T>();
- }
- #endif
- #endif
- public static MethodInfo GetMethod(this Delegate d) {
- return d.GetMethodInfo();
- }
- public static bool ContainsGenericParameters(this Type type) {
- return type.GetTypeInfo().ContainsGenericParameters;
- }
- public static bool IsInterface(this Type type) {
- return type.GetTypeInfo().IsInterface;
- }
- public static bool IsClass(this Type type) {
- return type.GetTypeInfo().IsClass;
- }
- public static bool IsGenericType(this Type type) {
- return type.GetTypeInfo().IsGenericType;
- }
- public static bool IsGenericTypeDefinition(this Type type) {
- return type.GetTypeInfo().IsGenericTypeDefinition;
- }
- public static bool IsSealed(this Type type) {
- return type.GetTypeInfo().IsSealed;
- }
- public static bool IsAbstract(this Type type) {
- return type.GetTypeInfo().IsAbstract;
- }
- public static bool IsPublic(this Type type) {
- return type.GetTypeInfo().IsPublic;
- }
- public static bool IsVisible(this Type type) {
- return type.GetTypeInfo().IsVisible;
- }
-
- public static Type GetBaseType(this Type type) {
- return type.GetTypeInfo().BaseType;
- }
- public static bool IsValueType(this Type type) {
- return type.GetTypeInfo().IsValueType;
- }
- public static bool IsEnum(this Type type) {
- return type.GetTypeInfo().IsEnum;
- }
- public static bool IsPrimitive(this Type type) {
- return type.GetTypeInfo().IsPrimitive;
- }
- public static GenericParameterAttributes GetGenericParameterAttributes(this Type type) {
- return type.GetTypeInfo().GenericParameterAttributes;
- }
-
- public static Type[] EmptyTypes = new Type[0];
- #endregion
- #if FEATURE_REFEMIT
- #if FEATURE_ASSEMBLYBUILDER_DEFINEDYNAMICASSEMBLY
- public static AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access) {
- return AssemblyBuilder.DefineDynamicAssembly(name, access);
- }
- #else
- public static AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access) {
- return AppDomain.CurrentDomain.DefineDynamicAssembly(name, access);
- }
- #endif
- #if !FEATURE_PDBEMIT
- public static ModuleBuilder DefineDynamicModule(this AssemblyBuilder assembly, string name, bool emitDebugInfo) {
- // ignore the flag
- return assembly.DefineDynamicModule(name);
- }
- #endif
- #endif
- #region Signature and Type Formatting
- // Generic type names have the arity (number of generic type paramters) appended at the end.
- // For eg. the mangled name of System.List<T> is "List`1". This mangling is done to enable multiple
- // generic types to exist as long as they have different arities.
- public const char GenericArityDelimiter = '`';
- #if !WIN8
- public static StringBuilder FormatSignature(StringBuilder result, MethodBase method) {
- return FormatSignature(result, method, (t) => t.FullName);
- }
- public static StringBuilder FormatSignature(StringBuilder result, MethodBase method, Func<Type, string> nameDispenser) {
- ContractUtils.RequiresNotNull(result, "result");
- ContractUtils.RequiresNotNull(method, "method");
- ContractUtils.RequiresNotNull(nameDispenser, "nameDispenser");
- MethodInfo methodInfo = method as MethodInfo;
- if (methodInfo != null) {
- FormatTypeName(result, methodInfo.ReturnType, nameDispenser);
- result.Append(' ');
- }
- #if FEATURE_REFEMIT && !NETSTANDARD
- MethodBuilder builder = method as MethodBuilder;
- if (builder != null) {
- result.Append(builder.Signature);
- return result;
- }
- ConstructorBuilder cb = method as ConstructorBuilder;
- if (cb != null) {
- result.Append(cb.Signature);
- return result;
- }
- #endif
- FormatTypeName(result, method.DeclaringType, nameDispenser);
- result.Append("::");
- result.Append(method.Name);
- if (!method.IsConstructor) {
- FormatTypeArgs(result, method.GetGenericArguments(), nameDispenser);
- }
- result.Append("(");
- if (!method.ContainsGenericParameters) {
- ParameterInfo[] ps = method.GetParameters();
- for (int i = 0; i < ps.Length; i++) {
- if (i > 0) result.Append(", ");
- FormatTypeName(result, ps[i].ParameterType, nameDispenser);
- if (!System.String.IsNullOrEmpty(ps[i].Name)) {
- result.Append(" ");
- result.Append(ps[i].Name);
- }
- }
- } else {
- result.Append("?");
- }
- result.Append(")");
- return result;
- }
- #endif
- public static StringBuilder FormatTypeName(StringBuilder result, Type type) {
- return FormatTypeName(result, type, (t) => t.FullName);
- }
- public static StringBuilder FormatTypeName(StringBuilder result, Type type, Func<Type, string> nameDispenser) {
- ContractUtils.RequiresNotNull(result, "result");
- ContractUtils.RequiresNotNull(type, "type");
- ContractUtils.RequiresNotNull(nameDispenser, "nameDispenser");
-
- if (type.IsGenericType()) {
- Type genType = type.GetGenericTypeDefinition();
- string genericName = nameDispenser(genType).Replace('+', '.');
- int tickIndex = genericName.IndexOf('`');
- result.Append(tickIndex != -1 ? genericName.Substring(0, tickIndex) : genericName);
- Type[] typeArgs = type.GetGenericArguments();
- if (type.IsGenericTypeDefinition()) {
- result.Append('<');
- result.Append(',', typeArgs.Length - 1);
- result.Append('>');
- } else {
- FormatTypeArgs(result, typeArgs, nameDispenser);
- }
- } else if (type.IsGenericParameter) {
- result.Append(type.Name);
- } else {
- // cut namespace off:
- result.Append(nameDispenser(type).Replace('+', '.'));
- }
- return result;
- }
- public static StringBuilder FormatTypeArgs(StringBuilder result, Type[] types) {
- return FormatTypeArgs(result, types, (t) => t.FullName);
- }
- public static StringBuilder FormatTypeArgs(StringBuilder result, Type[] types, Func<Type, string> nameDispenser) {
- ContractUtils.RequiresNotNull(result, "result");
- ContractUtils.RequiresNotNullItems(types, "types");
- ContractUtils.RequiresNotNull(nameDispenser, "nameDispenser");
-
- if (types.Length > 0) {
- result.Append("<");
- for (int i = 0; i < types.Length; i++) {
- if (i > 0) result.Append(", ");
- FormatTypeName(result, types[i], nameDispenser);
- }
- result.Append(">");
- }
- return result;
- }
- internal static string ToValidTypeName(string str) {
- if (String.IsNullOrEmpty(str)) {
- return "_";
- }
- StringBuilder sb = new StringBuilder(str);
- for (int i = 0; i < str.Length; i++) {
- if (str[i] == '\0' || str[i] == '.' || str[i] == '*' || str[i] == '+' || str[i] == '[' || str[i] == ']' || str[i] == '\\') {
- sb[i] = '_';
- }
- }
- return sb.ToString();
- }
- public static string GetNormalizedTypeName(Type type) {
- string name = type.Name;
- if (type.IsGenericType()) {
- return GetNormalizedTypeName(name);
- }
- return name;
- }
- public static string GetNormalizedTypeName(string typeName) {
- Debug.Assert(typeName.IndexOf('.') == -1); // This is the simple name, not the full name
- int backtick = typeName.IndexOf(ReflectionUtils.GenericArityDelimiter);
- if (backtick != -1) return typeName.Substring(0, backtick);
- return typeName;
- }
- #endregion
- #region Delegates and Dynamic Methods
- #if WP75
- /// <summary>
- /// Creates an open delegate for the given (dynamic)method.
- /// </summary>
- public static Delegate CreateDelegate(this MethodInfo methodInfo, Type delegateType) {
- return CreateDelegate(methodInfo, delegateType, null);
- }
- /// <summary>
- /// Creates a closed delegate for the given (dynamic)method.
- /// </summary>
- public static Delegate CreateDelegate(this MethodInfo methodInfo, Type delegateType, object target) {
- return Delegate.CreateDelegate(delegateType, target, methodInfo);
- }
- #elif !WIN8 && !NETSTANDARD
- /// <summary>
- /// Creates an open delegate for the given (dynamic)method.
- /// </summary>
- public static Delegate CreateDelegate(this MethodInfo methodInfo, Type delegateType) {
- return CreateDelegate(methodInfo, delegateType, null);
- }
- /// <summary>
- /// Creates a closed delegate for the given (dynamic)method.
- /// </summary>
- public static Delegate CreateDelegate(this MethodInfo methodInfo, Type delegateType, object target) {
- DynamicMethod dm = methodInfo as DynamicMethod;
- if (dm != null) {
- return dm.CreateDelegate(delegateType, target);
- } else {
- return Delegate.CreateDelegate(delegateType, target, methodInfo);
- }
- }
- #endif
- public static bool IsDynamicMethod(MethodBase method) {
- return !PlatformAdaptationLayer.IsCompactFramework && IsDynamicMethodInternal(method);
- }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static bool IsDynamicMethodInternal(MethodBase method) {
- return method is DynamicMethod;
- }
- public static void GetDelegateSignature(Type delegateType, out ParameterInfo[] parameterInfos, out ParameterInfo returnInfo) {
- ContractUtils.RequiresNotNull(delegateType, "delegateType");
- MethodInfo invokeMethod = delegateType.GetMethod("Invoke");
- ContractUtils.Requires(invokeMethod != null, "delegateType", Strings.InvalidDelegate);
- parameterInfos = invokeMethod.GetParameters();
- returnInfo = invokeMethod.ReturnParameter;
- }
- /// <summary>
- /// Gets a Func of CallSite, object * paramCnt, object delegate type
- /// that's suitable for use in a non-strongly typed call site.
- /// </summary>
- public static Type GetObjectCallSiteDelegateType(int paramCnt) {
- switch (paramCnt) {
- case 0: return typeof(Func<CallSite, object, object>);
- case 1: return typeof(Func<CallSite, object, object, object>);
- case 2: return typeof(Func<CallSite, object, object, object, object>);
- case 3: return typeof(Func<CallSite, object, object, object, object, object>);
- case 4: return typeof(Func<CallSite, object, object, object, object, object, object>);
- case 5: return typeof(Func<CallSite, object, object, object, object, object, object, object>);
- case 6: return typeof(Func<CallSite, object, object, object, object, object, object, object, object>);
- case 7: return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object>);
- case 8: return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object>);
- case 9: return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object>);
- case 10: return typeof(Func<CallSite, object, object, object, object, object, object, object, object, object, object, object, object>);
- case 11: return typeof(Func<CallSite, object, object, object, object, object, object, object, o…
Large files files are truncated, but you can click here to view the full file