Merge pull request #165 from dwango/work_aot_2

Removed Expression.Compile
This commit is contained in:
yutopp 2019-02-04 17:24:21 +09:00 committed by GitHub
commit 0e5ea326a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 462 additions and 258 deletions

View File

@ -20,6 +20,11 @@ namespace UniJSON
{
Value = value;
}
public int Get(int _)
{
return Value;
}
}
@ -29,15 +34,27 @@ namespace UniJSON
{
var s = new Sample();
var mi = s.GetType().GetMethod("Set");
var invoke = (Action<Sample, int>)GenericInvokeCallFactory.Create<Sample, int>(mi);
invoke(s, 1);
Assert.AreEqual(1, s.Value);
{
var mi = s.GetType().GetMethod("Set");
var action = GenericInvokeCallFactory.OpenAction<Sample, int>(mi);
action(s, 1);
Assert.AreEqual(1, s.Value);
}
var exp = (Action<Sample, int>)GenericExpressionCallFactory.Create<Sample, int>(mi);
exp(s, 2);
Assert.AreEqual(2, s.Value);
{
var mi = s.GetType().GetMethod("Get");
var func = GenericInvokeCallFactory.OpenFunc<Sample, int, int>(mi);
var value = func(s, 1);
Assert.AreEqual(1, s.Value);
}
{
var mi = s.GetType().GetMethod("Set");
var action = GenericExpressionCallFactory.Create<Sample, int>(mi);
action(s, 2);
Assert.AreEqual(2, s.Value);
}
}
}
}

View File

@ -45,23 +45,20 @@ namespace UniJSON
return method.MakeGenericMethod(typeof(T));
}
[Obsolete("error when AOT. use Key, Value")]
//
// https://stackoverflow.com/questions/238765/given-a-type-expressiontype-memberaccess-how-do-i-get-the-field-value
//
public static void KeyValue<T>(this IFormatter f, Expression<Func<T>> expression)
{
var func = expression.Compile();
var value = func();
if (value != null)
{
var body = expression.Body as MemberExpression;
if (body == null)
{
body = ((UnaryExpression)expression.Body).Operand as MemberExpression;
}
f.Key(body.Member.Name);
f.Serialize(expression.Compile()());
//var method = GetMethod(expression);
//method.Invoke(this, new object[] { value });
}
MemberExpression outerMember = (MemberExpression)expression.Body;
var outerProp = (FieldInfo)outerMember.Member;
MemberExpression innerMember = (MemberExpression)outerMember.Expression;
var innerField = (FieldInfo)innerMember.Member;
ConstantExpression ce = (ConstantExpression)innerMember.Expression;
object innerObj = ce.Value;
object outerObj = innerField.GetValue(innerObj);
f.Key(outerProp.Name);
f.Serialize(outerProp.GetValue(outerObj));
}
}
}

View File

@ -84,7 +84,7 @@ namespace UniJSON
if (typeof(T) == typeof(object) && t.GetType() != typeof(object))
{
var mi = FormatterExtensionsSerializer.GetMethod("SerializeObject");
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
return GenericInvokeCallFactory.StaticAction<IFormatter, T>(mi);
}
try
@ -93,7 +93,7 @@ namespace UniJSON
var mi = typeof(IFormatter).GetMethod("Value", new Type[] { t });
if (mi != null)
{
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
return GenericInvokeCallFactory.OpenAction<IFormatter, T>(mi);
}
}
catch (AmbiguousMatchException)
@ -111,7 +111,7 @@ namespace UniJSON
if (idictionary != null)
{
var mi = FormatterExtensionsSerializer.GetMethod("SerializeDictionary");
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
return GenericInvokeCallFactory.StaticAction<IFormatter, T>(mi);
}
}
@ -120,7 +120,7 @@ namespace UniJSON
if (t == typeof(object[]))
{
var mi = FormatterExtensionsSerializer.GetMethod("SerializeObjectArray");
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
return GenericInvokeCallFactory.StaticAction<IFormatter, T>(mi);
}
}
@ -134,7 +134,7 @@ namespace UniJSON
{
var g = FormatterExtensionsSerializer.GetMethod("SerializeArray");
var mi = g.MakeGenericMethod(ienumerable.GetGenericArguments());
return GenericInvokeCallFactory.Create<IFormatter, T>(mi);
return GenericInvokeCallFactory.StaticAction<IFormatter, T>(mi);
}
}

View File

