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))); }
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) )); }
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))); }
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))))); }
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))))); }
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)); }