Esempio n. 1
0
        private Expression ReduceForArray()
        {
            var inner_loop_break    = Expression.Label("inner_loop_break");
            var inner_loop_continue = Expression.Label("inner_loop_continue");

            var @continue = continue_target ?? Expression.Label("continue");
            var @break    = break_target ?? Expression.Label("break");

            var index = Expression.Variable(typeof(int), "i");

            return(Expression.Block(
                       new [] { index, variable },
                       index.Assign(Expression.Constant(0)),
                       Expression.Loop(
                           Expression.Block(
                               Expression.IfThen(
                                   Expression.IsFalse(
                                       Expression.LessThan(
                                           index,
                                           Expression.ArrayLength(enumerable))),
                                   Expression.Break(inner_loop_break)),
                               variable.Assign(
                                   Expression.ArrayIndex(
                                       enumerable,
                                       index).Convert(variable.Type)),
                               body,
                               Expression.Label(@continue),
                               Expression.PreIncrementAssign(index)),
                           inner_loop_break,
                           inner_loop_continue),
                       Expression.Label(@break)));
        }
Esempio n. 2
0
        public static Expression InForEach(this Expression collection,
                                           ParameterExpression loopVar, Expression body)
        {
            var elementType       = loopVar.Type;
            var enumerableType    = typeof(IEnumerable <>).MakeGenericType(elementType);
            var enumerator        = typeof(IEnumerator <>).MakeGenericType(elementType).Variable();
            var getEnumeratorCall = Expression.Call(collection, enumerableType
                                                    .GetMethod(nameof(IEnumerable.GetEnumerator)));
            var moveNextCall = Expression.Call(enumerator, Type <IEnumerator> .Method(x => x.MoveNext()));
            var breakLabel   = Expression.Label("LoopBreak");

            return(Expression.Block(new[] { enumerator },
                                    enumerator.Assign(getEnumeratorCall),
                                    Expression.Loop(
                                        Expression.IfThenElse(
                                            Expression.Equal(moveNextCall, true.ToConstant()),
                                            Expression.Block(new[] { loopVar },
                                                             loopVar.Assign(enumerator.PropertyAccess(nameof(IEnumerator.Current))),
                                                             body
                                                             ),
                                            Expression.Break(breakLabel)
                                            ),
                                        breakLabel)
                                    ));
        }
Esempio n. 3
0
        internal static BinaryExpression Assign(this ParameterExpression expr, object value)
        {
            if (value is Expression valueExpr)
            {
                return(expr.Assign(valueExpr));
            }

            return(Expression.Assign(expr, Expression.Constant(value)));
        }
Esempio n. 4
0
        public override Expression Reduce()
        {
            Type argument;
            Type enumerable_type;
            Type enumerator_type;

            if (!TryGetGenericEnumerableArgument(out argument))
            {
                enumerator_type = typeof(IEnumerator);
                enumerable_type = typeof(IEnumerable);
            }
            else
            {
                enumerator_type = typeof(IEnumerator <>).MakeGenericType(argument);
                enumerable_type = typeof(IEnumerable <>).MakeGenericType(argument);
            }

            var enumerator = Expression.Variable(enumerator_type);
            var disposable = Expression.Variable(typeof(IDisposable));

            var inner_loop_continue = Expression.Label("inner_loop_continue");
            var inner_loop_break    = Expression.Label("inner_loop_break");
            var @continue           = continue_target ?? Expression.Label("continue");
            var @break      = break_target ?? Expression.Label("break");
            var end_finally = Expression.Label("end");

            return(Expression.Block(
                       new[] { enumerator },
                       enumerator.Assign(Expression.Call(enumerable.Convert(enumerable_type), enumerable_type.GetMethod("GetEnumerator"))),
                       Expression.TryFinally(
                           Expression.Block(
                               new[] { variable },
                               Expression.Goto(@continue),
                               Expression.Loop(
                                   Expression.Block(
                                       variable.Assign(enumerator.Property("Current").Convert(variable.Type)),
                                       body,
                                       Expression.Label(@continue),
                                       Expression.Condition(
                                           Expression.Call(
                                               enumerator,
                                               typeof(IEnumerator).GetMethod("MoveNext")),
                                           Expression.Goto(inner_loop_continue),
                                           Expression.Goto(inner_loop_break))),
                                   inner_loop_break,
                                   inner_loop_continue),
                               Expression.Label(@break)),
                           Expression.Block(
                               new[] { disposable },
                               disposable.Assign(enumerator.TypeAs(typeof(IDisposable))),
                               disposable.NotEqual(Expression.Constant(null)).Condition(
                                   Expression.Call(disposable, typeof(IDisposable).GetMethod("Dispose", Type.EmptyTypes)),
                                   Expression.Goto(end_finally)),
                               Expression.Label(end_finally)))));
        }
