public void ShouldTranslateALabelWithABlockDefaultValue()
        {
            var returnLabelTarget = Expression.Label(typeof(int), "Return");

            var intVariable         = Expression.Variable(typeof(int), "i");
            var variableInit        = Expression.Assign(intVariable, Expression.Constant(0));
            var variablePlusOne     = Expression.Add(intVariable, Expression.Constant(1));
            var variableAdditionOne = Expression.Assign(intVariable, variablePlusOne);
            var variablePlusTwo     = Expression.Add(intVariable, Expression.Constant(2));
            var variableAdditionTwo = Expression.Assign(intVariable, variablePlusTwo);

            var variableBlock = Expression.Block(variableAdditionTwo, intVariable);

            var returnVariableBlock = Expression.Label(returnLabelTarget, variableBlock);

            var returnBlock = Expression.Block(
                new[] { intVariable },
                variableInit,
                variableAdditionOne,
                returnVariableBlock);

            const string EXPECTED   = @"
var i = 0;
i = i + 1;

return 
{
    i = i + 2;

    return i;
};";
            var          translated = ToReadableString(returnBlock);

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateAVariableBlockLambdaWithAReturnExpression()
        {
            var listVariable = Expression.Variable(typeof(List <int>), "list");
            var createList   = CreateLambda(() => new List <int> {
                1, 2, 3
            });

            var listAssignment = Expression.Assign(listVariable, createList.Body);

            var toArrayMethod      = typeof(Enumerable).GetPublicStaticMethod("ToArray");
            var typedToArrayMethod = toArrayMethod.MakeGenericMethod(typeof(int));
            var listToArray        = Expression.Call(typedToArrayMethod, listVariable);

            var listBlock  = Expression.Block(new[] { listVariable }, listAssignment, listToArray);
            var listLambda = Expression.Lambda <Func <int[]> >(listBlock);

            var translated = ToReadableString(listLambda);

            const string EXPECTED = @"() =>
{
    var list = new List<int> { 1, 2, 3 };

    return list.ToArray();
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
Exemplo n.º 3
0
        public void ShouldTranslateAMultipleLineIfStatementTest()
        {
            var intVariable             = Expression.Variable(typeof(int), "i");
            var one                     = Expression.Constant(1);
            var intVariableLessThanOne  = Expression.LessThan(intVariable, one);
            var returnLabel             = Expression.Label(typeof(bool), "Return");
            var returnTrue              = Expression.Return(returnLabel, Expression.Constant(true));
            var ifLessThanOneReturnTrue = Expression.IfThen(intVariableLessThanOne, returnTrue);
            var five                    = Expression.Constant(5);
            var intVariableMoreThanFive = Expression.GreaterThan(intVariable, five);
            var returnMoreThanFive      = Expression.Label(returnLabel, intVariableMoreThanFive);
            var testBlock               = Expression.Block(ifLessThanOneReturnTrue, returnMoreThanFive);

            var writeHello            = CreateLambda(() => Console.WriteLine("Hello"));
            var writeVariable         = Expression.Variable(writeHello.Type, "write");
            var assignWrite           = Expression.Assign(writeVariable, writeHello);
            var ifTestPassesThenWrite = Expression.IfThen(testBlock, assignWrite);

            var translated = ToReadableString(ifTestPassesThenWrite);

            const string EXPECTED = @"
if ({
        if (i < 1)
        {
            return true;
        }

        return i > 5;
    })
{
    write = () => Console.WriteLine(""Hello"");
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldVarAssignVariablesInSiblingBlocks()
        {
            var intVariable1    = Expression.Variable(typeof(int), "i");
            var assignVariable1 = Expression.Assign(intVariable1, Expression.Constant(1));
            var variable1Block  = Expression.Block(new[] { intVariable1 }, assignVariable1);

            var intVariable2    = Expression.Variable(typeof(int), "j");
            var assignVariable2 = Expression.Assign(intVariable2, Expression.Constant(2));
            var variable2Block  = Expression.Block(new[] { intVariable2 }, assignVariable2);

            var assign1Or2 = Expression.IfThenElse(
                Expression.Constant(true),
                variable1Block,
                variable2Block);

            var translated = ToReadableString(assign1Or2);

            const string EXPECTED = @"
if (true)
{
    var i = 1;
}
else
{
    var j = 2;
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldNotVarAssignAVariableAssignedInATryButUsedInACatch()
        {
            var exceptionFactory = CreateLambda((int number) => new Exception(number.ToString()));
            var intVariable      = exceptionFactory.Parameters.First();
            var newException     = exceptionFactory.Body;

            var assignment      = Expression.Assign(intVariable, Expression.Constant(10));
            var assignmentBlock = Expression.Block(assignment, Expression.Default(typeof(void)));

            var catchBlock    = Expression.Catch(typeof(Exception), Expression.Throw(newException));
            var tryCatch      = Expression.TryCatch(assignmentBlock, catchBlock);
            var tryCatchBlock = Expression.Block(new[] { intVariable }, tryCatch);

            var translated = ToReadableString(tryCatchBlock);

            const string EXPECTED = @"
int number;
try
{
    number = 10;
}
catch
{
    throw new Exception(number.ToString());
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldNotVarAssignAnOuterBlockDeclaredVariable()
        {
            var nameVariable           = Expression.Variable(typeof(string), "name");
            var writeNameTwiceVariable = Expression.Variable(typeof(Action), "writeNameTwice");
            var writeLine                = CreateLambda(() => Console.WriteLine(default(string)));
            var writeLineMethod          = ((MethodCallExpression)writeLine.Body).Method;
            var writeLineCall            = Expression.Call(writeLineMethod, nameVariable);
            var writeNameTwice           = Expression.Block(writeLineCall, writeLineCall);
            var writeNameTwiceLambda     = Expression.Lambda(writeNameTwice);
            var writeNameTwiceAssignment = Expression.Assign(writeNameTwiceVariable, writeNameTwiceLambda);
            var nameAssignment           = Expression.Assign(nameVariable, Expression.Constant("Alice"));
            var writeNameTwiceCall       = Expression.Invoke(writeNameTwiceVariable);

            var block = Expression.Block(
                new[] { nameVariable, writeNameTwiceVariable },
                Expression.Block(writeNameTwiceAssignment),
                Expression.Block(nameAssignment, writeNameTwiceCall));

            var translated = ToReadableString(block);

            const string EXPECTED = @"
string name;
Action writeNameTwice = () =>
{
    Console.WriteLine(name);
    Console.WriteLine(name);
};

name = ""Alice"";
writeNameTwice.Invoke();";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateAMultipleVariableBlockWithNoReturnValue()
        {
            var countOneVariable      = Expression.Variable(typeof(int), "countOne");
            var countTwoVariable      = Expression.Variable(typeof(int), "countTwo");
            var countThreeVariable    = Expression.Variable(typeof(byte), "countThree");
            var assignOneToCountOne   = Expression.Assign(countOneVariable, Expression.Constant(1));
            var assignTwoToCountTwo   = Expression.Assign(countTwoVariable, Expression.Constant(2));
            var sumCounts             = Expression.Add(countOneVariable, countTwoVariable);
            var castSumToBye          = Expression.Convert(sumCounts, typeof(byte));
            var assignSumToCountThree = Expression.Assign(countThreeVariable, castSumToBye);

            var countBlock = Expression.Block(
                new[] { countOneVariable, countTwoVariable, countThreeVariable },
                assignOneToCountOne,
                assignTwoToCountTwo,
                assignSumToCountThree);

            var translated = ToReadableString(countBlock);

            const string EXPECTED = @"
var countOne = 1;
var countTwo = 2;
var countThree = (byte)(countOne + countTwo);";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldDeclareAVariableIfUsedBeforeInitialisation()
        {
            var nameVariable      = Expression.Variable(typeof(string), "name");
            var getNameVariable   = Expression.Variable(typeof(Func <string>), "getName");
            var getNameLambda     = Expression.Lambda(nameVariable);
            var getNameAssignment = Expression.Assign(getNameVariable, getNameLambda);
            var nameAssignment    = Expression.Assign(nameVariable, Expression.Constant("Fred"));
            var getNameCall       = Expression.Invoke(getNameVariable);

            var block = Expression.Block(
                new[] { nameVariable, getNameVariable },
                getNameAssignment,
                nameAssignment,
                getNameCall);

            var translated = ToReadableString(block);

            const string EXPECTED = @"
string name;
Func<string> getName = () => name;
name = ""Fred"";

return getName.Invoke();";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldAssignTheResultOfATryCatch()
        {
            var intVariable = Expression.Variable(typeof(int), "i");

            var read = CreateLambda(() => Console.Read());

            var returnDefault = Expression.Catch(typeof(IOException), Expression.Default(typeof(int)));
            var readOrDefault = Expression.TryCatch(read.Body, returnDefault);

            var assignReadOrDefault = Expression.Assign(intVariable, readOrDefault);

            var translated = ToReadableString(assignReadOrDefault);

            const string EXPECTED = @"
i =
{
    try
    {
        return Console.Read();
    }
    catch (IOException)
    {
        return default(int);
    }
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldTranslateAVariableBlockLambdaWithAReturnValue()
        {
            var countVariable   = Expression.Variable(typeof(ushort), "count");
            var countEqualsZero = Expression.Assign(countVariable, Expression.Constant((ushort)0));
            var incrementCount  = Expression.Increment(countVariable);
            var returnCount     = countVariable;

            var countBlock = Expression.Block(
                new[] { countVariable },
                countEqualsZero,
                incrementCount,
                returnCount);

            var countLambda = Expression.Lambda <Func <ushort> >(countBlock);

            var translated = ToReadableString(countLambda);

            const string EXPECTED = @"() =>
{
    var count = 0;
    ++count;

    return count;
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldNameAnUnnamedVariable()
        {
            var intVariable        = Expression.Variable(typeof(int));
            var assignDefaultToInt = Expression.Assign(intVariable, Expression.Default(typeof(int)));

            var translated = ToReadableString(assignDefaultToInt);

            translated.ShouldBe("@int = default(int)");
        }
        public void ShouldTranslateAnAssignment()
        {
            var intVariable        = Expression.Variable(typeof(int), "i");
            var assignDefaultToInt = Expression.Assign(intVariable, Expression.Default(typeof(int)));

            var translated = ToReadableString(assignDefaultToInt);

            translated.ShouldBe("i = default(int)");
        }
        public void ShouldNotWrapAnAssignmentValueInParentheses()
        {
            var intVariable        = Expression.Variable(typeof(int), "i");
            var oneMultipliedByTwo = Expression.Multiply(Expression.Constant(1), Expression.Constant(2));
            var assignment         = Expression.Assign(intVariable, oneMultipliedByTwo);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("i = 1 * 2");
        }
        public void ShouldTranslateAnExtensionAssignment()
        {
            var value             = new ExtensionExpression(typeof(int));
            var extensionVariable = Expression.Variable(value.Type, "ext");
            var assignment        = Expression.Assign(extensionVariable, value);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("ext = " + value);
        }
Exemplo n.º 15
0
        public void ShouldUseFriendlyNamesForArrays()
        {
            var intArrayVariable = Expression.Variable(typeof(int[]), "ints");
            var assignNull       = Expression.Assign(intArrayVariable, Expression.Default(intArrayVariable.Type));
            var assignNullBlock  = Expression.Block(new[] { intArrayVariable }, assignNull);

            var translated = ToReadableString(assignNullBlock);

            translated.ShouldBe("var ints = default(int[]);");
        }
        public void ShouldNameAnUnnamedParameter()
        {
            var stringParameter           = Expression.Parameter(typeof(string), string.Empty);
            var stringVariable            = Expression.Variable(typeof(string), "  ");
            var assignVariableToParameter = Expression.Assign(stringVariable, stringParameter);

            var translated = ToReadableString(assignVariableToParameter);

            translated.ShouldBe("string1 = string2");
        }
        public void ShouldTranslateANegatedBooleanAssignment()
        {
            var boolVariable1 = Expression.Variable(typeof(bool), "isItNot");
            var boolVariable2 = Expression.Variable(typeof(bool), "isIt");
            var assignBool    = Expression.Assign(boolVariable1, Expression.IsFalse(boolVariable2));
            var negated       = Expression.Not(assignBool);

            var translated = ToReadableString(negated);

            translated.ShouldBe("!(isItNot = !isIt)");
        }
        public void ShouldTranslateAnAssignmentResultAssignment()
        {
            var intVariable1    = Expression.Variable(typeof(int), "i");
            var intVariable2    = Expression.Variable(typeof(int), "j");
            var assignVariable2 = Expression.Assign(intVariable2, Expression.Constant(1));
            var setVariableOneToAssignmentResult = Expression.Assign(intVariable1, assignVariable2);

            var translated = ToReadableString(setVariableOneToAssignmentResult);

            translated.ShouldBe("i = j = 1");
        }
        public void ShouldTranslateDbNullValue()
        {
            var dbParameter      = Expression.Variable(typeof(DbParameter), "param");
            var parameterValue   = Expression.Property(dbParameter, "Value");
            var dbNull           = Expression.Constant(DBNull.Value, typeof(DBNull));
            var setParamToDbNull = Expression.Assign(parameterValue, dbNull);

            var translated = ToReadableString(setParamToDbNull);

            translated.ShouldBe("param.Value = DBNull.Value");
        }
        public void ShouldTranslateImplicitOperatorUse()
        {
            var adderToString = CreateLambda <string>(() => new CustomAdder());

            var stringVariable = Expression.Variable(typeof(string), "str");
            var assignment     = Expression.Assign(stringVariable, adderToString.Body);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("str = new CustomAdder()");
        }
        public void ShouldTranslateExplicitOperatorUse()
        {
            var adderToString = CreateLambda(() => (int)new CustomAdder());

            var intVariable = Expression.Variable(typeof(int), "i");
            var assignment  = Expression.Assign(intVariable, adderToString.Body);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("i = (int)new CustomAdder()");
        }
        public void ShouldAssignAMultiplicationToStringResult()
        {
            var timesThreeToString = CreateLambda((int i) => (i * 3).ToString());

            var stringVariable   = Expression.Variable(typeof(string), "value");
            var stringAssignment = Expression.Assign(stringVariable, timesThreeToString.Body);

            var translated = ToReadableString(stringAssignment);

            translated.ShouldBe("value = (i * 3).ToString()");
        }
        public void ShouldNotVarAssignAVariableOfNonImpliedType()
        {
            var intsVariable = Expression.Variable(typeof(IEnumerable <int>), "ints");
            var newArray     = Expression.NewArrayBounds(typeof(int), Expression.Constant(2));
            var assignment   = Expression.Assign(intsVariable, newArray);

            var block = Expression.Block(new[] { intsVariable }, assignment);

            var translated = ToReadableString(block);

            translated.ShouldBe("IEnumerable<int> ints = new int[2];");
        }
        public void ShouldNotRemoveParenthesesFromACastObjectChainedMethodCall()
        {
            var intArrayConverter = CreateLambda(
                (IList <int> ints) => ((int[])ints).ToString().Split(','));

            var stringArrayVariable = Expression.Variable(typeof(string[]), "strings");
            var assignment          = Expression.Assign(stringArrayVariable, intArrayConverter.Body);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("strings = ((int[])ints).ToString().Split(',')");
        }
        public void ShouldTranslateImplicitMethodOperatorUse()
        {
            var stringVariable = Expression.Variable(typeof(string), "str");
            var stringOperator = typeof(CustomAdder).GetImplicitOperator(o => o.To <string>());
            var adderInstance  = Expression.New(typeof(CustomAdder).GetPublicInstanceConstructor());
            var operatorCall   = Expression.Call(stringOperator, adderInstance);
            var assignment     = Expression.Assign(stringVariable, operatorCall);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("str = new CustomAdder()");
        }
        public void ShouldTranslateExplicitMethodOperatorUse()
        {
            var intVariable   = Expression.Variable(typeof(int), "i");
            var intOperator   = typeof(CustomAdder).GetExplicitOperator(o => o.To <int>());
            var adderInstance = Expression.New(typeof(CustomAdder).GetPublicInstanceConstructor());
            var operatorCall  = Expression.Call(intOperator, adderInstance);
            var assignment    = Expression.Assign(intVariable, operatorCall);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("i = (int)new CustomAdder()");
        }
        public void ShouldNotRemoveParenthesesFromALambdaInvokeResultAssignment()
        {
            var intsAdder          = CreateLambda((int a, int b) => a + b);
            var one                = Expression.Constant(1);
            var two                = Expression.Constant(2);
            var lambdaInvocation   = Expression.Invoke(intsAdder, one, two);
            var result             = Expression.Variable(typeof(int), "result");
            var assignInvokeResult = Expression.Assign(result, lambdaInvocation);

            const string EXPECTED   = "result = ((a, b) => a + b).Invoke(1, 2)";
            var          translated = ToReadableString(assignInvokeResult);

            translated.ShouldBe(EXPECTED);
        }
        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 ShouldTranslateMultilineBlockSingleMethodArguments()
        {
            var intVariable          = Expression.Variable(typeof(int), "i");
            var variableInit         = Expression.Assign(intVariable, Expression.Constant(3));
            var variableMultiplyFive = Expression.Multiply(intVariable, Expression.Constant(5));
            var variableAdditionOne  = Expression.Assign(intVariable, variableMultiplyFive);
            var variableDivideThree  = Expression.Divide(intVariable, Expression.Constant(3));
            var variableAdditionTwo  = Expression.Assign(intVariable, variableDivideThree);

            var argumentBlock = Expression.Block(
                new[] { intVariable },
                variableInit,
                variableAdditionOne,
                variableAdditionTwo,
                intVariable);

            var catchBlock = Expression.Catch(
                typeof(Exception),
                Expression.Block(ReadableExpression.Comment("So what!"), Expression.Constant(0)));

            var tryCatch = Expression.TryCatch(argumentBlock, catchBlock);

            var collectionVariable = Expression.Variable(typeof(ICollection <int>), "ints");
            var addMethod          = collectionVariable.Type.GetPublicInstanceMethod("Add");
            var addMethodCall      = Expression.Call(collectionVariable, addMethod, tryCatch);

            const string EXPECTED = @"
ints.Add(
{
    try
    {
        var i = 3;
        i = i * 5;
        i = i / 3;

        return i;
    }
    catch
    {
        // So what!
        return 0;
    }
})";

            var translated = ToReadableString(addMethodCall);

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldIgnoreABlankLabelTargetLine()
        {
            var intVariable   = Expression.Variable(typeof(int), "i");
            var intAssignment = Expression.Assign(intVariable, Expression.Constant(0));

            var labelTarget = Expression.Label(typeof(void), "LabelTarget");

            var intAssignmentBlock = Expression.Block(
                new[] { intVariable },
                intAssignment,
                Expression.Label(labelTarget));

            var translated = ToReadableString(intAssignmentBlock);

            translated.ShouldBe("var i = 0;");
        }