110 lines
5.4 KiB
C#
110 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
|
|
namespace CPF.Windows.Json.Deserialize
|
|
{
|
|
[ExpressionBuildType(DeserializeBuildTypeEnum.Dynamic)]
|
|
internal class DynamicBuild : ExpressionJsonResolve
|
|
{
|
|
internal static BlockExpression Build(Type type)
|
|
{
|
|
List<Expression> methodCall = new List<Expression>();
|
|
LabelTarget returnValueLable = Expression.Label(type, "returnValue");
|
|
|
|
var c = type.GetProperties();
|
|
ParameterExpression[] ctorArgs = null;
|
|
if (c.Length > 0)
|
|
{
|
|
ctorArgs = new ParameterExpression[c.Length];
|
|
for (int i = 0; i < c.Length; i++)
|
|
{
|
|
ctorArgs[i] = Expression.Variable(c[i].PropertyType);
|
|
if (c[i].PropertyType.IsValueType)
|
|
methodCall.Add(Expression.Assign(ctorArgs[i], Expression.New(c[i].PropertyType)));
|
|
else
|
|
methodCall.Add(Expression.Assign(ctorArgs[i], Expression.Constant(null, c[i].PropertyType)));
|
|
}
|
|
}
|
|
methodCall.Add(Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrObjLeft), Expression.Return(returnValueLable, Expression.Constant(null, type))));
|
|
|
|
methodCall.Add(Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolObjRight), Expression.Return(returnValueLable, c.Length == 0 ? Expression.New(type) : Expression.New(type.GetConstructors()[0], ctorArgs))));
|
|
/*
|
|
read.ReadLeftOrNull()
|
|
return null
|
|
if(_ReadBoolObjRight)
|
|
reture new (default)
|
|
int a;
|
|
string b;
|
|
i=2
|
|
while(i-->0)
|
|
{
|
|
var s= readString;
|
|
ReadColon()
|
|
switch(s)
|
|
case(s=='Name')
|
|
b=readValue
|
|
|
|
case(s=='Age')
|
|
a=readValue
|
|
arrig=true
|
|
if(!arrig)
|
|
throw
|
|
if(comma())
|
|
i++;
|
|
}
|
|
readRight();
|
|
return new dynamicModel(a,b)
|
|
*/
|
|
List<ParameterExpression> args = new List<ParameterExpression>() { };
|
|
if (c.Length > 0)
|
|
{
|
|
ParameterExpression str = Expression.Variable(typeof(string), "str");
|
|
LabelTarget whileBreak = Expression.Label();
|
|
methodCall.Add(ExpressionMembers.MoveNextAssignOne);
|
|
LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
|
|
ReturnFunc<Expression>(() =>
|
|
{
|
|
Expression[] expressions = new Expression[5];
|
|
expressions[0] = Expression.Assign(str, Expression.Call(ExpressionMembers.Reader, JsonReader._ReadString));
|
|
expressions[1] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon);
|
|
expressions[2] = Expression.Switch(str,
|
|
ReturnFunc(() =>
|
|
{
|
|
SwitchCase[] switchCases = new SwitchCase[c.Length];
|
|
for (int i = 0; i < c.Length; i++)
|
|
{
|
|
switchCases[i] = Expression.SwitchCase(
|
|
Expression.Block(typeof(void),
|
|
Expression.Assign(ctorArgs[i], ExpressionMembers.GetMethodCall(c[i].PropertyType)),
|
|
ExpressionMembers.IsArriveAssignTrue
|
|
)
|
|
, Expression.Constant(c[i].Name, typeof(string)));
|
|
}
|
|
return switchCases;
|
|
})
|
|
);
|
|
expressions[3] = Expression.IfThen(Expression.Equal(ExpressionMembers.IsArrive, Expression.Constant(false, typeof(bool))), Expression.Throw(Expression.New(JsonDeserializationTypeResolutionException._JsonDeserializationTypeResolutionExceptionMsgCtor, Expression.Constant("An error occurred parsing the dynamically typed key. The key does not match", typeof(string)))));
|
|
expressions[4] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement;
|
|
return Expression.Block(expressions);
|
|
}),
|
|
Expression.Break(whileBreak)
|
|
));
|
|
methodCall.Add(loopExpression);
|
|
methodCall.Add(Expression.Label(whileBreak));
|
|
args.Add(str);
|
|
args.AddRange(ctorArgs);
|
|
}
|
|
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight));
|
|
methodCall.Add(Expression.Return(returnValueLable, c.Length == 0 ? Expression.New(type) : Expression.New(type.GetConstructors()[0], ctorArgs)));
|
|
methodCall.Add(Expression.Label(returnValueLable, Expression.Constant(null, type)));
|
|
|
|
|
|
args.Add(ExpressionMembers.IsArrive);
|
|
args.Add(ExpressionMembers.MoveNext);
|
|
return Expression.Block(args, methodCall);
|
|
|
|
}
|
|
}
|
|
}
|