public string Translate(Expression expression, TranslationContext context) { var quote = (UnaryExpression)expression; if (context.Settings.DoNotCommentQuotedLambdas) { return(context.TranslateAsCodeBlock(quote.Operand)); } var comment = ReadableExpression.Comment("Quoted to induce a closure:"); var quotedLambdaBlock = Expression.Block(comment, quote.Operand); var translatedLambda = context .TranslateCodeBlock(quotedLambdaBlock) .Indented() .WithoutCurlyBraces(); return(Environment.NewLine + translatedLambda); }
public void ShouldTranslateASwitchStatementWithADefault() { var intVariable = Expression.Variable(typeof(int), "i"); var writeOne = CreateLambda(() => Console.WriteLine("One")); var writeTwo = CreateLambda(() => Console.WriteLine("Two")); var writeThree = CreateLambda(() => Console.WriteLine("Three")); var writeOneTwoThree = Expression.Block(writeOne.Body, writeTwo.Body, writeThree.Body); var switchStatement = Expression.Switch( intVariable, writeOneTwoThree, Expression.SwitchCase(writeOne.Body, Expression.Constant(1)), Expression.SwitchCase(writeTwo.Body, Expression.Constant(2)), Expression.SwitchCase(writeThree.Body, Expression.Constant(3))); var translated = ToReadableString(switchStatement); const string EXPECTED = @" switch (i) { case 1: Console.WriteLine(""One""); break; case 2: Console.WriteLine(""Two""); break; case 3: Console.WriteLine(""Three""); break; default: Console.WriteLine(""One""); Console.WriteLine(""Two""); Console.WriteLine(""Three""); break; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
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 ShouldIncludeAReturnKeywordForACoalesce() { var stringVariable1 = Expression.Variable(typeof(string), "myString"); var stringVariable2 = Expression.Variable(typeof(string), "yourString"); var assignStrings = Expression.Assign(stringVariable1, stringVariable2); var stringEmpty = Expression.Field(null, typeof(string), "Empty"); var variableOrNull = Expression.Coalesce(stringVariable1, stringEmpty); var coalesceBlock = Expression.Block(assignStrings, variableOrNull); var translated = ToReadableString(coalesceBlock); const string EXPECTED = @" var myString = yourString; return (myString ?? string.Empty);"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldSplitLongConstructorArgumentListsOntoMultipleLines() { var helperVariable = Expression.Variable(typeof(HelperClass), "helper"); var helperConstructor = helperVariable.Type.GetConstructors().First(); var longVariable = Expression.Variable(typeof(int), "thisVariableReallyHasAVeryLongNameIndeed"); var newHelper = Expression.New(helperConstructor, longVariable, longVariable, longVariable); var helperAssignment = Expression.Assign(helperVariable, newHelper); var longArgumentListBlock = Expression.Block(new[] { helperVariable }, helperAssignment); var translated = ToReadableString(longArgumentListBlock); const string EXPECTED = @" var helper = new HelperClass( thisVariableReallyHasAVeryLongNameIndeed, thisVariableReallyHasAVeryLongNameIndeed, thisVariableReallyHasAVeryLongNameIndeed);"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldSplitLongInvokeArgumentListsOntoMultipleLines() { var longVariable = Expression.Variable(typeof(int), "thisVariableReallyHasAVeryLongNameIndeed"); var threeIntsAction = Expression.Variable(typeof(Action <int, int, int>), "threeIntsAction"); var threeIntsCall = Expression.Invoke(threeIntsAction, longVariable, longVariable, longVariable); var longArgumentListBlock = Expression.Block(new[] { longVariable, threeIntsAction }, threeIntsCall); var translated = ToReadableString(longArgumentListBlock); const string EXPECTED = @" int thisVariableReallyHasAVeryLongNameIndeed; Action<int, int, int> threeIntsAction; threeIntsAction.Invoke( thisVariableReallyHasAVeryLongNameIndeed, thisVariableReallyHasAVeryLongNameIndeed, thisVariableReallyHasAVeryLongNameIndeed);"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslatedMultipleLineValueBlockAssignments() { var linqSelect = CreateLambda((string[] ints) => ints.Select(int.Parse)); var selectMethod = ((MethodCallExpression)linqSelect.Body).Method; var getStringArray = CreateLambda(() => new[] { "1", "2", "blah" }); var stringArray = getStringArray.Body; // ReSharper disable once RedundantAssignment var intTryParse = CreateLambda((string str, int value) => int.TryParse(str, out value) ? value : 0); var stringParameter = intTryParse.Parameters[0]; var intVariable = intTryParse.Parameters[1]; var tryParseTernary = intTryParse.Body; var tryParseBlock = Expression.Block(new[] { intVariable }, tryParseTernary); var tryParseLambda = Expression.Lambda <Func <string, int> >(tryParseBlock, stringParameter); var selectCall = Expression.Call(selectMethod, stringArray, tryParseLambda); var linqToArray = CreateLambda((IEnumerable <int> ints) => ints.ToArray()); var toArrayMethod = ((MethodCallExpression)linqToArray.Body).Method; var toArrayCall = Expression.Call(toArrayMethod, selectCall); var resultVariable = Expression.Variable(typeof(IList <int>), "result"); var assignment = Expression.Assign(resultVariable, toArrayCall); var assignmentBlock = Expression.Block(assignment); var translation = ToReadableString(assignmentBlock); const string EXPECTED = @" IList<int> result = new[] { ""1"", ""2"", ""blah"" } .Select(str => { int value; return int.TryParse(str, out value) ? value : 0; }) .ToArray();"; translation.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 ShouldTranslateAVariableBlockWithNoReturnValue() { var countVariable = Expression.Variable(typeof(int), "count"); var assignZeroToCount = Expression.Assign(countVariable, Expression.Constant(0)); var incrementCount = Expression.Increment(countVariable); var returnVoid = Expression.Default(typeof(void)); var countBlock = Expression.Block( new[] { countVariable }, assignZeroToCount, incrementCount, returnVoid); var translated = ToReadableString(countBlock); const string EXPECTED = @" var count = 0; ++count;"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAMultipleLineIfStatement() { var intVariable = Expression.Variable(typeof(int), "i"); var one = Expression.Constant(1); var intVariableLessThanOne = Expression.LessThan(intVariable, one); var writeHello = CreateLambda(() => Console.WriteLine("Hello")); var writeThere = CreateLambda(() => Console.WriteLine("There")); var writeBlock = Expression.Block(writeHello.Body, writeThere.Body); var ifLessThanOneThenWrite = Expression.IfThen(intVariableLessThanOne, writeBlock); var translated = ToReadableString(ifLessThanOneThenWrite); const string EXPECTED = @" if (i < 1) { Console.WriteLine(""Hello""); Console.WriteLine(""There""); }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateABlockAssignmentResultAssignment() { var longVariable = Expression.Variable(typeof(long), "i"); var intVariable = Expression.Variable(typeof(int), "j"); var assignInt = Expression.Assign(intVariable, Expression.Constant(10)); var castAssignmentResult = Expression.Convert(assignInt, typeof(long)); var assignIntBlock = Expression.Block(castAssignmentResult); var setLongVariableToAssignmentResult = Expression.Assign(longVariable, assignIntBlock); var assignmentBlock = Expression.Block( new[] { longVariable, intVariable }, setLongVariableToAssignmentResult); var translated = ToReadableString(assignmentBlock); const string EXPECTED = @" int j; var i = ((long)(j = 10));"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateSingleStatementValueBlockAssignments() { var valueConditional = GetReturnStatementBlock(out var existingInts); var singleStatementValueBlock = Expression.Block( new[] { existingInts }, valueConditional); var resultVariable = Expression.Variable(singleStatementValueBlock.Type, "result"); var resultOneAssignment = Expression.Assign(resultVariable, singleStatementValueBlock); var translated = ToReadableString(resultOneAssignment); const string EXPECTED = @" result = { List<int> ints; return (ints == null) ? new List<int>() : { var enumerator = ints.GetEnumerator(); while (true) { if (enumerator.MoveNext()) { var item = enumerator.Current; ints.Add(item); } else { break; } } return ints; }; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
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 ShouldTranslateAShortCircuitingIfStatement() { var oneCastToDouble = Expression.Convert(Expression.Constant(1), typeof(double?)); var ifTrueOne = Expression.IfThen(Expression.Constant(true), oneCastToDouble); var nullDouble = Expression.Constant(null, typeof(double?)); var block = Expression.Block(ifTrueOne, nullDouble); var translated = ToReadableString(block); const string EXPECTED = @" if (true) { return (double?)1; } return null;"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateASwitchWithMultipleVariableAssignments() { var countVariable = Expression.Variable(typeof(int), "count"); var intVariable = Expression.Variable(typeof(int), "i"); var switchStatement = Expression.Switch( intVariable, Expression.Assign(countVariable, Expression.Constant(0)), Enumerable .Range(1, 2) .Select(i => Expression.SwitchCase( Expression.Assign(countVariable, Expression.Constant(i * 2)), Expression.Constant(i))) .ToArray()); var switchBlock = Expression.Block(new[] { countVariable }, switchStatement); var translated = ToReadableString(switchBlock); const string EXPECTED = @" int count; switch (i) { case 1: count = 2; break; case 2: count = 4; break; default: count = 0; break; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAMemberInitReturnValue() { var company = Expression.Variable(typeof(Company), "c"); var ceo = Expression.Variable(typeof(Employee), "ceo"); var ceoAddress = Expression.Property(ceo, "Address"); var assignCeo = Expression.Assign(ceo, Expression.Property(company, "Ceo")); var newAddress = Expression.MemberInit( Expression.New(typeof(Address).GetPublicInstanceConstructor()), Expression.Bind( typeof(Address).GetPublicInstanceMember("Line1"), Expression.Property(ceoAddress, "Line1"))); var newEmployee = Expression.MemberInit( Expression.New(typeof(Employee).GetPublicInstanceConstructor()), Expression.Bind( typeof(Employee).GetPublicInstanceMember("Address"), newAddress) ); var block = Expression.Block(assignCeo, newEmployee); var translated = ToReadableString(block); const string EXPECTED = @" var ceo = c.Ceo; return new WhenTranslatingBlocks.Employee { Address = new WhenTranslatingBlocks.Address { Line1 = ceo.Address.Line1 } };"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAMultiLineCheckedSubtractionAssignment() { var intVariable = Expression.Variable(typeof(int), "i"); var consoleRead = CreateLambda(() => Console.Read()); var variableOne = Expression.Variable(typeof(int), "one"); var variableTwo = Expression.Variable(typeof(int), "two"); var variableOneAssignment = Expression.Assign(variableOne, consoleRead.Body); var variableTwoAssignment = Expression.Assign(variableTwo, consoleRead.Body); var variableOnePlusTwo = Expression.Add(variableOne, variableTwo); var valueBlock = Expression.Block( new[] { variableOne, variableTwo }, variableOneAssignment, variableTwoAssignment, variableOnePlusTwo); var substractOneAndAssign = Expression.SubtractAssignChecked(intVariable, valueBlock); var translated = ToReadableString(substractOneAndAssign); const string EXPECTED = @" checked { i -= { var one = Console.Read(); var two = Console.Read(); return (one + two); } }"; 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 ShouldTranslateAReturnStatementWithAValue() { var returnTarget = Expression.Label(typeof(int)); var returnOne = Expression.Return(returnTarget, Expression.Constant(1)); var returnTwo = Expression.Return(returnTarget, Expression.Constant(2)); var numberParameter = Expression.Parameter(typeof(string), "i"); var numberEqualsOne = Expression.Equal(numberParameter, Expression.Constant("One")); var ifOneReturnOneElseTwo = Expression.IfThenElse(numberEqualsOne, returnOne, returnTwo); var returnLabel = Expression.Label(returnTarget, Expression.Constant(0)); var gotoBlock = Expression.Block(ifOneReturnOneElseTwo, 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; } else { return 2; } return 0; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAVariableAssignmentWithinACondition() { var countVariable = Expression.Variable(typeof(int), "count"); var assignFiveToCount = Expression.Assign(countVariable, Expression.Constant(5)); var isResultLessThanTen = Expression.LessThan(assignFiveToCount, Expression.Constant(10)); var ifResultIsLessThanTenDoNothing = Expression.IfThen(isResultLessThanTen, Expression.Default(typeof(void))); var countBlock = Expression.Block(new[] { countVariable }, ifResultIsLessThanTenDoNothing); var countLambda = Expression.Lambda <Action>(countBlock); var translated = ToReadableString(countLambda); const string EXPECTED = @"() => { int count; if ((count = 5) < 10) { } }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAVariableBlockLambdaWithNoReturnValue() { var countVariable = Expression.Variable(typeof(short), "count"); var assignTenToCount = Expression.Assign(countVariable, Expression.Constant((short)10)); var decrementCount = Expression.Decrement(countVariable); var countBlock = Expression.Block( new[] { countVariable }, assignTenToCount, decrementCount); var countLambda = Expression.Lambda <Action>(countBlock); var translated = ToReadableString(countLambda); const string EXPECTED = @"() => { var count = 10; --count; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateATryCatchFinally() { var writeHello = CreateLambda(() => Console.Write("Hello")); var writeNotSupported = CreateLambda((NotSupportedException ex) => Console.Write("NotSupported!")); var notSupportedCatchBlock = Expression.Catch(writeNotSupported.Parameters.First(), writeNotSupported.Body); var writeException = CreateLambda((Exception ex) => Console.Write(ex)); var topLevelCatchBlock = Expression.Catch(writeException.Parameters.First(), writeException.Body); var writeFinished = CreateLambda(() => Console.WriteLine("Finished!")); var writeGoodbye = CreateLambda(() => Console.Write("Goodbye")); var finallyBlock = Expression.Block(writeFinished.Body, writeGoodbye.Body); var tryCatchFinally = Expression.TryCatchFinally(writeHello.Body, finallyBlock, notSupportedCatchBlock, topLevelCatchBlock); var translated = ToReadableString(tryCatchFinally); const string EXPECTED = @" try { Console.Write(""Hello""); } catch (NotSupportedException) { Console.Write(""NotSupported!""); } catch (Exception ex) { Console.Write(ex); } finally { Console.WriteLine(""Finished!""); Console.Write(""Goodbye""); }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateAReturnStatementWithABlock() { var returnLabelTarget = Expression.Label(typeof(int)); 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( new[] { intVariable }, variableInit, variableAdditionOne, variableAdditionTwo, intVariable); var returnVariableBlock = Expression.Return(returnLabelTarget, variableBlock); var returnBlock = Expression.Block(returnVariableBlock); const string EXPECTED = @" return { var i = 0; i = i + 1; i = i + 2; return i; };"; var translated = ToReadableString(returnBlock); translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldIncludeAReturnKeywordForANewObjectStatement() { var exception = Expression.Variable(typeof(Exception), "ex"); var newList = Expression.New(typeof(List <string>).GetConstructors().First()); var rethrow = Expression.Rethrow(newList.Type); var globalCatchAndRethrow = Expression.Catch(exception, rethrow); var tryCatch = Expression.TryCatch(newList, globalCatchAndRethrow); var tryCatchBlock = Expression.Block(tryCatch); var translated = ToReadableString(tryCatchBlock); const string EXPECTED = @" try { return new List<string>(); } catch { throw; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateACheckedMultiplicationExpression() { var consoleRead = CreateLambda(() => Console.Read()); var variableOne = Expression.Variable(typeof(int), "one"); var variableTwo = Expression.Variable(typeof(int), "two"); var variableOneAssignment = Expression.Assign(variableOne, consoleRead.Body); var variableTwoAssignment = Expression.Assign(variableTwo, consoleRead.Body); var variableOnePlusTwo = Expression.Add(variableOne, variableTwo); var valueOneBlock = Expression.Block( new[] { variableOne, variableTwo }, variableOneAssignment, variableTwoAssignment, variableOnePlusTwo); var intVariable = Expression.Parameter(typeof(int), "i"); var checkedMultiplication = Expression.MultiplyChecked(valueOneBlock, intVariable); var translated = ToReadableString(checkedMultiplication); const string EXPECTED = @" checked { { var one = Console.Read(); var two = Console.Read(); return (one + two); } * i }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateANestedBlockAssignment() { var consoleRead = CreateLambda(() => Console.Read()); var variableOne = Expression.Variable(typeof(int), "one"); var variableTwo = Expression.Variable(typeof(int), "two"); var variableOneAssignment = Expression.Assign(variableOne, consoleRead.Body); var variableTwoAssignment = Expression.Assign(variableTwo, consoleRead.Body); var variableOneMinusTwo = Expression.Subtract(variableOne, variableTwo); var valueBlock = Expression.Block( new[] { variableOne, variableTwo }, variableOneAssignment, variableTwoAssignment, variableOneMinusTwo); var wrappingBlock = Expression.Block(valueBlock); var resultVariable = Expression.Variable(typeof(int), "result"); var resultOneAssignment = Expression.Assign(resultVariable, wrappingBlock); var translated = ToReadableString(resultOneAssignment); const string EXPECTED = @" result = { var one = Console.Read(); var two = Console.Read(); return (one - 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()); }
public void ShouldVarAssignAVariableUsedInNestedConstructs() { var returnLabel = Expression.Label(typeof(long), "Return"); var streamVariable = Expression.Variable(typeof(Stream), "stream"); var memoryStreamVariable = Expression.Variable(typeof(MemoryStream), "memoryStream"); var streamAsMemoryStream = Expression.TypeAs(streamVariable, typeof(MemoryStream)); var memoryStreamAssignment = Expression.Assign(memoryStreamVariable, streamAsMemoryStream); var nullMemoryStream = Expression.Default(memoryStreamVariable.Type); var memoryStreamNotNull = Expression.NotEqual(memoryStreamVariable, nullMemoryStream); var msLengthVariable = Expression.Variable(typeof(long), "msLength"); var memoryStreamLength = Expression.Property(memoryStreamVariable, "Length"); var msLengthAssignment = Expression.Assign(msLengthVariable, memoryStreamLength); var msTryBlock = Expression.Block(new[] { msLengthVariable }, msLengthAssignment, msLengthVariable); var newNotSupportedException = Expression.New(typeof(NotSupportedException)); var throwMsException = Expression.Throw(newNotSupportedException, typeof(long)); var msCatchBlock = Expression.Catch(typeof(Exception), throwMsException); var memoryStreamTryCatch = Expression.TryCatch(msTryBlock, msCatchBlock); var returnMemoryStreamResult = Expression.Return(returnLabel, memoryStreamTryCatch); var ifMemoryStreamTryCatch = Expression.IfThen(memoryStreamNotNull, returnMemoryStreamResult); var fileStreamVariable = Expression.Variable(typeof(FileStream), "fileStream"); var streamAsFileStream = Expression.TypeAs(streamVariable, typeof(FileStream)); var fileStreamAssignment = Expression.Assign(fileStreamVariable, streamAsFileStream); var nullFileStream = Expression.Default(fileStreamVariable.Type); var fileStreamNotNull = Expression.NotEqual(fileStreamVariable, nullFileStream); var fsLengthVariable = Expression.Variable(typeof(long), "fsLength"); var fileStreamLength = Expression.Property(fileStreamVariable, "Length"); var fsLengthAssignment = Expression.Assign(fsLengthVariable, fileStreamLength); var fsTryBlock = Expression.Block(new[] { fsLengthVariable }, fsLengthAssignment, fsLengthVariable); var newIoException = Expression.New(typeof(IOException)); var throwIoException = Expression.Throw(newIoException, typeof(long)); var fsCatchBlock = Expression.Catch(typeof(Exception), throwIoException); var fileStreamTryCatch = Expression.TryCatch(fsTryBlock, fsCatchBlock); var returnFileStreamResult = Expression.Return(returnLabel, fileStreamTryCatch); var ifFileStreamTryCatch = Expression.IfThen(fileStreamNotNull, returnFileStreamResult); var overallBlock = Expression.Block( new[] { memoryStreamVariable, fileStreamVariable }, memoryStreamAssignment, ifMemoryStreamTryCatch, fileStreamAssignment, ifFileStreamTryCatch, Expression.Label(returnLabel, Expression.Constant(0L))); var overallCatchBlock = Expression.Catch(typeof(Exception), Expression.Constant(-1L)); var overallTryCatch = Expression.TryCatch(overallBlock, overallCatchBlock); const string EXPECTED = @" try { var memoryStream = stream as MemoryStream; if (memoryStream != null) { return { try { var msLength = memoryStream.Length; return msLength; } catch { throw new NotSupportedException(); } }; } var fileStream = stream as FileStream; if (fileStream != null) { return { try { var fsLength = fileStream.Length; return fsLength; } catch { throw new IOException(); } }; } return 0L; } catch { return -1L; }"; var translated = ToReadableString(overallTryCatch); translated.ShouldBe(EXPECTED.TrimStart()); }