public void ShouldNotLeaveDoubleBlankLinesBetweenIfStatements()
        {
            var intVariable             = Expression.Variable(typeof(int), "i");
            var one                     = Expression.Constant(1);
            var intVariableEqualsOne    = Expression.Equal(intVariable, one);
            var doNothing               = Expression.Default(typeof(void));
            var ifIntEqualsOneDoNothing = Expression.IfThen(intVariableEqualsOne, doNothing);

            var block = Expression.Block(
                new[] { intVariable },
                ifIntEqualsOneDoNothing,
                ifIntEqualsOneDoNothing);

            const string EXPECTED = @"
int i;

if (i == 1)
{
}

if (i == 1)
{
}";

            var translated = ToReadableString(block);

            translated.ShouldBe(EXPECTED.TrimStart());
        }
Пример #2
0
        public void ShouldTranslateAMultipleLineNonVoidIfElseStatements()
        {
            var intVariable           = Expression.Variable(typeof(int), "i");
            var zero                  = Expression.Constant(0);
            var intVariableEqualsZero = Expression.Equal(intVariable, zero);
            var writeHello            = CreateLambda(() => Console.WriteLine("Hello"));
            var writeGoodbye          = CreateLambda(() => Console.WriteLine("Goodbye"));
            var helloThenGoodbye      = Expression.Block(writeHello.Body, writeGoodbye.Body, intVariable);
            var goodbyeThenHello      = Expression.Block(writeGoodbye.Body, writeHello.Body, intVariable);
            var writeHelloAndGoodbye  = Expression.IfThenElse(intVariableEqualsZero, helloThenGoodbye, goodbyeThenHello);

            var translated = ToReadableString(writeHelloAndGoodbye);

            const string EXPECTED = @"
if (i == 0)
{
    Console.WriteLine(""Hello"");
    Console.WriteLine(""Goodbye"");

    return i;
}

Console.WriteLine(""Goodbye"");
Console.WriteLine(""Hello"");

return i;
";

            translated.ShouldBe(EXPECTED.Trim());
        }
        public void ShouldTranslateAGotoReturnStatement()
        {
            var returnTarget = Expression.Label(typeof(int), "Return");

            var numberParameter = Expression.Parameter(typeof(string), "i");
            var numberEqualsOne = Expression.Equal(numberParameter, Expression.Constant("One"));
            var returnOne       = Expression.Goto(returnTarget, Expression.Constant(1));
            var ifOneReturnOne  = Expression.IfThen(numberEqualsOne, returnOne);

            var returnLabel = Expression.Label(returnTarget, Expression.Constant(0));
            var gotoBlock   = Expression.Block(ifOneReturnOne, returnLabel);

            var gotoLambda = Expression.Lambda <Func <string, int> >(gotoBlock, numberParameter);

            gotoLambda.Compile();

            var translated = ToReadableString(gotoLambda);

            const string EXPECTED = @"
i =>
{
    if (i == ""One"")
    {
        return 1;
    }

    return 0;
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldAbbreviateBooleanFalseComparisons()
        {
            var boolVariable = Expression.Variable(typeof(bool), "couldBe");
            var boolIsFalse  = Expression.Equal(Expression.Constant(false), boolVariable);

            var translated = ToReadableString(boolIsFalse);

            translated.ShouldBe("!couldBe");
        }
        public void ShouldAbbreviateBooleanTrueComparisons()
        {
            var boolVariable = Expression.Variable(typeof(bool), "couldBe");
            var boolIsTrue   = Expression.Equal(boolVariable, Expression.Constant(true));

            var translated = ToReadableString(boolIsTrue);

            translated.ShouldBe("couldBe");
        }
        public void ShouldTranslateGotoStatements()
        {
            var labelTargetOne = Expression.Label(typeof(void), "One");
            var labelOne       = Expression.Label(labelTargetOne);
            var writeOne       = CreateLambda(() => Console.Write("One"));
            var gotoOne        = Expression.Goto(labelTargetOne);

            var labelTargetTwo = Expression.Label(typeof(void), "Two");
            var labelTwo       = Expression.Label(labelTargetTwo);
            var writeTwo       = CreateLambda(() => Console.Write("Two"));
            var gotoTwo        = Expression.Goto(labelTargetTwo);

            var intVariable  = Expression.Variable(typeof(int), "i");
            var intEqualsOne = Expression.Equal(intVariable, Expression.Constant(1));
            var intEqualsTwo = Expression.Equal(intVariable, Expression.Constant(2));

            var ifTwoGotoTwo = Expression.IfThen(intEqualsTwo, gotoTwo);
            var gotoOneOrTwo = Expression.IfThenElse(intEqualsOne, gotoOne, ifTwoGotoTwo);

            var writeNeither    = CreateLambda(() => Console.Write("Neither"));
            var returnFromBlock = Expression.Return(Expression.Label());

            var block = Expression.Block(
                gotoOneOrTwo,
                writeNeither.Body,
                returnFromBlock,
                labelOne,
                writeOne.Body,
                labelTwo,
                writeTwo.Body);

            var translated = ToReadableString(block);

            const string EXPECTED = @"
if (i == 1)
{
    goto One;
}
else if (i == 2)
{
    goto Two;
}

Console.Write(""Neither"");
return;

One:
Console.Write(""One"");

Two:
Console.Write(""Two"");
";

            translated.ShouldBe(EXPECTED.Trim());
        }
Пример #7
0
        public void ShouldTranslateEnumComparisonTests()
        {
            var flagParameter     = Expression.Parameter(typeof(bool), "flag");
            var one               = Expression.Constant(Test.One);
            var two               = Expression.Constant(Test.Two);
            var oneOrTwo          = Expression.Condition(flagParameter, one, two);
            var oneOrTwoEqualsTwo = Expression.Equal(oneOrTwo, two);
            var testLambda        = Expression.Lambda <Func <bool, bool> >(oneOrTwoEqualsTwo, flagParameter);

            var translated = ToReadableString(testLambda);

            translated.ShouldBe("flag => (flag ? Test.One : Test.Two) == Test.Two");
        }
        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);
        }
        public void ShouldAssignAVariableInAConditionalTest()
        {
            var intVariable      = Expression.Variable(typeof(int), "i");
            var assignVariable   = Expression.Assign(intVariable, Expression.Constant(10));
            var isAssignmentFive = Expression.Equal(assignVariable, Expression.Constant(5));
            var ifFiveDoNothing  = Expression.IfThen(isAssignmentFive, Expression.Empty());

            var translated = ToReadableString(ifFiveDoNothing);

            const string EXPECTED = @"
if ((i = 10) == 5)
{
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateAConditionalBranchWithAComment()
        {
            var comment               = ReadableExpression.Comment("Maths works");
            var one                   = Expression.Constant(1);
            var oneEqualsOne          = Expression.Equal(one, one);
            var ifOneEqualsOneComment = Expression.IfThen(oneEqualsOne, comment);

            var translated = ToReadableString(ifOneEqualsOneComment);

            const string EXPECTED = @"
if (1 == 1)
{
    // Maths works
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldLeaveABlankLineBeforeAnIfStatement()
        {
            var intVariable              = Expression.Variable(typeof(int), "i");
            var zero                     = Expression.Constant(0);
            var intVariableEqualsZero    = Expression.Equal(intVariable, zero);
            var doNothing                = Expression.Default(typeof(void));
            var ifIntEqualsZeroDoNothing = Expression.IfThen(intVariableEqualsZero, doNothing);

            var block = Expression.Block(new[] { intVariable }, ifIntEqualsZeroDoNothing);

            const string EXPECTED = @"
int i;

if (i == 0)
{
}";

            var translated = ToReadableString(block);

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldNotVarAssignATernaryValueWithDifferingTypeBranches()
        {
            var intVariable          = Expression.Variable(typeof(int), "i");
            var intVariableEqualsOne = Expression.Equal(intVariable, Expression.Constant(1));
            var newArray             = Expression.NewArrayBounds(typeof(int?), Expression.Constant(0));
            var newList = Expression.New(typeof(List <int?>));

            var newArrayOrList = Expression.Condition(
                intVariableEqualsOne,
                newArray,
                newList,
                typeof(ICollection <int?>));

            var resultVariable = Expression.Variable(typeof(ICollection <int?>), "result");
            var assignResult   = Expression.Assign(resultVariable, newArrayOrList);
            var assignBlock    = Expression.Block(new[] { resultVariable }, assignResult);

            var translated = ToReadableString(assignBlock);

            translated.ShouldBe("ICollection<int?> result = (i == 1) ? new int?[0] : new List<int?>();");
        }
        public void ShouldOnlyRemoveParenthesesIfNecessary()
        {
            var intVariable      = Expression.Variable(typeof(int), "i");
            var intVariableIsOne = Expression.Equal(intVariable, Expression.Constant(1));

            var objectVariable    = Expression.Variable(typeof(object), "o");
            var objectCastToInt   = Expression.Convert(objectVariable, typeof(int));
            var intToStringMethod = typeof(object).GetPublicInstanceMethod("ToString");
            var intToStringCall   = Expression.Call(objectCastToInt, intToStringMethod);

            var emptyString = CreateLambda(() => string.Empty);

            var toStringOrEmptyString = Expression.Condition(
                intVariableIsOne,
                emptyString.Body,
                intToStringCall);

            var translated = ToReadableString(toStringOrEmptyString);

            translated.ShouldBe("(i == 1) ? string.Empty : ((int)o).ToString()");
        }
        public void ShouldNotLeaveDoubleBlankLinesBetweenInitAndIfStatements()
        {
            var writeWat = CreateLambda(() => Console.WriteLine("Wat"));
            var read     = CreateLambda <long>(() => Console.Read());

            var newMemoryStream  = Expression.New(typeof(MemoryStream));
            var positionProperty = newMemoryStream.Type.GetProperty("Position");
            var valueBlock       = Expression.Block(writeWat.Body, read.Body);
            // ReSharper disable once AssignNullToNotNullAttribute
            var positionInit     = Expression.Bind(positionProperty, valueBlock);
            var memoryStreamInit = Expression.MemberInit(newMemoryStream, positionInit);

            var intVariable             = Expression.Variable(typeof(int), "i");
            var one                     = Expression.Constant(1);
            var intVariableEqualsOne    = Expression.Equal(intVariable, one);
            var doNothing               = Expression.Default(typeof(void));
            var ifIntEqualsOneDoNothing = Expression.IfThen(intVariableEqualsOne, doNothing);

            var block = Expression.Block(memoryStreamInit, ifIntEqualsOneDoNothing);

            const string EXPECTED = @"
new MemoryStream
{
    Position = 
    {
        Console.WriteLine(""Wat"");

        return ((long)Console.Read());
    }
};

if (i == 1)
{
}";

            var translated = ToReadableString(block);

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTerminateAMultipleLineMemberInitAssignment()
        {
            var writeWat = CreateLambda(() => Console.WriteLine("Wat"));
            var read     = CreateLambda <long>(() => Console.Read());

            var newMemoryStream  = Expression.New(typeof(MemoryStream));
            var positionProperty = newMemoryStream.Type.GetProperty("Position");
            var valueBlock       = Expression.Block(writeWat.Body, read.Body);
            // ReSharper disable once AssignNullToNotNullAttribute
            var positionInit     = Expression.Bind(positionProperty, valueBlock);
            var memoryStreamInit = Expression.MemberInit(newMemoryStream, positionInit);

            var streamVariable = Expression.Variable(typeof(Stream), "stream");

            var assignStream = Expression.Assign(streamVariable, memoryStreamInit);

            var streamIsNull = Expression.Equal(streamVariable, Expression.Default(typeof(Stream)));

            var ifNullAssign = Expression.IfThen(streamIsNull, assignStream);

            var translated = ToReadableString(ifNullAssign);

            const string EXPECTED = @"
if (stream == null)
{
    stream = new MemoryStream
    {
        Position = 
        {
            Console.WriteLine(""Wat"");

            return ((long)Console.Read());
        }
    };
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldSplitLongTernaryOptionsOntoMultipleLines()
        {
            var oneEqualsTwo = Expression.Equal(Expression.Constant(1), Expression.Constant(2));

            var defaultInt = Expression.Default(typeof(int));

            var threeIntsFunc = Expression.Variable(typeof(Func <int, int, int, int>), "threeIntsFunc");
            var longVariable  = Expression.Variable(typeof(int), "thisVariableReallyHasAVeryLongNameIndeed");
            var threeIntsCall = Expression.Invoke(threeIntsFunc, longVariable, longVariable, longVariable);

            var ternary = Expression.Condition(oneEqualsTwo, defaultInt, threeIntsCall);

            var translated = ToReadableString(ternary);

            const string EXPECTED = @"
(1 == 2)
    ? default(int)
    : threeIntsFunc.Invoke(
        thisVariableReallyHasAVeryLongNameIndeed,
        thisVariableReallyHasAVeryLongNameIndeed,
        thisVariableReallyHasAVeryLongNameIndeed)";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
Пример #17
0
        public void ShouldTranslateAnIfElseIfStatement()
        {
            var intVariable   = Expression.Variable(typeof(int), "i");
            var intEqualsOne  = Expression.Equal(intVariable, Expression.Constant(1));
            var intEqualsTwo  = Expression.Equal(intVariable, Expression.Constant(2));
            var writeOne      = CreateLambda(() => Console.WriteLine("One"));
            var writeTwo      = CreateLambda(() => Console.WriteLine("Two"));
            var ifTwoWriteTwo = Expression.IfThen(intEqualsTwo, writeTwo.Body);
            var writeOneOrTwo = Expression.IfThenElse(intEqualsOne, writeOne.Body, ifTwoWriteTwo);

            var translated = ToReadableString(writeOneOrTwo);

            const string EXPECTED = @"
if (i == 1)
{
    Console.WriteLine(""One"");
}
else if (i == 2)
{
    Console.WriteLine(""Two"");
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateAMultipleLineTernaryAssignment()
        {
            var consoleRead = CreateLambda(() => Console.Read());

            var variableOne       = Expression.Variable(typeof(int), "one");
            var variableTwo       = Expression.Variable(typeof(int), "two");
            var resultVariableOne = Expression.Variable(typeof(int), "resultOne");

            var variableOneAssignment = Expression.Assign(variableOne, consoleRead.Body);
            var variableTwoAssignment = Expression.Assign(variableTwo, consoleRead.Body);

            var variableOneTimesTwo = Expression.Multiply(variableOne, variableTwo);
            var resultOneAssignment = Expression.Assign(resultVariableOne, variableOneTimesTwo);

            var ifTrueBlock = Expression.Block(
                new[] { variableOne, variableTwo, resultVariableOne },
                variableOneAssignment,
                variableTwoAssignment,
                resultOneAssignment,
                resultVariableOne);

            var variableThree     = Expression.Variable(typeof(int), "three");
            var variableFour      = Expression.Variable(typeof(int), "four");
            var resultVariableTwo = Expression.Variable(typeof(int), "resultTwo");

            var variableThreeAssignment = Expression.Assign(variableThree, consoleRead.Body);
            var variableFourAssignment  = Expression.Assign(variableFour, consoleRead.Body);

            var variableThreeDivideFour = Expression.Divide(variableThree, variableFour);
            var resultTwoAssignment     = Expression.Assign(resultVariableTwo, variableThreeDivideFour);

            var ifFalseBlock = Expression.Block(
                new[] { variableThree, variableFour, resultVariableTwo },
                variableThreeAssignment,
                variableFourAssignment,
                resultTwoAssignment,
                resultVariableTwo);

            var dateTimeNow      = Expression.Property(null, typeof(DateTime), "Now");
            var nowHour          = Expression.Property(dateTimeNow, "Hour");
            var nowHourModuloTwo = Expression.Modulo(nowHour, Expression.Constant(2));
            var nowHourIsEven    = Expression.Equal(nowHourModuloTwo, Expression.Constant(0));

            var conditional = Expression.Condition(nowHourIsEven, ifTrueBlock, ifFalseBlock);

            var resultVariable   = Expression.Variable(typeof(int), "result");
            var resultAssignment = Expression.Assign(resultVariable, conditional);

            var translated = ToReadableString(resultAssignment);

            const string EXPECTED = @"
result = ((DateTime.Now.Hour % 2) == 0)
    ? {
        var one = Console.Read();
        var two = Console.Read();
        var resultOne = one * two;

        return resultOne;
    }
    : {
        var three = Console.Read();
        var four = Console.Read();
        var resultTwo = three / four;

        return resultTwo;
    }";

            translated.ShouldBe(EXPECTED.TrimStart());
        }