Exemplo n.º 1
0
        internal static BlockExpression Build(Type type)
        {
            Type keyType   = type.GetGenericArguments()[0];
            Type valueType = type.GetGenericArguments()[1];
            List <Expression> methodCall = new List <Expression>();
            Type        keyValuePairType = typeof(KeyValuePair <,>).MakeGenericType(keyType, valueType);
            LabelTarget returnValueLable = Expression.Label(keyValuePairType, "returnValue");

            ConstructorInfo     ctor  = keyValuePairType.GetConstructor(new[] { keyType, valueType });
            ParameterExpression key   = Expression.Variable(keyType, "key");
            ParameterExpression value = Expression.Variable(valueType, "value");

            /*
             *  ReadObjLeft()
             */
            methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjLeft));

            /*
             *  if(reader.ReadBoolObjRight)
             *          return new KeyValuePair<,>(default,default);
             */
            methodCall.Add(
                Expression.IfThen(
                    Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolObjRight),
                    Expression.Return(returnValueLable, Expression.New(ctor, keyType.IsValueType ? (Expression)Expression.New(keyType) : Expression.Constant(null, keyType), valueType.IsValueType ? (Expression)Expression.New(valueType) : Expression.Constant(null, valueType)))));

            /*
             * ReadKey()
             */
            methodCall.Add(ExpressionMembers.GenerateKeyValuePairByReadKey(keyType, key));

            /*
             * reader.ReadColon()
             */
            methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon));

            /*
             * value = ResolveProvider<ValueType>.InvokeGet(reader, handler);
             */
            methodCall.Add(Expression.Assign(value, ExpressionMembers.GetMethodCall(valueType)));

            /*
             * reader.ReadObjRight();
             */
            methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight));

            /*
             * return new KeyValuePair<,>(key,value);
             */
            methodCall.Add(Expression.Return(returnValueLable, Expression.New(ctor, key, value)));
            methodCall.Add(Expression.Label(returnValueLable, Expression.New(ctor, key, value)));

            return(Expression.Block(new[] { key, value }, methodCall));
        }
Exemplo n.º 2
0
        internal static BlockExpression Build(Type type)
        {
            LabelTarget         returnTarget = Expression.Label(type, "returnLable");
            Type                elementType  = type.GetGenericArguments()[0];
            ParameterExpression element      = Expression.Variable(elementType, "element");
            var ctr = type.GetAppointTypeCtor(typeof(Func <>).MakeGenericType(elementType));

            return(Expression.Block(new[] { element },
                                    Expression.IfThenElse(
                                        Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolNull),
                                        Expression.Return(returnTarget, Expression.Constant(null, type)),
                                        Expression.Block(
                                            Expression.Assign(element, ExpressionMembers.GetMethodCall(elementType)), //inject = Read<T>();  T-->)
                                            Expression.Return(returnTarget, Expression.New(ctr, Expression.Call(_TransitionFunc.MakeGenericMethod(elementType), element)))
                                            )),
                                    Expression.Label(returnTarget, Expression.Constant(null, type))
                                    ));
        }
Exemplo n.º 3
0
        internal static BlockExpression Build(Type type, Type injectType, ConstructorInfo ctr)
        {
            LabelTarget returnTarget = Expression.Label(type, "returnLable");

            ParameterExpression inject = Expression.Variable(injectType, "inject");

            if (!type.IsValueType)
            {
                return(Expression.Block(new[] { inject },

                                        Expression.Assign(inject, ExpressionMembers.GetMethodCall(injectType)),//inject = Read<T>();  T-->
                                        Expression.IfThenElse(
                                            Expression.Equal(inject, Expression.Constant(null, injectType)),
                                            Expression.Return(returnTarget, Expression.Constant(null, type)),
                                            Expression.Return(returnTarget, Expression.Convert(Expression.New(ctr, inject), type))),
                                        Expression.Label(returnTarget, Expression.Constant(null, type))
                                        ));
            }

            return(Expression.Block(new[] { inject },
                                    Expression.Assign(inject, ExpressionMembers.GetMethodCall(injectType)),
                                    Expression.Return(returnTarget, Expression.Convert(Expression.New(ctr, inject), type)),
                                    Expression.Label(returnTarget, Expression.Convert(Expression.New(ctr, inject), type))));
        }
