public void ShouldIncludeAReturnKeywordForANewListInitStatement() { var exception = Expression.Variable(typeof(Exception), "ex"); var listConstructor = typeof(List <int>).GetConstructor(new[] { typeof(int) }); var one = Expression.Constant(1); // ReSharper disable once AssignNullToNotNullAttribute var newList = Expression.New(listConstructor, one); var newListInit = Expression.ListInit(newList, one); var rethrow = Expression.Rethrow(newListInit.Type); var globalCatchAndRethrow = Expression.Catch(exception, rethrow); var tryCatch = Expression.TryCatch(newListInit, globalCatchAndRethrow); var tryCatchBlock = Expression.Block(tryCatch); var translated = ToReadableString(tryCatchBlock); const string EXPECTED = @" try { return new List<int>(1) { 1 }; } catch { throw; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldIncludeAReturnKeywordForANewArrayInitStatement() { var exception = Expression.Variable(typeof(Exception), "ex"); var zero = Expression.Constant(0, typeof(int)); var newArray = Expression.NewArrayInit(typeof(int), zero); var rethrow = Expression.Rethrow(newArray.Type); var globalCatchAndRethrow = Expression.Catch(exception, rethrow); var tryCatch = Expression.TryCatch(newArray, globalCatchAndRethrow); var tryCatchBlock = Expression.Block(tryCatch); var translated = ToReadableString(tryCatchBlock); const string EXPECTED = @" try { return new[] { 0 }; } catch { throw; }"; 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 ShouldIncludeAReturnKeywordForAnObjectInitStatement() { var exception = Expression.Variable(typeof(Exception), "ex"); var newAddress = Expression.New(typeof(Address).GetConstructors().First()); var line1Property = newAddress.Type.GetMember("Line1").First(); var line1Value = Expression.Constant("Over here"); var line1Init = Expression.Bind(line1Property, line1Value); var addressInit = Expression.MemberInit(newAddress, line1Init); var rethrow = Expression.Rethrow(newAddress.Type); var globalCatchAndRethrow = Expression.Catch(exception, rethrow); var tryCatch = Expression.TryCatch(addressInit, globalCatchAndRethrow); var tryCatchBlock = Expression.Block(tryCatch); var translated = ToReadableString(tryCatchBlock); const string EXPECTED = @" try { return new WhenTranslatingBlocks.Address { Line1 = ""Over here"" }; } catch { throw; }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateATryWithATopLevelCatchWithAWrappedExceptionThrow() { var exception = Expression.Variable(typeof(Exception), "ex"); var writeBoom = CreateLambda(() => Console.Write("BOOM?")); var wrappedException = Expression.New( // ReSharper disable once AssignNullToNotNullAttribute typeof(InvalidOperationException).GetConstructor(new[] { typeof(string), typeof(Exception) }), Expression.Constant("Wrapped!"), exception); var throwWrapped = Expression.Throw(wrappedException); var globalCatch = Expression.Catch(exception, throwWrapped); var tryCatch = Expression.TryCatch(writeBoom.Body, globalCatch); var translated = ToReadableString(tryCatch); const string EXPECTED = @" try { Console.Write(""BOOM?""); } catch (Exception ex) { throw new InvalidOperationException(""Wrapped!"", ex); }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateATryWithATopLevelCatchWithExceptionUseAndRethrow() { var writeException = CreateLambda((Exception ex) => Console.Write(ex)); var exception = writeException.Parameters.First(); var writeHello = CreateLambda(() => Console.Write("Hello")); var rethrow = Expression.Throw(exception); var writeExceptionAndRethrow = Expression.Block(writeException.Body, rethrow); var globalCatch = Expression.Catch(exception, writeExceptionAndRethrow); var tryCatch = Expression.TryCatch(writeHello.Body, globalCatch); var translated = ToReadableString(tryCatch); const string EXPECTED = @" try { Console.Write(""Hello""); } catch (Exception ex) { Console.Write(ex); throw; }"; 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 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 ShouldTranslateATryCatch() { var writeHello = CreateLambda(() => Console.Write("Hello")); var exception = Expression.Variable(typeof(TimeoutException), "timeoutEx"); var timeoutCatch = Expression.Catch(exception, Expression.Empty()); var tryCatch = Expression.TryCatch(writeHello.Body, timeoutCatch); var translated = ToReadableString(tryCatch); const string EXPECTED = @" try { Console.Write(""Hello""); } catch (TimeoutException) { }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateATryWithAFilteredCatch() { var writeHello = CreateLambda(() => Console.Write("Hello")); var filter = CreateLambda((TimeoutException timeoutEx) => timeoutEx.Data != null); var exception = filter.Parameters.First(); var timeoutCatch = Expression.Catch(exception, Expression.Empty(), filter.Body); var tryCatch = Expression.TryCatch(writeHello.Body, timeoutCatch); var translated = ToReadableString(tryCatch); const string EXPECTED = @" try { Console.Write(""Hello""); } catch (TimeoutException timeoutEx) when (timeoutEx.Data != null) { }"; translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateMultilineConstructorParameters() { var consoleRead = CreateLambda(() => Console.Read()); var catchAll = Expression.Catch(typeof(Exception), Expression.Default(typeof(int))); var tryReadInt = Expression.TryCatch(consoleRead.Body, catchAll); var createStringBuilder = Expression.New( typeof(StringBuilder).GetPublicInstanceConstructor(typeof(int), typeof(int)), tryReadInt, tryReadInt); const string EXPECTED = @" new StringBuilder( { try { return Console.Read(); } catch { return default(int); } }, { try { return Console.Read(); } catch { return default(int); } })"; var translated = ToReadableString(createStringBuilder); translated.ShouldBe(EXPECTED.TrimStart()); }
public void ShouldTranslateATryWithATopLevelCatchWithAnExplicitExceptionRethrow() { var exception = Expression.Variable(typeof(Exception), "ex"); var writeHello = CreateLambda(() => Console.Write("Hello")); var rethrow = Expression.Throw(exception); var globalCatchAndRethrow = Expression.Catch(exception, rethrow); var tryCatch = Expression.TryCatch(writeHello.Body, globalCatchAndRethrow); var translated = ToReadableString(tryCatch); const string EXPECTED = @" try { Console.Write(""Hello""); } catch { throw; }"; 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 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 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()); }