public void ShouldTranslateAComplexMethodArgument()
        {
            var intVariable        = Expression.Variable(typeof(int), "intValue");
            var dictionaryVariable = Expression.Variable(typeof(Dictionary <string, int>), "dictionary_String_IntValues");
            var tryGetValueMethod  = dictionaryVariable.Type.GetPublicInstanceMethod("TryGetValue", 2);
            var key             = Expression.Constant("NumberThatIWantToGet");
            var tryGetValueCall = Expression.Call(dictionaryVariable, tryGetValueMethod, key, intVariable);

            var defaultInt          = Expression.Default(typeof(int));
            var valueOrDefault      = Expression.Condition(tryGetValueCall, intVariable, defaultInt);
            var valueOrDefaultBlock = Expression.Block(new[] { intVariable }, valueOrDefault);

            var helperCtor = typeof(HelperClass).GetPublicInstanceConstructors().First();
            var helper     = Expression.New(helperCtor, defaultInt, defaultInt, defaultInt);
            var intsMethod = helper.Type.GetPublicInstanceMethod(nameof(HelperClass.GiveMeSomeInts));
            var methodCall = Expression.Call(helper, intsMethod, defaultInt, valueOrDefaultBlock, defaultInt);

            var translated = ToReadableString(methodCall);

            const string EXPECTED = @"
new HelperClass(default(int), default(int), default(int)).GiveMeSomeInts(
    default(int),
    {
        int intValue;
        return dictionary_String_IntValues.TryGetValue(""NumberThatIWantToGet"", out intValue)
            ? intValue
            : default(int);
    },
    default(int))";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
Exemplo n.º 2
0
        public void ShouldNotWrapSingleExpressionTernaryConditionsInParentheses()
        {
            var ternary = Expression.Condition(
                Expression.Constant(false),
                Expression.Constant(1),
                Expression.Constant(2));

            var translated = ToReadableString(ternary);

            translated.ShouldBe("false ? 1 : 2");
        }
Exemplo n.º 3
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 ShouldTranslateAssignmentsOfNestedVariableBlocksWithANestedTernaryReturnValue()
        {
            var objectVariable = Expression.Variable(typeof(object), "id");
            var objectValue    = Expression.Variable(typeof(object), "value");
            var longVariable   = Expression.Variable(typeof(long), "number");
            var longValue      = Expression.Variable(typeof(long), "numberValue");

            var longTryParse = Expression.Call(
                null,
                typeof(long).GetPublicStaticMethod("TryParse", parameterCount: 2),
                Expression.Call(objectVariable, typeof(object).GetPublicInstanceMethod("ToString")),
                longValue);

            var objectNotNull = Expression.NotEqual(objectVariable, Expression.Default(typeof(object)));
            var defaultlong   = Expression.Default(typeof(long));

            var objectAslongOrDefault = Expression.Condition(
                objectNotNull,
                Expression.Condition(longTryParse, longValue, defaultlong),
                defaultlong);

            var longParseInnerBlock = Expression.Block(new[] { longValue }, objectAslongOrDefault);

            var longParseOuterBlock = Expression.Block(
                new[] { objectVariable },
                Expression.Assign(objectVariable, objectValue),
                longParseInnerBlock);

            var longAssignment = Expression.Assign(longVariable, longParseOuterBlock);

            var translated = ToReadableString(longAssignment);

            const string EXPECTED = @"
number =
{
    var id = value;

    long numberValue;
    return (id != null)
        ? long.TryParse(id.ToString(), out numberValue) ? numberValue : default(long)
        : default(long);
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        public void ShouldWrapAnAssignmentTernaryTestInParentheses()
        {
            var intVariable1 = Expression.Variable(typeof(int), "i");
            var intVariable2 = Expression.Variable(typeof(int), "j");

            var intVariable2GreaterThanOne = Expression.GreaterThan(intVariable2, Expression.Constant(1));

            var threeOrDefault = Expression.Condition(
                intVariable2GreaterThanOne,
                Expression.Constant(3),
                Expression.Default(typeof(int)));

            var assignment = Expression.Assign(intVariable1, threeOrDefault);

            var translated = ToReadableString(assignment);

            translated.ShouldBe("i = (j > 1) ? 3 : default(int)");
        }
Exemplo n.º 7
0
        public void ShouldNotWrapMethodCallTernaryConditionsInParentheses()
        {
            var method = typeof(MethodCallHelper).GetPublicInstanceMethod("MultipleParameterMethod");

            var methodCall = Expression.Call(
                Expression.Variable(typeof(MethodCallHelper), "helper"),
                method,
                Expression.Constant("hello"),
                Expression.Constant(123));

            var ternary = Expression.Condition(
                methodCall,
                Expression.Constant(1),
                Expression.Constant(2));

            var translated = ToReadableString(ternary);

            translated.ShouldBe("helper.MultipleParameterMethod(\"hello\", 123) ? 1 : 2");
        }
        public void ShouldTranslateAssignmentsOfNestedVariableBlocksWithATernaryReturnValue()
        {
            var objectVariable = Expression.Variable(typeof(object), "id");
            var objectValue    = Expression.Variable(typeof(object), "value");
            var intVariable    = Expression.Variable(typeof(int), "num");
            var intValue       = Expression.Variable(typeof(int), "numValue");

            var objectNotNull = Expression.NotEqual(objectVariable, Expression.Default(typeof(object)));
            var defaultInt    = Expression.Default(typeof(int));

            var intTryParse = Expression.Call(
                typeof(int).GetPublicStaticMethod("TryParse", parameterCount: 2),
                Expression.Condition(
                    objectNotNull,
                    Expression.Call(objectVariable, typeof(object).GetPublicInstanceMethod("ToString")),
                    Expression.Default(typeof(string))),
                intValue);

            var objectAsIntOrDefault = Expression.Condition(intTryParse, intValue, defaultInt);

            var intParseInnerBlock = Expression.Block(new[] { intValue }, objectAsIntOrDefault);

            var intParseOuterBlock = Expression.Block(
                new[] { objectVariable },
                Expression.Assign(objectVariable, objectValue),
                intParseInnerBlock);

            var intAssignment = Expression.Assign(intVariable, intParseOuterBlock);

            var translated = ToReadableString(intAssignment);

            const string EXPECTED = @"
num =
{
    var id = value;

    int numValue;
    return int.TryParse((id != null) ? id.ToString() : null, out numValue) ? numValue : default(int);
}";

            translated.ShouldBe(EXPECTED.TrimStart());
        }
        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 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?>();");
        }
Exemplo n.º 11
0
        public void ShouldTranslateAnIfStatementWithAConditional()
        {
            var guidVariable        = Expression.Variable(typeof(Guid), "guid");
            var defaultGuid         = Expression.Default(typeof(Guid));
            var guidNotDefault      = Expression.NotEqual(guidVariable, defaultGuid);
            var guidEmpty           = Expression.Field(null, typeof(Guid), "Empty");
            var guidNotEmpty        = Expression.NotEqual(guidVariable, guidEmpty);
            var falseConstant       = Expression.Constant(false);
            var guidNotEmptyOrFalse = Expression.Condition(guidNotDefault, guidNotEmpty, falseConstant);
            var writeGuidFun        = CreateLambda(() => Console.Write("GUID FUN!"));
            var ifNotEmptyThenWrite = Expression.IfThen(guidNotEmptyOrFalse, writeGuidFun.Body);

            var translated = ToReadableString(ifNotEmptyThenWrite);

            const string EXPECTED = @"
if ((guid != default(Guid)) ? guid != Guid.Empty : false)
{
    Console.Write(""GUID FUN!"");
}";

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