@ -1,15 +1,23 @@
using System;
using System.Reflection;
#if UNITY_EDITOR && VRM_DEVELOP
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniJSON
{
/// <summary>
/// MethodInfoからDelegateを作成する
///
/// * StaticAction/Func StaticMethod呼び出し
/// * OpenAction/Func 第1引数にthisを受けるメソッド呼び出し
/// * BindAction/Func thisを内部に保持したメソッド呼び出し
///
/// </summary>
public static partial class GenericInvokeCallFactory
{
#if UNITY_EDITOR && VRM_DEVELOP
@ -42,36 +50,22 @@ namespace UniJSON
{
");
// CreateWithThis
w.WriteLine("//////////// Create");
// Create
for (int i = 1; i <= ARGS && i< NET35MAX; ++i)
// StaticAction
w.WriteLine("//////////// StaticAction");
for (int i = 1; i <= ARGS && i <= NET35MAX; ++i)
{
var g = String.Join(", ", GetArgs("A", i).ToArray());
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Action<S, $0> Create<S, $0>(MethodInfo m)
public static Action<$0> StaticAction<$0>(MethodInfo m)
{
Action<S, $0> callback = null;
if (m.IsStatic)
if (!m.IsStatic)
{
callback = (s, $1) =>
{
m.Invoke(null, new object[] { s, $1 });
};
throw new ArgumentException(string.Format(""{0} is not static"", m));
}
else
{
callback = (s, $1) =>
{
m.Invoke(s, new object[] { $1 });
};
}
return callback;
return (Action<$0>)Delegate.CreateDelegate(typeof(Action<$0>), null, m);
}
".Replace("$0", g).Replace("$1", a);
@ -79,42 +73,119 @@ namespace UniJSON
}
// CreateWithThis
w.WriteLine("//////////// CreateWithThis");
for (int i = 1; i <= ARGS && i<= NET35MAX; ++i)
// OpenAction
w.WriteLine("//////////// OpenAction");
for (int i = 1; i <= ARGS && i < NET35MAX; ++i)
{
var g = String.Join(", ", GetArgs("A", i).ToArray());
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Action<$0> CreateWithThis<S, $0>(MethodInfo m, S instance)
public static Action<S, $0> OpenAction<S, $0>(MethodInfo m)
{
if (m.IsStatic)
{
if (instance != null)
{
throw new ArgumentException();
}
}
else
{
if (instance == null)
{
throw new ArgumentNullException();
}
throw new ArgumentException(string.Format(""{0} is static"", m));
}
// ToDo: CreateDelegate
Action<$0> callback=
($1) => {
m.Invoke(instance, new object[]{ $1 });
};
return callback;
return (Action<S, $0>)Delegate.CreateDelegate(typeof(Action<S, $0>), m);
}
".Replace("$0", g).Replace("$1", a);
w.WriteLine(source);
}
// BindAction
w.WriteLine("//////////// BindAction");
for (int i = 1; i <= ARGS && i <= NET35MAX; ++i)
{
var g = String.Join(", ", GetArgs("A", i).ToArray());
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Action<$0> BindAction<S, $0>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format(""{0} is static"", m));
}
return (Action<$0>)Delegate.CreateDelegate(typeof(Action<$0>), instance, m);
}
".Replace("$0", g).Replace("$1", a);
w.WriteLine(source);
}
// StaticFunc
w.WriteLine("//////////// StaticFunc");
for (int i = 1; i <= ARGS && i <= NET35MAX; ++i)
{
var g = String.Join(", ", GetArgs("A", i).ToArray());
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Func<$0, T> StaticFunc<$0, T>(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format(""{0} is not static"", m));
}
return (Func<$0, T>)Delegate.CreateDelegate(typeof(Func<$0, T>), null, m);
}
".Replace("$0", g).Replace("$1", a);
w.WriteLine(source);
}
// OpenFunc
w.WriteLine("//////////// OpenFunc");
for (int i = 1; i <= ARGS && i < NET35MAX; ++i)
{
var g = String.Join(", ", GetArgs("A", i).ToArray());
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Func<S, $0, T> OpenFunc<S, $0, T>(MethodInfo m)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format(""{0} is static"", m));
}
return (Func<S, $0, T>)Delegate.CreateDelegate(typeof(Func<S, $0, T>), m);
}
".Replace("$0", g).Replace("$1", a);
w.WriteLine(source);
}
// BindFunc
w.WriteLine("//////////// BindFunc");
for (int i = 1; i <= ARGS && i <= NET35MAX; ++i)
{
var g = String.Join(", ", GetArgs("A", i).ToArray());
var a = String.Join(", ", GetArgs("a", i).ToArray());
var source = @"
public static Func<$0, T> BindFunc<S, $0, T>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format(""{0} is static"", m));
}
return (Func<$0, T>)Delegate.CreateDelegate(typeof(Func<$0, T>), instance, m);
}
".Replace("$0", g).Replace("$1", a);
w.WriteLine(source);
}
@ -130,22 +201,74 @@ namespace UniJSON
}
#endif
#region no arguments
public static Action<S> Create<S>(MethodInfo m)
#region Action without arguments
public static Action StaticAction(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is not static", m));
}
return (Action)Delegate.CreateDelegate(typeof(Action), null, m);
}
public static Action<S> OpenAction<S>(MethodInfo m)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (s) =>
{
m.Invoke(s, new object[] { });
};
}
public static Action CreateWithThis<S>(MethodInfo m, S instance)
public static Action BindAction<S>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return () =>
{
m.Invoke(instance, new object[] { });
};
}
#endregion
#region Func without arguments
public static Func<T> StaticFunc<T>(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is not static", m));
}
return () => (T)m.Invoke(null, new object[] { });
}
public static Func<S, T> OpenFunc<S, T>(MethodInfo m)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (s) => (T)m.Invoke(s, new object[] { });
}
public static Func<T> BindFunc<S, T>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return () => (T)m.Invoke(instance, new object[] { });
}
#endregion
}
}

