You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.3 KiB
128 lines
3.3 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Reflection; |
|
using UnityEngine; |
|
|
|
namespace NaughtyAttributes.Editor |
|
{ |
|
public static class ReflectionUtility |
|
{ |
|
public static IEnumerable<FieldInfo> GetAllFields(object target, Func<FieldInfo, bool> predicate) |
|
{ |
|
if (target == null) |
|
{ |
|
Debug.LogError("The target object is null. Check for missing scripts."); |
|
yield break; |
|
} |
|
|
|
List<Type> types = GetSelfAndBaseTypes(target); |
|
|
|
for (int i = types.Count - 1; i >= 0; i--) |
|
{ |
|
IEnumerable<FieldInfo> fieldInfos = types[i] |
|
.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly) |
|
.Where(predicate); |
|
|
|
foreach (var fieldInfo in fieldInfos) |
|
{ |
|
yield return fieldInfo; |
|
} |
|
} |
|
} |
|
|
|
public static IEnumerable<PropertyInfo> GetAllProperties(object target, Func<PropertyInfo, bool> predicate) |
|
{ |
|
if (target == null) |
|
{ |
|
Debug.LogError("The target object is null. Check for missing scripts."); |
|
yield break; |
|
} |
|
|
|
List<Type> types = GetSelfAndBaseTypes(target); |
|
|
|
for (int i = types.Count - 1; i >= 0; i--) |
|
{ |
|
IEnumerable<PropertyInfo> propertyInfos = types[i] |
|
.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly) |
|
.Where(predicate); |
|
|
|
foreach (var propertyInfo in propertyInfos) |
|
{ |
|
yield return propertyInfo; |
|
} |
|
} |
|
} |
|
|
|
public static IEnumerable<MethodInfo> GetAllMethods(object target, Func<MethodInfo, bool> predicate) |
|
{ |
|
if (target == null) |
|
{ |
|
Debug.LogError("The target object is null. Check for missing scripts."); |
|
yield break; |
|
} |
|
|
|
List<Type> types = GetSelfAndBaseTypes(target); |
|
|
|
for (int i = types.Count - 1; i >= 0; i--) |
|
{ |
|
IEnumerable<MethodInfo> methodInfos = types[i] |
|
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly) |
|
.Where(predicate); |
|
|
|
foreach (var methodInfo in methodInfos) |
|
{ |
|
yield return methodInfo; |
|
} |
|
} |
|
} |
|
|
|
public static FieldInfo GetField(object target, string fieldName) |
|
{ |
|
return GetAllFields(target, f => f.Name.Equals(fieldName, StringComparison.Ordinal)).FirstOrDefault(); |
|
} |
|
|
|
public static PropertyInfo GetProperty(object target, string propertyName) |
|
{ |
|
return GetAllProperties(target, p => p.Name.Equals(propertyName, StringComparison.Ordinal)).FirstOrDefault(); |
|
} |
|
|
|
public static MethodInfo GetMethod(object target, string methodName) |
|
{ |
|
return GetAllMethods(target, m => m.Name.Equals(methodName, StringComparison.Ordinal)).FirstOrDefault(); |
|
} |
|
|
|
public static Type GetListElementType(Type listType) |
|
{ |
|
if (listType.IsGenericType) |
|
{ |
|
return listType.GetGenericArguments()[0]; |
|
} |
|
else |
|
{ |
|
return listType.GetElementType(); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Get type and all base types of target, sorted as following: |
|
/// <para />[target's type, base type, base's base type, ...] |
|
/// </summary> |
|
/// <param name="target"></param> |
|
/// <returns></returns> |
|
private static List<Type> GetSelfAndBaseTypes(object target) |
|
{ |
|
List<Type> types = new List<Type>() |
|
{ |
|
target.GetType() |
|
}; |
|
|
|
while (types.Last().BaseType != null) |
|
{ |
|
types.Add(types.Last().BaseType); |
|
} |
|
|
|
return types; |
|
} |
|
} |
|
}
|
|
|