Add support for static fields, properties and methods in ValueResolver

This commit is contained in:
VladV 2022-07-16 10:26:04 +03:00
parent 1a36b38b29
commit b9d2a633db
8 changed files with 275 additions and 0 deletions

View File

@ -0,0 +1,76 @@
using System;
using System.Reflection;
using TriInspector.Utilities;
using UnityEngine;
namespace TriInspector.Resolvers
{
public class StaticFieldValueResolver<T> : ValueResolver<T>
{
private readonly FieldInfo _fieldInfo;
public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression,
out ValueResolver<T> resolver)
{
if (expression.IndexOf('.') == -1)
{
resolver = null;
return false;
}
var separatorIndex = expression.LastIndexOf('.');
var className = expression.Substring(0, separatorIndex);
var methodName = expression.Substring(separatorIndex + 1);
if (!TriReflectionUtilities.TryFindTypeByFullName(className, out var type))
{
resolver = null;
return false;
}
const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var fieldInfo in type.GetFields(flags))
{
if (fieldInfo.Name == methodName &&
typeof(T).IsAssignableFrom(fieldInfo.FieldType))
{
resolver = new StaticFieldValueResolver<T>(fieldInfo);
return true;
}
}
resolver = null;
return false;
}
public StaticFieldValueResolver(FieldInfo fieldInfo)
{
_fieldInfo = fieldInfo;
}
public override bool TryGetErrorString(out string error)
{
error = "";
return false;
}
public override T GetValue(TriProperty property, T defaultValue = default)
{
try
{
return (T) _fieldInfo.GetValue(null);
}
catch (Exception e)
{
if (e is TargetInvocationException targetInvocationException)
{
e = targetInvocationException.InnerException;
}
Debug.LogException(e);
return defaultValue;
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bc82b93a5bf949958553418b396127ec
timeCreated: 1657955836

View File

@ -0,0 +1,78 @@
using System;
using System.Reflection;
using TriInspector.Utilities;
using UnityEngine;
namespace TriInspector.Resolvers
{
public class StaticMethodValueResolver<T> : ValueResolver<T>
{
private readonly MethodInfo _methodInfo;
public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression,
out ValueResolver<T> resolver)
{
if (expression.IndexOf('.') == -1)
{
resolver = null;
return false;
}
var separatorIndex = expression.LastIndexOf('.');
var className = expression.Substring(0, separatorIndex);
var methodName = expression.Substring(separatorIndex + 1);
if (!TriReflectionUtilities.TryFindTypeByFullName(className, out var type))
{
resolver = null;
return false;
}
const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var methodInfo in type.GetMethods(flags))
{
if (methodInfo.Name == methodName &&
typeof(T).IsAssignableFrom(methodInfo.ReturnType) &&
methodInfo.GetParameters() is var parametersInfo &&
parametersInfo.Length == 0)
{
resolver = new StaticMethodValueResolver<T>(methodInfo);
return true;
}
}
resolver = null;
return false;
}
public StaticMethodValueResolver(MethodInfo methodInfo)
{
_methodInfo = methodInfo;
}
public override bool TryGetErrorString(out string error)
{
error = "";
return false;
}
public override T GetValue(TriProperty property, T defaultValue = default)
{
try
{
return (T) _methodInfo.Invoke(null, null);
}
catch (Exception e)
{
if (e is TargetInvocationException targetInvocationException)
{
e = targetInvocationException.InnerException;
}
Debug.LogException(e);
return defaultValue;
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 96c731e2cdce45da8ee4be44ce6674ea
timeCreated: 1657954360

View File

@ -0,0 +1,77 @@
using System;
using System.Reflection;
using TriInspector.Utilities;
using UnityEngine;
namespace TriInspector.Resolvers
{
public class StaticPropertyValueResolver<T> : ValueResolver<T>
{
private readonly PropertyInfo _propertyInfo;
public static bool TryResolve(TriPropertyDefinition propertyDefinition, string expression,
out ValueResolver<T> resolver)
{
if (expression.IndexOf('.') == -1)
{
resolver = null;
return false;
}
var separatorIndex = expression.LastIndexOf('.');
var className = expression.Substring(0, separatorIndex);
var methodName = expression.Substring(separatorIndex + 1);
if (!TriReflectionUtilities.TryFindTypeByFullName(className, out var type))
{
resolver = null;
return false;
}
const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var propertyInfo in type.GetProperties(flags))
{
if (propertyInfo.Name == methodName &&
typeof(T).IsAssignableFrom(propertyInfo.PropertyType) &&
propertyInfo.CanRead)
{
resolver = new StaticPropertyValueResolver<T>(propertyInfo);
return true;
}
}
resolver = null;
return false;
}
public StaticPropertyValueResolver(PropertyInfo propertyInfo)
{
_propertyInfo = propertyInfo;
}
public override bool TryGetErrorString(out string error)
{
error = "";
return false;
}
public override T GetValue(TriProperty property, T defaultValue = default)
{
try
{
return (T) _propertyInfo.GetValue(null);
}
catch (Exception e)
{
if (e is TargetInvocationException targetInvocationException)
{
e = targetInvocationException.InnerException;
}
Debug.LogException(e);
return defaultValue;
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8cbab37d02e54764a8b1ae73eac12d8a
timeCreated: 1657955361

View File

@ -7,6 +7,21 @@ namespace TriInspector.Resolvers
public static ValueResolver<T> Resolve<T>(TriPropertyDefinition propertyDefinition, public static ValueResolver<T> Resolve<T>(TriPropertyDefinition propertyDefinition,
string expression) string expression)
{ {
if (StaticFieldValueResolver<T>.TryResolve(propertyDefinition, expression, out var sfr))
{
return sfr;
}
if (StaticPropertyValueResolver<T>.TryResolve(propertyDefinition, expression, out var spr))
{
return spr;
}
if (StaticMethodValueResolver<T>.TryResolve(propertyDefinition, expression, out var smr))
{
return smr;
}
if (InstanceFieldValueResolver<T>.TryResolve(propertyDefinition, expression, out var ifr)) if (InstanceFieldValueResolver<T>.TryResolve(propertyDefinition, expression, out var ifr))
{ {
return ifr; return ifr;

View File

@ -122,6 +122,26 @@ namespace TriInspector.Utilities
.Single(it => it.FullName == name); .Single(it => it.FullName == name);
} }
public static bool TryFindTypeByFullName(string name, out Type type)
{
type = Type.GetType(name);
if (type != null)
{
return true;
}
foreach (var assembly in Assemblies)
{
type = assembly.GetType(name);
if (type != null)
{
return true;
}
}
return false;
}
private static IReadOnlyList<T> GetAllMembersInDeclarationOrder<T>( private static IReadOnlyList<T> GetAllMembersInDeclarationOrder<T>(
Type type, Func<Type, T[]> select) Type type, Func<Type, T[]> select)
where T : MemberInfo where T : MemberInfo