View File

@ -8,173 +8,252 @@ namespace UniJSON
public static partial class GenericInvokeCallFactory
{
//////////// Create
//////////// StaticAction
public static Action<S, A0> Create<S, A0>(MethodInfo m)
public static Action<A0> StaticAction<A0>(MethodInfo m)
{
Action<S, A0> callback = null;
if (m.IsStatic)
if (!m.IsStatic)
{
callback = (s, a0) =>
{
m.Invoke(null, new object[] { s, a0 });
};
throw new ArgumentException(string.Format("{0} is not static", m));
}
else
{
callback = (s, a0) =>
{
m.Invoke(s, new object[] { a0 });
};
}
return callback;
return (Action<A0>)Delegate.CreateDelegate(typeof(Action<A0>), null, m);
}
public static Action<S, A0, A1> Create<S, A0, A1>(MethodInfo m)
public static Action<A0, A1> StaticAction<A0, A1>(MethodInfo m)
{
Action<S, A0, A1> callback = null;
if (m.IsStatic)
if (!m.IsStatic)
{
callback = (s, a0, a1) =>
{
m.Invoke(null, new object[] { s, a0, a1 });
};
throw new ArgumentException(string.Format("{0} is not static", m));
}
else
{
callback = (s, a0, a1) =>
{
m.Invoke(s, new object[] { a0, a1 });
};
}
return callback;
return (Action<A0, A1>)Delegate.CreateDelegate(typeof(Action<A0, A1>), null, m);
}
public static Action<S, A0, A1, A2> Create<S, A0, A1, A2>(MethodInfo m)
public static Action<A0, A1, A2> StaticAction<A0, A1, A2>(MethodInfo m)
{
Action<S, A0, A1, A2> callback = null;
if (m.IsStatic)
if (!m.IsStatic)
{
callback = (s, a0, a1, a2) =>
{
m.Invoke(null, new object[] { s, a0, a1, a2 });
};
}
else
{
callback = (s, a0, a1, a2) =>
{
m.Invoke(s, new object[] { a0, a1, a2 });
};
}
return callback;
}
//////////// CreateWithThis
public static Action<A0> CreateWithThis<S, A0>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
if (instance != null)
{
throw new ArgumentException();
}
}
else
{
if (instance == null)
{
throw new ArgumentNullException();
}
throw new ArgumentException(string.Format("{0} is not static", m));
}
// ToDo: CreateDelegate
Action<A0> callback=
(a0) => {
m.Invoke(instance, new object[]{ a0 });
};
return callback;
return (Action<A0, A1, A2>)Delegate.CreateDelegate(typeof(Action<A0, A1, A2>), null, m);
}
public static Action<A0, A1> CreateWithThis<S, A0, A1>(MethodInfo m, S instance)
public static Action<A0, A1, A2, A3> StaticAction<A0, A1, A2, A3>(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is not static", m));
}
return (Action<A0, A1, A2, A3>)Delegate.CreateDelegate(typeof(Action<A0, A1, A2, A3>), null, m);
}
//////////// OpenAction
public static Action<S, A0> OpenAction<S, A0>(MethodInfo m)
{
if (m.IsStatic)
{
if (instance != null)
{
throw new ArgumentException();
}
}
else
{
if (instance == null)
{
throw new ArgumentNullException();
}
throw new ArgumentException(string.Format("{0} is static", m));
}
// ToDo: CreateDelegate
Action<A0, A1> callback=
(a0, a1) => {
m.Invoke(instance, new object[]{ a0, a1 });
};
return callback;
return (Action<S, A0>)Delegate.CreateDelegate(typeof(Action<S, A0>), m);
}
public static Action<A0, A1, A2> CreateWithThis<S, A0, A1, A2>(MethodInfo m, S instance)
public static Action<S, A0, A1> OpenAction<S, A0, A1>(MethodInfo m)
{
if (m.IsStatic)
{
if (instance != null)
{
throw new ArgumentException();
}
}
else
{
if (instance == null)
{
throw new ArgumentNullException();
}
throw new ArgumentException(string.Format("{0} is static", m));
}
// ToDo: CreateDelegate
Action<A0, A1, A2> callback=
(a0, a1, a2) => {
m.Invoke(instance, new object[]{ a0, a1, a2 });
};
return callback;
return (Action<S, A0, A1>)Delegate.CreateDelegate(typeof(Action<S, A0, A1>), m);
}
public static Action<A0, A1, A2, A3> CreateWithThis<S, A0, A1, A2, A3>(MethodInfo m, S instance)
public static Action<S, A0, A1, A2> OpenAction<S, A0, A1, A2>(MethodInfo m)
{
if (m.IsStatic)
{
if (instance != null)
{
throw new ArgumentException();
}
}
else
{
if (instance == null)
{
throw new ArgumentNullException();
}
throw new ArgumentException(string.Format("{0} is static", m));
}
// ToDo: CreateDelegate
Action<A0, A1, A2, A3> callback=
(a0, a1, a2, a3) => {
m.Invoke(instance, new object[]{ a0, a1, a2, a3 });
};
return callback;
return (Action<S, A0, A1, A2>)Delegate.CreateDelegate(typeof(Action<S, A0, A1, A2>), m);
}
//////////// BindAction
public static Action<A0> BindAction<S, A0>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (Action<A0>)Delegate.CreateDelegate(typeof(Action<A0>), instance, m);
}
public static Action<A0, A1> BindAction<S, A0, A1>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (Action<A0, A1>)Delegate.CreateDelegate(typeof(Action<A0, A1>), instance, m);
}
public static Action<A0, A1, A2> BindAction<S, A0, A1, A2>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (Action<A0, A1, A2>)Delegate.CreateDelegate(typeof(Action<A0, A1, A2>), instance, m);
}
public static Action<A0, A1, A2, A3> BindAction<S, A0, A1, A2, A3>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (Action<A0, A1, A2, A3>)Delegate.CreateDelegate(typeof(Action<A0, A1, A2, A3>), instance, m);
}
//////////// StaticFunc
public static Func<A0, T> StaticFunc<A0, T>(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is not static", m));
}
return (a0) => (T)m.Invoke(null, new object[] { a0 });
}
public static Func<A0, A1, T> StaticFunc<A0, A1, T>(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is not static", m));
}
return (a0, a1) => (T)m.Invoke(null, new object[] { a0, a1 });
}
public static Func<A0, A1, A2, T> StaticFunc<A0, A1, A2, T>(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is not static", m));
}
return (a0, a1, a2) => (T)m.Invoke(null, new object[] { a0, a1, a2 });
}
public static Func<A0, A1, A2, A3, T> StaticFunc<A0, A1, A2, A3, T>(MethodInfo m)
{
if (!m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is not static", m));
}
return (a0, a1, a2, a3) => (T)m.Invoke(null, new object[] { a0, a1, a2, a3 });
}
//////////// OpenFunc
public static Func<S, A0, T> OpenFunc<S, A0, T>(MethodInfo m)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (s, a0) => (T)m.Invoke(s, new object[] { a0 });
}
public static Func<S, A0, A1, T> OpenFunc<S, A0, A1, T>(MethodInfo m)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (s, a0, a1) => (T)m.Invoke(s, new object[] { a0, a1 });
}
public static Func<S, A0, A1, A2, T> OpenFunc<S, A0, A1, A2, T>(MethodInfo m)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (s, a0, a1, a2) => (T)m.Invoke(s, new object[] { a0, a1, a2 });
}
//////////// BindFunc
public static Func<A0, T> BindFunc<S, A0, T>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (a0) => (T)m.Invoke(instance, new object[] { a0 });
}
public static Func<A0, A1, T> BindFunc<S, A0, A1, T>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (a0, a1) => (T)m.Invoke(instance, new object[] { a0, a1 });
}
public static Func<A0, A1, A2, T> BindFunc<S, A0, A1, A2, T>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (a0, a1, a2) => (T)m.Invoke(instance, new object[] { a0, a1, a2 });
}
public static Func<A0, A1, A2, A3, T> BindFunc<S, A0, A1, A2, A3, T>(MethodInfo m, S instance)
{
if (m.IsStatic)
{
throw new ArgumentException(string.Format("{0} is static", m));
}
return (a0, a1, a2, a3) => (T)m.Invoke(instance, new object[] { a0, a1, a2, a3 });
}

