public void ShouldTranslateALoopWithABreakStatement() { var intVariable = Expression.Variable(typeof(int), "i"); var intGreaterThanTwo = Expression.GreaterThan(intVariable, Expression.Constant(2)); var breakLoop = Expression.Break(Expression.Label()); var ifGreaterThanTwoBreak = Expression.IfThen(intGreaterThanTwo, breakLoop); var writeLine = CreateLambda(() => Console.WriteLine()); var incrementVariable = Expression.Increment(intVariable); var loopBody = Expression.Block(ifGreaterThanTwoBreak, writeLine.Body, incrementVariable); var loop = Expression.Loop(loopBody, breakLoop.Target); var translated = ToReadableString(loop); const string EXPECTED = @" while (true) { if (i > 2) { break; } Console.WriteLine(); ++i; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
private static Expression GetReturnStatementBlock(out ParameterExpression existingInts) { existingInts = Expression.Variable(typeof(List <int>), "ints"); var existingIntsEnumerator = Expression.Variable(typeof(List <int> .Enumerator), "enumerator"); var getEnumeratorMethod = existingInts.Type.GetPublicInstanceMethod("GetEnumerator"); var getEnumeratorCall = Expression.Call(existingInts, getEnumeratorMethod); var enumeratorAssignment = Expression.Assign(existingIntsEnumerator, getEnumeratorCall); var enumeratorMoveNextMethod = existingIntsEnumerator.Type.GetPublicInstanceMethod("MoveNext"); var enumeratorMoveNextCall = Expression.Call(existingIntsEnumerator, enumeratorMoveNextMethod); var enumeratorItem = Expression.Variable(typeof(int), "item"); var enumeratorCurrent = Expression.Property(existingIntsEnumerator, "Current"); var itemAssignment = Expression.Assign(enumeratorItem, enumeratorCurrent); var intsAddMethod = existingInts.Type.GetPublicInstanceMethod("Add"); var intsAddCall = Expression.Call(existingInts, intsAddMethod, enumeratorItem); var addItemBlock = Expression.Block( new[] { enumeratorItem }, itemAssignment, intsAddCall); var loopBreakTarget = Expression.Label(typeof(void), "LoopBreak"); var conditionallyAddItems = Expression.Condition( Expression.IsTrue(enumeratorMoveNextCall), addItemBlock, Expression.Break(loopBreakTarget)); var addItemsLoop = Expression.Loop(conditionallyAddItems, loopBreakTarget); var populateExistingInts = Expression.Block( new[] { existingIntsEnumerator }, enumeratorAssignment, addItemsLoop); var conditionFalseBlock = Expression.Block( populateExistingInts, existingInts); var valueConditional = Expression.Condition( Expression.Equal(existingInts, Expression.Default(existingInts.Type)), Expression.New(conditionFalseBlock.Type), conditionFalseBlock); return(valueConditional); }