Exemplo n.º 4
0
        private static BlockExpression GenerateValueFormatCode(Expression formatDeclareInstance, MethodInfo callFormat, Expression[] paras, ParameterExpression newModel, MemberExtension member)
        {
            Expression[] expressions = new Expression[6];

            /*
             * reader.BeforAnnotation();
             * reader.RollBackChar()
             */
            expressions[0] = Expression.Call(ExpressionMembers.Reader, JsonReader._BeforAnnotation);
            expressions[1] = Expression.Call(ExpressionMembers.Reader, JsonReader._RollbackChar);

            /*
             * currentIdx= Length - reader.Remaining
             */
            expressions[2] = ExpressionMembers.CurrentIdxAssignReming;

            /*
             * valueLength=reader.Skipobj()
             */
            expressions[3] = (ExpressionMembers.ValueLengthAssignSkipObj);

            /*
             * object formatResult = ValueFormat.ReadValueFormat(  reader.Substring(currentIdx,valueLength) ,out isValueFormat);
             */
            expressions[4] = (Expression.Assign(ExpressionMembers.FormatResult, Expression.Call(formatDeclareInstance, callFormat, paras)));

            /*
             * if(isValueFormat==true)
             *   model.N=(Convert)obj;
             * else
             *  reader.Rollback(valueLength)
             *  m.N=ReadJson();//string
             */
            expressions[5] = (Expression.IfThenElse(ExpressionMembers.IsValueFormatEqualTrue, Expression.Assign(Expression.MakeMemberAccess(newModel, member.MemberInfo), Expression.Convert(ExpressionMembers.FormatResult, member.Type)), Expression.Block(Expression.Call(ExpressionMembers.Reader, JsonReader._Rollback, ExpressionMembers.ValueLength), Expression.Assign(Expression.MakeMemberAccess(newModel, member.MemberInfo), ExpressionMembers.GetMethodCall(member.Type)))));

            return(Expression.Block(expressions));
        }
Exemplo n.º 5
0
 private static Expression GenerateKeyValueObjectReadValue(MemberExtension member, ParameterExpression newModel)
 {
     if (!member.IsProperty || (member.IsProperty && member.PropertyInfo.CanWrite))
     {
         var valueFormatAttribute = member.MemberInfo.GetCustomAttribute <ValueFormatAttribute>() ?? member.MemberInfo.DeclaringType.GetCustomAttribute <ValueFormatAttribute>();
         if (valueFormatAttribute != null)//part
         {
             return(GenerateValueFormatCode(Expression.Constant(valueFormatAttribute, typeof(ValueFormatAttribute)), ValueFormatAttribute._ReadValueFormat, new[] { ExpressionMembers.JsonRemoveQuoteAndSubstring, Expression.Constant(member.Type, typeof(Type)), ExpressionMembers.JsonDeserializeHandler, ExpressionMembers.IsValueFormat }, newModel, member));
         }
         else //global
         {
             /*
              * if( jsonDeserializeHandler.jsonDeserializeOption .globalValueFormat!=null)
              * {
              * }
              * else
              *   model.N=ReadJson();
              */
             return(Expression.IfThenElse(ExpressionMembers.GlobalValueFormatNotEqualNull, GenerateValueFormatCode(ExpressionMembers.GlobalValueFormat, JsonDeserializeOption._GlobalValueFormatInvoke, new[] { ExpressionMembers.JsonRemoveQuoteAndSubstring, Expression.Constant(member.Type, typeof(Type)), ExpressionMembers.JsonDeserializeHandler, ExpressionMembers.IsValueFormat }, newModel, member), Expression.Assign(Expression.MakeMemberAccess(newModel, member.MemberInfo), ExpressionMembers.GetMethodCall(member.Type))));
         }
     }
     else
     {
         /*   SkipObj(); */
         return(Expression.Call(ExpressionMembers.Reader, JsonReader._SkipObj, ExpressionMembers.JsonDeserializeHandler));
     }
 }