View File

@ -56,10 +56,7 @@ namespace UniJSON
}
else
{
return (Func<S, T>)((S s) =>
{
return (T)mi.Invoke(null, new object[] { s });
});
return GenericInvokeCallFactory.StaticFunc<S, T>(mi);
}
}

View File

@ -264,7 +264,7 @@ namespace UniJSON
IFormatter,
JsonSchemaValidationContext,
T>)
GenericInvokeCallFactory.Create<
GenericInvokeCallFactory.StaticAction<
IJsonSchemaValidator,
IFormatter,
JsonSchemaValidationContext,

View File

@ -319,9 +319,11 @@ namespace UniJSON
var mi = typeof(Enum).GetMethods(BindingFlags.Static | BindingFlags.Public).First(
x => x.Name == "Parse" && x.GetParameters().Length == 3
);
var enumParse = GenericInvokeCallFactory.StaticFunc<Type, string, bool, object>(mi);
s_d = x =>
{
var enumValue = mi.Invoke(null, new object[] { typeof(U), x.GetString(), true });
var enumValue = enumParse(typeof(U), x.GetString(), true);
return GenericCast<object, U>.Cast(enumValue);
};
}

View File

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace UniJSON
{
/// <summary>
@ -306,27 +306,13 @@ namespace UniJSON
}
public static void CreateFieldProcessors<G, D>(
string methodName,
Func<FieldInfo, D> creator,
Dictionary<string, D> processors
)
{
var mi = typeof(G).GetMethod(methodName, BindingFlags.Static | BindingFlags.NonPublic);
var t = typeof(T);
foreach (var fi in GetFields())
{
var value = Expression.Parameter(t, "value");
var fieldValue = Expression.Field(value, fi);
var compileld = Expression.Lambda(fieldValue, value).Compile();
var getter = Expression.Constant(compileld);
var name = Expression.Constant(fi.Name);
var g = mi.MakeGenericMethod(fi.FieldType);
var call = Expression.Call(g, getter, name);
var lambda = (Func<D>)Expression.Lambda(call).Compile();
processors.Add(fi.Name, lambda());
processors.Add(fi.Name, creator(fi));
}
}
}
@ -346,12 +332,23 @@ namespace UniJSON
Dictionary<string, FieldValidator> m_validators;
static FieldValidator CreateFieldValidator<U>(Func<T, U> getter, string name)
static FieldValidator CreateFieldValidator(FieldInfo fi)
{
var mi = typeof(ObjectValidator).GetMethod("_CreateFieldValidator",
BindingFlags.Static | BindingFlags.NonPublic)
;
var g = mi.MakeGenericMethod(fi.FieldType);
return GenericInvokeCallFactory.StaticFunc<FieldInfo, FieldValidator>(g)(fi);
}
static FieldValidator _CreateFieldValidator<U>(FieldInfo fi)
{
var getter = (Func<T, U>)((t) => (U)fi.GetValue(t));
return (JsonSchema s, JsonSchemaValidationContext c, T o, out bool isIgnorable) =>
{
var v = s.Validator;
using (c.Push(name))
using (c.Push(fi.Name))
{
var field = getter(o);
var ex = v.Validate(c, field);
@ -367,7 +364,7 @@ namespace UniJSON
{
var validators = new Dictionary<string, FieldValidator>();
GenericFieldView<T>.CreateFieldProcessors<ObjectValidator, FieldValidator>(
"CreateFieldValidator", validators);
CreateFieldValidator, validators);
m_validators = validators;
}
@ -496,14 +493,27 @@ namespace UniJSON
Dictionary<string, FieldSerializer> m_serializers;
static FieldSerializer CreateFieldSerializer<U>(Func<T, U> getter, string name)
static FieldSerializer CreateFieldSerializer(FieldInfo fi)
{
var mi = typeof(Serializer).GetMethod("_CreateFieldSerializer",
BindingFlags.Static | BindingFlags.NonPublic);
var g = mi.MakeGenericMethod(fi.FieldType);
return GenericInvokeCallFactory.StaticFunc<FieldInfo, FieldSerializer>(g)(fi);
}
static FieldSerializer _CreateFieldSerializer<U>(FieldInfo fi)
{
Func<T, U> getter = t =>
{
return (U)fi.GetValue(t);
};
return (s, c, f, o, vRes, deps) =>
{
var v = s.Validator;
var field = getter(o);
if (vRes[name].Ex != null)
if (vRes[fi.Name].Ex != null)
{
return;
}
@ -519,7 +529,7 @@ namespace UniJSON
}
}
f.Key(name);
f.Key(fi.Name);
v.Serialize(f, c, field);
};
}
@ -528,7 +538,7 @@ namespace UniJSON
{
var serializers = new Dictionary<string, FieldSerializer>();
GenericFieldView<T>.CreateFieldProcessors<Serializer, FieldSerializer>(
"CreateFieldSerializer", serializers);
CreateFieldSerializer, serializers);
m_serializers = serializers;
}

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@ -30,10 +29,7 @@ namespace UniJSON
var mi = typeof(GenericCreator<T, U>).GetMethod("ArrayCreator",
BindingFlags.NonPublic | BindingFlags.Static);
var g = mi.MakeGenericMethod(t.GetElementType());
var src = Expression.Parameter(typeof(T), "src");
var call = Expression.Call(g, src);
var func = Expression.Lambda(call, src);
return (Func<ListTreeNode<T>, U>)func.Compile();
return GenericInvokeCallFactory.StaticFunc<ListTreeNode<T>, U>(g);
}
{
@ -180,10 +176,7 @@ namespace UniJSON
if (mi != null)
{
var self = Expression.Parameter(typeof(ListTreeNode<T>), "self");
var call = Expression.Call(self, mi);
var func = Expression.Lambda(call, self);
return (Func<ListTreeNode<T>, U>)func.Compile();
return GenericInvokeCallFactory.StaticFunc<ListTreeNode<T>, U>(mi);
}
}
@ -194,10 +187,7 @@ namespace UniJSON
var mi = typeof(GenericDeserializer<T, U>).GetMethod("GenericArrayDeserializer",
BindingFlags.Static | BindingFlags.NonPublic);
var g = mi.MakeGenericMethod(target.GetElementType());
var self = Expression.Parameter(typeof(ListTreeNode<T>), "self");
var call = Expression.Call(g, self);
var func = Expression.Lambda(call, self);
return (Func<ListTreeNode<T>, U>)func.Compile();
return GenericInvokeCallFactory.StaticFunc<ListTreeNode<T>, U>(g);
}
if (target.IsGenericType)
@ -207,10 +197,7 @@ namespace UniJSON
var mi = typeof(GenericDeserializer<T, U>).GetMethod("GenericListDeserializer",
BindingFlags.Static | BindingFlags.NonPublic);
var g = mi.MakeGenericMethod(target.GetGenericArguments());
var self = Expression.Parameter(typeof(ListTreeNode<T>), "self");
var call = Expression.Call(g, self);
var func = Expression.Lambda(call, self);
return (Func<ListTreeNode<T>, U>)func.Compile();
return GenericInvokeCallFactory.StaticFunc<ListTreeNode<T>, U>(g);
}
if (target.GetGenericTypeDefinition() == typeof(Dictionary<,>) &&
@ -219,15 +206,7 @@ namespace UniJSON
var mi = typeof(ListTreeNodeDeserializerExtensions).GetMethod("DictionaryDeserializer",
BindingFlags.Static | BindingFlags.NonPublic);
var g = mi.MakeGenericMethod(typeof(T));
var self = Expression.Parameter(typeof(ListTreeNode<T>), "self");
var call = Expression.Call(g, self);
var func = Expression.Lambda(call, self);
var d = (Func<ListTreeNode<T>, object>)func.Compile();
return (ListTreeNode<T> s) =>
{
var x = d(s);
return (U)x;
};
return GenericInvokeCallFactory.StaticFunc<ListTreeNode<T>, U>(g);
}
}