Esempio n. 5
0
        public override Expression Reduce()
        {
            var end_finally = Expression.Label("end_finally");

            return(Expression.Block(
                       new[] { variable },
                       variable.Assign(disposable),
                       Expression.TryFinally(
                           body,
                           Expression.Block(
                               variable.NotEqual(Expression.Constant(null)).Condition(
                                   Expression.Block(
                                       Expression.Call(
                                           variable.Convert(typeof(IDisposable)),
                                           typeof(IDisposable).GetMethod("Dispose")),
                                       Expression.Goto(end_finally)),
                                   Expression.Goto(end_finally)),
                               Expression.Label(end_finally)))));
        }
Esempio n. 6
0
        public override Expression Reduce()
        {
            var inner_loop_break    = Expression.Label("inner_loop_break");
            var inner_loop_continue = Expression.Label("inner_loop_continue");

            var @continue = continue_target ?? Expression.Label("continue");
            var @break    = break_target ?? Expression.Label("break");

            return(Expression.Block(
                       new [] { variable },
                       variable.Assign(initializer),
                       Expression.Loop(
                           Expression.Block(
                               Expression.IfThen(
                                   Expression.IsFalse(test),
                                   Expression.Break(inner_loop_break)),
                               body,
                               Expression.Label(@continue),
                               step),
                           inner_loop_break,
                           inner_loop_continue),
                       Expression.Label(@break)));
        }
        /// <summary>
        /// Construct an expression like
        ///
        /// var obj = new Obj();
        ///
        /// while(ReadAttribute())
        /// {
        ///     ...
        /// }
        ///
        /// while(ReadElement())
        /// {
        ///     ...
        /// }
        ///
        /// return obj;
        /// </summary>
        /// <param name="first">Whether this is the outer object being deserialized.</param>
        /// <param name="parentProperty">The property on our parent object this object will be deserialized to.</param>
        /// <returns></returns>
        internal Expression MakeReadElement(bool first = false, PropertyCache parentProperty = null)
        {
            Expression          moveToContent = null;
            ParameterExpression itemPointer   = Expression.Variable(typeof(object), "item");

            if (first)
            {
                moveToContent = XmlExpressionConstants.XmlReader_MoveToContent;
            }

            var makeNew = Expression.Assign(Target, Expression.New(trueType));             //obj = new TableData<Sensor>();

            var initArrays = InitializeArrays();                                           //if (obj.Items == null) obj.Items = new List<Sensor>();

            var newFlags = Expression.NewArrayBounds(                                      //new bool[40]
                typeof(bool),
                Expression.Constant(Mappings.Count)
                );
            var flagsAssignment = XmlExpressionConstants.SerializerFlags.Assign(newFlags); //var flagsArray = new bool[40]

            var newName = Expression.NewArrayBounds(typeof(object),                        //new object[42]
                                                    Expression.Constant(Mappings.Sum(m => m.AttributeValue.Length))
                                                    );
            var nameAssignment = XmlExpressionConstants.SerializerNames.Assign(newName);   //var nameArray = new object[42]

            var populateNameTable = PopulateNameTable(parentProperty);                     //InitTableData(nameArray)

            var processAttributes    = ProcessAttributes();
            var skipOrProcessElement = SkipOrProcessElement();

            var blockExpressions = new List <Expression>();

            if (first)
            {
                blockExpressions.Add(moveToContent);                                       //reader.MoveToContent();
            }
            if (!update)
            {
                blockExpressions.Add(makeNew);                                             //var obj = new TObj()
            }
            else
            {
                var nameTable = XmlExpressionConstants.XmlReader_NameTable;
                var add       = XmlExpressionConstants.ListAdd(nameTable, Expression.Constant("item"));

                blockExpressions.Add(itemPointer.Assign(add));
                blockExpressions.Add(XmlExpressionConstants.XmlReader_ReadToFollowing(Expression.Convert(itemPointer, typeof(string))));
            }

            if (initArrays.Count > 0)
            {
                blockExpressions.AddRange(initArrays);                                     //obj.Items = new List<Sensor>();
            }
            blockExpressions.Add(flagsAssignment);                                         //var flagsArray = new bool[40]
            blockExpressions.Add(nameAssignment);                                          //var nameArray = new object[42]

            if (populateNameTable != null)
            {
                blockExpressions.Add(populateNameTable);                                   //InitTableData(nameArray)
            }
            blockExpressions.Add(processAttributes);                                       //if (!flagsArray[0] && (object)reader.Name == nameArray[0])
            blockExpressions.Add(XmlExpressionConstants.XmlReader_MoveToContent);
            blockExpressions.Add(skipOrProcessElement);

            var variables = new List <ParameterExpression>();

            if (!update)
            {
                variables.Add(Target);                                                     //TableData<Sensor> obj;
            }
            variables.Add(XmlExpressionConstants.SerializerFlags);                         //bool[] flagArray;
            variables.Add(XmlExpressionConstants.SerializerNames);                         //object[] nameArray;

            if (update)
            {
                variables.Add(itemPointer);
            }

            var block = Expression.Block(
                variables.ToArray(),
                blockExpressions
                );

            var lambda = Expression.Lambda(
                block,
                $"Read{GetDynamicTypeNameInternal(trueType)}",
                GetReadElementParameters(null, false).Cast <ParameterExpression>().ToArray()
                );

            return(LambdaOrDelegate(lambda));
        }