Exemplo n.º 6
0
        internal static BlockExpression Build(Type multiType, Type sawtoothType, int rank)
        {
            LabelTarget returnValueLable = Expression.Label(multiType, "returnValue");
            List <ParameterExpression> lambdaVariables = new List <ParameterExpression>();

            Expression[] exs = new Expression[3];

            ParameterExpression sawtoothAry = Expression.Variable(sawtoothType);

            lambdaVariables.Add(sawtoothAry);

            /*
             * int[][][] sawtoothAry= InvokeGet<int[][][]>();
             */
            exs[0] = Expression.Assign(sawtoothAry, ExpressionMembers.GetMethodCall(sawtoothType));

            /*
             * if(sawtoothAry==null)
             *     return null;
             * else
             *     ...
             */
            exs[1] = Expression.IfThenElse(
                Expression.Equal(sawtoothAry, Expression.Constant(null, sawtoothType)),
                Expression.Return(returnValueLable, Expression.Constant(null, multiType)),
                ReturnFunc <Expression>(() =>
            {
                List <Expression> expressions = new List <Expression>();

                /*
                 * var index0_Length = sawtoothAry.Length;
                 * var index1_Length = sawtoothAry[0].Length;
                 * var index2_Length = sawtoothAry[0][0].Length;
                 *
                 * var a = 0;
                 * var b = 0;
                 * var c = 0;
                 */
                ParameterExpression[] arrayLengthVariables = new ParameterExpression[rank];
                ParameterExpression[] forVariables         = new ParameterExpression[rank];
                for (int i = 0; i < arrayLengthVariables.Length; i++)
                {
                    arrayLengthVariables[i] = Expression.Variable(typeof(int));
                    expressions.Add(Expression.Assign(arrayLengthVariables[i], Expression.MakeMemberAccess(GetIndexAccessBySawtoothAry(sawtoothAry, GetExpressionConstantZero(i).ToArray()), typeof(Array).GetProperty("Length"))));

                    forVariables[i] = Expression.Variable(typeof(int));
                }
                lambdaVariables.AddRange(arrayLengthVariables);

                /*
                 * int[,,] multiAry=new multiAry(index0_Length,index1_Length,index2_Length)
                 */
                ParameterExpression multiAry = Expression.Variable(multiType);
                lambdaVariables.Add(multiAry);

                expressions.Add(Expression.Assign(multiAry, Expression.New(multiType.GetConstructors()[0], arrayLengthVariables)));

                /*
                 *  for (int a = 0; a < index0_Length; a++)
                 *  {
                 *      for (int b = 0; b < index1_Length; b++)
                 *      {
                 *          for (int c = 0; c < index2_Length; c++)
                 *          {
                 *              multiAry[a,b,c] = sawtoothAry[a][b][c];
                 *          }
                 *      }
                 *  }
                 */
                Expression forMain = null;
                for (int i = arrayLengthVariables.Length - 1; i >= 0; i--)
                {
                    Expression content = null;
                    if (forMain == null)
                    {
                        /*
                         * sawtoothAry[a][b][c];
                         */
                        Expression sawtoothAryAccess = GetIndexAccessBySawtoothAry(sawtoothAry, forVariables);

                        /*
                         * multiAry[a,b,c] = sawtoothAry[a][b][c];
                         */
                        content = Expression.Assign(Expression.ArrayAccess(multiAry, forVariables), sawtoothAryAccess);
                    }
                    else
                    {
                        content = forMain;
                    }

                    forMain = ExpressionHelper.For(forVariables[i], Expression.LessThan(forVariables[i], arrayLengthVariables[i]), Expression.PostIncrementAssign(forVariables[i]),
                                                   content
                                                   );
                }
                expressions.Add(forMain);

                /*
                 * return  multiAry
                 */
                expressions.Add(Expression.Return(returnValueLable, multiAry));

                return(Expression.Block(expressions));
            }));

            exs[2] = Expression.Label(returnValueLable, Expression.Constant(null, multiType));

            return(Expression.Block(lambdaVariables.ToArray(), exs));
        }
Exemplo n.º 7
0
        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));
        }
