using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace EnhancedHierarchy {
///
/// Class containing method extensions for getting private and internal members.
///
public static partial class ReflectionHelper {
public const BindingFlags FULL_BINDING = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
public const BindingFlags INSTANCE_BINDING = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
public const BindingFlags STATIC_BINDING = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
private static Assembly[] cachedAssemblies;
private static Dictionary cachedTypes;
public static Type FindType(string name) {
Type result;
if (cachedTypes == null)
cachedTypes = new Dictionary();
if (cachedTypes.TryGetValue(name, out result))
return result;
result = FindTypeInAssembly(name, typeof(Editor).Assembly);
if (result == null) {
if (cachedAssemblies == null)
cachedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
for (var i = 0; i < cachedAssemblies.Length; i++) {
result = FindTypeInAssembly(name, cachedAssemblies[i]);
if (result != null)
break;
}
}
if (Preferences.DebugEnabled)
if (result == null)
Debug.LogFormat("Cache fault for \"{0}\", type not found", name);
else
Debug.LogFormat("Cache fault for \"{0}\", found type at \"{1}\"", name, result.Assembly.Location);
cachedTypes[name] = result;
return result;
}
private static Type FindTypeInAssembly(string name, Assembly assembly) {
return assembly == null ?
null :
assembly.GetType(name, false, true);
}
public static FieldInfo FindField(this Type type, string fieldName, BindingFlags flags = FULL_BINDING) {
return type.GetField(fieldName, flags);
}
public static PropertyInfo FindProperty(this Type type, string propertyName, BindingFlags flags = FULL_BINDING) {
return type.GetProperty(propertyName, flags);
}
public static MethodInfo FindMethod(this Type type, string methodName, Type[] argsTypes = null, BindingFlags flags = FULL_BINDING) {
return argsTypes == null ?
type.GetMethod(methodName, flags) :
type.GetMethod(methodName, flags, null, argsTypes, null);
}
#region Fields
public static T GetStaticField(this Type type, string fieldName) {
if (type == null)
throw new ArgumentNullException("type");
return (T)type.FindField(fieldName, STATIC_BINDING).GetValue(null);
}
public static T GetInstanceField(this object obj, string fieldName) {
if (obj == null)
throw new ArgumentNullException("obj");
return (T)obj.GetType().FindField(fieldName, INSTANCE_BINDING).GetValue(obj);
}
public static void SetStaticField(this Type type, string fieldName, TValue value) {
if (type == null)
throw new ArgumentNullException("type");
type.FindField(fieldName, STATIC_BINDING).SetValue(null, value);
}
public static void SetInstanceField(this TObj obj, string fieldName, TValue value) {
if (obj == null)
throw new ArgumentNullException("obj");
obj.GetType().FindField(fieldName, INSTANCE_BINDING).SetValue(obj, value);
}
public static bool HasField(this Type type, string fieldName) {
return type.FindField(fieldName) != null;
}
public static bool HasField(this T obj, string fieldName) {
return obj.GetType().HasField(fieldName);
}
#endregion
#region Props
public static T GetStaticProperty(this Type type, string propertyName) {
if (type == null)
throw new ArgumentNullException("type");
return (T)type.FindProperty(propertyName, STATIC_BINDING).GetValue(null, null);
}
public static T GetInstanceProperty(this object obj, string propertyName) {
if (obj == null)
throw new ArgumentNullException("obj");
return (T)obj.GetType().FindProperty(propertyName, INSTANCE_BINDING).GetValue(obj, null);
}
public static void SetStaticProperty(this Type type, string propertyName, TValue value) {
if (type == null)
throw new ArgumentNullException("type");
type.FindProperty(propertyName, STATIC_BINDING).SetValue(null, value, null);
}
public static void SetInstanceProperty(this TObj obj, string propertyName, TValue value) {
if (obj == null)
throw new ArgumentNullException("obj");
obj.GetType().FindProperty(propertyName, INSTANCE_BINDING).SetValue(obj, value, null);
}
public static bool HasProperty(this Type type, string propertyName) {
return type.FindProperty(propertyName) != null;
}
public static bool HasProperty(this T obj, string propertyName) {
return obj.GetType().HasProperty(propertyName);
}
#endregion
public static object RawCall(Type type, object obj, string methodName, object[] args, Type[] argsTypes, bool isStatic) {
if (obj == null && !isStatic)
throw new ArgumentNullException("obj", "obj cannot be null for instance methods");
if (type == null)
throw new ArgumentNullException("type");
for (var i = 0; i < argsTypes.Length; i++)
if (argsTypes[i] == typeof(object))
argsTypes[i] = args[i].GetType();
var method = type.FindMethod(methodName, argsTypes, isStatic ? STATIC_BINDING : INSTANCE_BINDING);
if (method == null)
throw new MissingMethodException(type.FullName, methodName);
return method.Invoke(obj, args);
}
#region Invoke Instance
public static void InvokeMethod(this object obj, string methodName) {
var args = new object[] { };
var argsTypes = new Type[] { };
RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static void InvokeMethod(this object obj, string methodName, TArg1 arg1) {
var args = new object[] { arg1 };
var argsTypes = new Type[] { typeof(TArg1) };
RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static void InvokeMethod(this object obj, string methodName, TArg1 arg1, TArg2 arg2) {
var args = new object[] { arg1, arg2 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2) };
RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static void InvokeMethod(this object obj, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3) {
var args = new object[] { arg1, arg2, arg3 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3) };
RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static void InvokeMethod(this object obj, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) {
var args = new object[] { arg1, arg2, arg3, arg4 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) };
RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static TResult InvokeMethod(this object obj, string methodName) {
var args = new object[] { };
var argsTypes = new Type[] { };
return (TResult)RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static TResult InvokeMethod(this object obj, string methodName, TArg1 arg1) {
var args = new object[] { arg1 };
var argsTypes = new Type[] { typeof(TArg1) };
return (TResult)RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static TResult InvokeMethod(this object obj, string methodName, TArg1 arg1, TArg2 arg2) {
var args = new object[] { arg1, arg2 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2) };
return (TResult)RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static TResult InvokeMethod(this object obj, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3) {
var args = new object[] { arg1, arg2, arg3 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3) };
return (TResult)RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
public static TResult InvokeMethod(this object obj, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) {
var args = new object[] { arg1, arg2, arg3, arg4 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) };
return (TResult)RawCall(obj.GetType(), obj, methodName, args, argsTypes, false);
}
#endregion
#region Invoke Static
public static void InvokeStaticMethod(this Type type, string methodName) {
var args = new object[] { };
var argsTypes = new Type[] { };
RawCall(type, null, methodName, args, argsTypes, true);
}
public static void InvokeStaticMethod(this Type type, string methodName, TArg1 arg1) {
var args = new object[] { arg1 };
var argsTypes = new Type[] { typeof(TArg1) };
RawCall(type, null, methodName, args, argsTypes, true);
}
public static void InvokeStaticMethod(this Type type, string methodName, TArg1 arg1, TArg2 arg2) {
var args = new object[] { arg1, arg2 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2) };
RawCall(type, null, methodName, args, argsTypes, true);
}
public static void InvokeStaticMethod(this Type type, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3) {
var args = new object[] { arg1, arg2, arg3 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3) };
RawCall(type, null, methodName, args, argsTypes, true);
}
public static void InvokeStaticMethod(this Type type, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) {
var args = new object[] { arg1, arg2, arg3, arg4 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) };
RawCall(type, null, methodName, args, argsTypes, true);
}
public static TResult InvokeStaticMethod(this Type type, string methodName) {
var args = new object[] { };
var argsTypes = new Type[] { };
return (TResult)RawCall(type, null, methodName, args, argsTypes, true);
}
public static TResult InvokeStaticMethod(this Type type, string methodName, TArg1 arg1) {
var args = new object[] { arg1 };
var argsTypes = new Type[] { typeof(TArg1) };
return (TResult)RawCall(type, null, methodName, args, argsTypes, true);
}
public static TResult InvokeStaticMethod(this Type type, string methodName, TArg1 arg1, TArg2 arg2) {
var args = new object[] { arg1, arg2 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2) };
return (TResult)RawCall(type, null, methodName, args, argsTypes, true);
}
public static TResult InvokeStaticMethod(this Type type, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3) {
var args = new object[] { arg1, arg2, arg3 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3) };
return (TResult)RawCall(type, null, methodName, args, argsTypes, true);
}
public static TResult InvokeStaticMethod(this Type type, string methodName, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) {
var args = new object[] { arg1, arg2, arg3, arg4 };
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) };
return (TResult)RawCall(type, null, methodName, args, argsTypes, true);
}
#endregion
#region Has Method
public static bool HasMethod(this object obj, string methodName) {
var argsTypes = new Type[] { };
return obj.GetType().FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this object obj, string methodName) {
var argsTypes = new Type[] { typeof(TArg1) };
return obj.GetType().FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this object obj, string methodName) {
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2) };
return obj.GetType().FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this object obj, string methodName) {
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3) };
return obj.GetType().FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this object obj, string methodName) {
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) };
return obj.GetType().FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this Type type, string methodName) {
var argsTypes = new Type[] { };
return type.FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this Type type, string methodName) {
var argsTypes = new Type[] { typeof(TArg1) };
return type.FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this Type type, string methodName) {
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2) };
return type.FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this Type type, string methodName) {
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3) };
return type.FindMethod(methodName, argsTypes) != null;
}
public static bool HasMethod(this Type type, string methodName) {
var argsTypes = new Type[] { typeof(TArg1), typeof(TArg2), typeof(TArg3), typeof(TArg4) };
return type.FindMethod(methodName, argsTypes) != null;
}
#endregion
}
}