|
2 | 2 | { |
3 | 3 | using System; |
4 | 4 | using System.Collections.Generic; |
| 5 | + using System.IO; |
5 | 6 | using System.Linq; |
6 | 7 | using System.Linq.Expressions; |
7 | 8 | using System.Reflection; |
@@ -350,6 +351,106 @@ public void ShouldNotVarAssignAVariableAssignedInATryButUsedInACatch() |
350 | 351 | Assert.AreEqual(EXPECTED.TrimStart(), translated); |
351 | 352 | } |
352 | 353 |
|
| 354 | + [TestMethod] |
| 355 | + public void ShouldVarAssignAVariableUsedInNestedConstructs() |
| 356 | + { |
| 357 | + var returnLabel = Expression.Label(typeof(long), "Return"); |
| 358 | + var streamVariable = Expression.Variable(typeof(Stream), "stream"); |
| 359 | + |
| 360 | + var memoryStreamVariable = Expression.Variable(typeof(MemoryStream), "memoryStream"); |
| 361 | + var streamAsMemoryStream = Expression.TypeAs(streamVariable, typeof(MemoryStream)); |
| 362 | + var memoryStreamAssignment = Expression.Assign(memoryStreamVariable, streamAsMemoryStream); |
| 363 | + var nullMemoryStream = Expression.Default(memoryStreamVariable.Type); |
| 364 | + var memoryStreamNotNull = Expression.NotEqual(memoryStreamVariable, nullMemoryStream); |
| 365 | + var msLengthVariable = Expression.Variable(typeof(long), "msLength"); |
| 366 | + var memoryStreamLength = Expression.Property(memoryStreamVariable, "Length"); |
| 367 | + var msLengthAssignment = Expression.Assign(msLengthVariable, memoryStreamLength); |
| 368 | + |
| 369 | + var msTryBlock = Expression.Block(new[] { msLengthVariable }, msLengthAssignment, msLengthVariable); |
| 370 | + var newNotSupportedException = Expression.New(typeof(NotSupportedException)); |
| 371 | + var throwMsException = Expression.Throw(newNotSupportedException, typeof(long)); |
| 372 | + var msCatchBlock = Expression.Catch(typeof(Exception), throwMsException); |
| 373 | + var memoryStreamTryCatch = Expression.TryCatch(msTryBlock, msCatchBlock); |
| 374 | + var returnMemoryStreamResult = Expression.Return(returnLabel, memoryStreamTryCatch); |
| 375 | + var ifMemoryStreamTryCatch = Expression.IfThen(memoryStreamNotNull, returnMemoryStreamResult); |
| 376 | + |
| 377 | + var fileStreamVariable = Expression.Variable(typeof(FileStream), "fileStream"); |
| 378 | + var streamAsFileStream = Expression.TypeAs(streamVariable, typeof(FileStream)); |
| 379 | + var fileStreamAssignment = Expression.Assign(fileStreamVariable, streamAsFileStream); |
| 380 | + var nullFileStream = Expression.Default(fileStreamVariable.Type); |
| 381 | + var fileStreamNotNull = Expression.NotEqual(fileStreamVariable, nullFileStream); |
| 382 | + var fsLengthVariable = Expression.Variable(typeof(long), "fsLength"); |
| 383 | + var fileStreamLength = Expression.Property(fileStreamVariable, "Length"); |
| 384 | + var fsLengthAssignment = Expression.Assign(fsLengthVariable, fileStreamLength); |
| 385 | + |
| 386 | + var fsTryBlock = Expression.Block(new[] { fsLengthVariable }, fsLengthAssignment, fsLengthVariable); |
| 387 | + var newIoException = Expression.New(typeof(IOException)); |
| 388 | + var throwIoException = Expression.Throw(newIoException, typeof(long)); |
| 389 | + var fsCatchBlock = Expression.Catch(typeof(Exception), throwIoException); |
| 390 | + var fileStreamTryCatch = Expression.TryCatch(fsTryBlock, fsCatchBlock); |
| 391 | + var returnFileStreamResult = Expression.Return(returnLabel, fileStreamTryCatch); |
| 392 | + var ifFileStreamTryCatch = Expression.IfThen(fileStreamNotNull, returnFileStreamResult); |
| 393 | + |
| 394 | + var overallBlock = Expression.Block( |
| 395 | + new[] { memoryStreamVariable, fileStreamVariable }, |
| 396 | + memoryStreamAssignment, |
| 397 | + ifMemoryStreamTryCatch, |
| 398 | + fileStreamAssignment, |
| 399 | + ifFileStreamTryCatch, |
| 400 | + Expression.Label(returnLabel, Expression.Constant(0L))); |
| 401 | + |
| 402 | + var overallCatchBlock = Expression.Catch(typeof(Exception), Expression.Constant(-1L)); |
| 403 | + var overallTryCatch = Expression.TryCatch(overallBlock, overallCatchBlock); |
| 404 | + |
| 405 | + const string EXPECTED = @" |
| 406 | +try |
| 407 | +{ |
| 408 | + var memoryStream = stream as MemoryStream; |
| 409 | + if (memoryStream != null) |
| 410 | + { |
| 411 | + return |
| 412 | + { |
| 413 | + try |
| 414 | + { |
| 415 | + var msLength = memoryStream.Length; |
| 416 | + return msLength; |
| 417 | + } |
| 418 | + catch |
| 419 | + { |
| 420 | + throw new NotSupportedException(); |
| 421 | + } |
| 422 | + } |
| 423 | + } |
| 424 | +
|
| 425 | + var fileStream = stream as FileStream; |
| 426 | + if (fileStream != null) |
| 427 | + { |
| 428 | + return |
| 429 | + { |
| 430 | + try |
| 431 | + { |
| 432 | + var fsLength = fileStream.Length; |
| 433 | + return fsLength; |
| 434 | + } |
| 435 | + catch |
| 436 | + { |
| 437 | + throw new IOException(); |
| 438 | + } |
| 439 | + } |
| 440 | + } |
| 441 | +
|
| 442 | + return 0L; |
| 443 | +} |
| 444 | +catch |
| 445 | +{ |
| 446 | + return -1L; |
| 447 | +}"; |
| 448 | + |
| 449 | + var translated = overallTryCatch.ToReadableString(); |
| 450 | + |
| 451 | + Assert.AreEqual(EXPECTED.TrimStart(), translated); |
| 452 | + } |
| 453 | + |
353 | 454 | [TestMethod] |
354 | 455 | public void ShouldTranslateAnExtensionExpressionType() |
355 | 456 | { |
|
0 commit comments