Exemplo n.º 8
0
        internal static BlockExpression Build(Type defindType, Type instanceType, Type convertType, Type keyType, Type valueType)
        {
            /*
             * defind:ExpandoObject    new:ExpandoObject   convert:IDictionary<string, object>
             * ExpandoObject ss = new ExpandoObject();
             * IDictionary<string, object> dic = (IDictionary<string, object>)ss;
             *
             * hashtable
             */


            Expression[] methodDictionaryCall = new Expression[9];

            LabelTarget returnTarget = Expression.Label(defindType, "returnLable");
            Expression  ifReadNullOrObjLeftReturnNull;

            if (!defindType.IsValueType)
            {
                /*
                 * if (reader.ReadNullOrObjLeft())
                 *   return null;
                 */
                ifReadNullOrObjLeftReturnNull = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrObjLeft), Expression.Return(returnTarget, Expression.Constant(null, defindType)));
            }
            else
            {
                ifReadNullOrObjLeftReturnNull = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjLeft);
            }
            methodDictionaryCall[0] = ifReadNullOrObjLeftReturnNull;

            /*
             * Dictionary<> dictionary =new Dictionary<>();
             */
            NewExpression       dictionaryCtor = Expression.New(instanceType);
            ParameterExpression dictionary     = Expression.Variable(defindType, "dictionary");

            methodDictionaryCall[1] = Expression.Assign(dictionary, dictionaryCtor);

            /*
             * if(reader.ReadBoolObjRight)
             *     return dictionary;
             */
            methodDictionaryCall[2] = (Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolObjRight), Expression.Return(returnTarget, dictionary)));

            /*
             * IDictionary iDic = dictionary;
             * IDictionary<,> iDic = dictionary;
             */
            MethodInfo          iDicAdd = convertType.GetMethod("Add");
            ParameterExpression iDic    = Expression.Variable(convertType, "iDic");

            methodDictionaryCall[3] = Expression.Assign(iDic, Expression.Convert(dictionary, convertType));

            /*
             * int moveNext=2;
             */
            methodDictionaryCall[4] = ExpressionMembers.MoveNextAssignOne;

            ParameterExpression key   = Expression.Variable(keyType, "key");
            ParameterExpression value = Expression.Variable(valueType, "value");

            /*
             * while(moveNext-->0)
             *  {}
             */
            LabelTarget    loopBreak      = Expression.Label("loopBreak");
            LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
                                                                                  ReturnFunc <Expression>(() =>
            {
                Expression[] methodCall = new Expression[5];

                /*
                 *  ReadKey()
                 */
                methodCall[0] = ExpressionMembers.GenerateKeyValuePairByReadKey(keyType, key);

                /*
                 * reader.ReadColon()
                 */
                methodCall[1] = (Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon));

                /*
                 * value = ResolveProvider<ValueType>.InvokeGet(reader, handler);
                 */
                methodCall[2] = (Expression.Assign(value, ExpressionMembers.GetMethodCall(valueType)));

                /*
                 * iDic.Add(key,value);
                 */
                methodCall[3] = (Expression.Call(iDic, iDicAdd, key, value));

                /*
                 * if(reader.ReadComma()==true)
                 *       moveNext++;
                 */
                methodCall[4] = (ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement);

                return(Expression.Block(methodCall));;
            })
                                                                                  , Expression.Break(loopBreak)));

            methodDictionaryCall[5] = Expression.Block(loopExpression, Expression.Label(loopBreak));

            /*
             * reader.ReadObjRight();
             */
            methodDictionaryCall[6] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight);

            /*
             * return dictionary
             */
            GotoExpression  returnExpression = Expression.Return(returnTarget, dictionary);
            LabelExpression returnLabel      = Expression.Label(returnTarget, dictionary);

            methodDictionaryCall[7] = returnExpression;
            methodDictionaryCall[8] = returnLabel;

            return(Expression.Block(new[] { iDic, dictionary, key, value, ExpressionMembers.MoveNext }, methodDictionaryCall));
        }
Exemplo n.º 9
0
        internal static BlockExpression Build(Type type)
        {
            Type arrayItemType = type.GetElementType();

            Expression[] methodListCall = new Expression[11];
            LabelTarget  returnTarget   = Expression.Label(type, "returnLable");

            /*
             * if (reader.ReadNullOrArrayLeft())
             *   return null;
             */
            Expression ifReadNullOrArrayLeftReturnNull = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrArrayLeft), Expression.Return(returnTarget, Expression.Constant(null, type)));

            methodListCall[0] = ifReadNullOrArrayLeftReturnNull;

            /*
             * int arrayLength=reader._GetArrayLength;
             * T[] array=new [arrayLength];
             */
            ParameterExpression arrayLength = Expression.Variable(typeof(int), "arrayLength");

            methodListCall[1] = Expression.Assign(arrayLength, Expression.Call(ExpressionMembers.Reader, JsonReader._GetArrayLength, ExpressionMembers.JsonDeserializeHandler));
            NewExpression       aryCtor = Expression.New(type.GetConstructors()[0], arrayLength);
            ParameterExpression array   = Expression.Variable(type, "array");

            methodListCall[2] = Expression.Assign(array, aryCtor);

            /*
             * if(arrayLength==0)
             *  goto ReadArrayRightLabel;
             */
            LabelTarget readArrayRightLabel = Expression.Label(typeof(void), "ReadArrayRightLabel");

            methodListCall[3] = Expression.IfThen(Expression.Equal(arrayLength, Expression.Constant(0)), Expression.Goto(readArrayRightLabel));

            /*
             * int moveNext=1;
             */
            methodListCall[4] = ExpressionMembers.MoveNextAssignOne;

            /*
             * int idx=0;
             */
            ParameterExpression idx = Expression.Variable(typeof(int), "idx");

            methodListCall[5] = Expression.Assign(idx, Expression.Constant(0));

            /*
             * while(moveNext-->0)
             * {}
             */
            LabelTarget    loopBreak      = Expression.Label("loopBreak");
            LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
                                                                                  ReturnFunc <Expression>(() =>
            {
                Expression[] methodCall = new Expression[3];

                /*
                 * ary[idx]=item;
                 */
                methodCall[0] = Expression.Assign(Expression.ArrayAccess(array, idx), ExpressionMembers.GetMethodCall(arrayItemType));

                /*
                 * if(reader.ReadBoolComma()==true)
                 *       moveNext++;
                 */
                methodCall[1] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement;

                /*
                 * idx++;
                 */
                methodCall[2] = Expression.PostIncrementAssign(idx);
                return(Expression.Block(methodCall));;
            })
                                                                                  , Expression.Break(loopBreak)));

            methodListCall[6] = Expression.Block(loopExpression, Expression.Label(loopBreak));

            /*
             * ReadArrayRightLabel:
             * reader.ReadArrayRight()
             */
            methodListCall[7] = Expression.Label(readArrayRightLabel);
            methodListCall[8] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadArrayRight);

            /*
             * return list;
             */
            GotoExpression  returnExpression = Expression.Return(returnTarget, array);
            LabelExpression returnLabel      = Expression.Label(returnTarget, array);

            methodListCall[9]  = returnExpression;
            methodListCall[10] = returnLabel;

            return(Expression.Block(new[] { arrayLength, array, idx, ExpressionMembers.MoveNext }, methodListCall));
        }
Exemplo n.º 10
0
        internal static BlockExpression Build(Type defindType, Type instanceType, Type convertType, Type arrayItemType)
        {
            /*
             *  //defind:IEnumerable<string>    new: List<string>  convert: List<string>
             *  IEnumerable<string> li = new List<string>();
             *  List<string> list = (List<string>)li;
             *
             *  //defind:ArrayList   new:ArrayList   convert: IList/ArrayList
             *   ArrayList v = new ArrayList();
             *   var df = (IList)v;
             */

            Expression[] methodListCall = new Expression[9];

            LabelTarget returnTarget = Expression.Label(defindType, "returnLable");
            Expression  ifReadNullOrArrayLeftReturnNull;

            if (!defindType.IsValueType)
            {
                /*
                 * if (reader.ReadNullOrArrayLeft())
                 *   return null;
                 */
                ifReadNullOrArrayLeftReturnNull = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrArrayLeft), Expression.Return(returnTarget, Expression.Constant(null, defindType)));
            }
            else
            {
                ifReadNullOrArrayLeftReturnNull = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadArrayLeft);
            }
            methodListCall[0] = ifReadNullOrArrayLeftReturnNull;

            /*
             * List<> list =new List<>();
             */
            NewExpression       listCtor = Expression.New(instanceType);
            ParameterExpression list     = Expression.Variable(defindType, "list");

            methodListCall[1] = Expression.Assign(list, listCtor);

            /*
             * if(reader.ReadBoolArrayRight)
             *       return list;
             */
            methodListCall[2] = (Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolArrayRight), Expression.Return(returnTarget, list)));

            /*
             * ICollection<int> iCollec = (ICollection<int>)list;
             * iCollec.Add(ReadInt())
             */
            MethodInfo iCollecAdd = convertType.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);

            ParameterExpression iCollec = Expression.Variable(convertType, "iDic");

            methodListCall[3] = Expression.Assign(iCollec, Expression.Convert(list, convertType));

            /*
             * int moveNext=1;
             */
            methodListCall[4] = ExpressionMembers.MoveNextAssignOne;

            /*
             * while(moveNext-->0)
             * {}
             */
            LabelTarget    loopBreak      = Expression.Label("loopBreak");
            LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
                                                                                  ReturnFunc <Expression>(() =>
            {
                Expression[] methodCall = new Expression[2];

                /*
                 * list.Add(item);
                 */
                methodCall[0] = Expression.Call(iCollec, iCollecAdd, ExpressionMembers.GetMethodCall(arrayItemType));

                /*
                 * if(reader.ReadBoolComma()==true)
                 *       moveNext++;
                 */
                methodCall[1] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement;

                return(Expression.Block(methodCall));;
            })
                                                                                  , Expression.Break(loopBreak)));

            methodListCall[5] = Expression.Block(loopExpression, Expression.Label(loopBreak));

            /*
             * reader.ReadArrayRight()
             */
            methodListCall[6] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadArrayRight);

            /*
             * return list;
             */
            GotoExpression  returnExpression = Expression.Return(returnTarget, list);
            LabelExpression returnLabel      = Expression.Label(returnTarget, list);

            methodListCall[7] = returnExpression;
            methodListCall[8] = returnLabel;

            return(Expression.Block(new[] { iCollec, list, ExpressionMembers.MoveNext }, methodListCall));
        }