Browse Source

FSharpTests: check-in IL instead of compiling F# source in the tests.

pull/671/head
lrieger 9 years ago
parent
commit
189e873461
  1. 12
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpPatternTests.cs
  2. 11
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Debug.cs
  3. 344
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Debug.il
  4. 5
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Release.cs
  5. 311
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Release.il
  6. 57
      ICSharpCode.Decompiler/Tests/FSharpPatterns/TestHelpers.cs
  7. 99
      ICSharpCode.Decompiler/Tests/FSharpPatterns/ToolLocator.cs
  8. 7
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

12
ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpPatternTests.cs

@ -5,9 +5,9 @@ using System.Linq; @@ -5,9 +5,9 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static ICSharpCode.Decompiler.Tests.FS2CS.TestRunner;
using static ICSharpCode.Decompiler.Tests.FSharpPatterns.TestHelpers;
namespace ICSharpCode.Decompiler.Tests.FS2CS
namespace ICSharpCode.Decompiler.Tests.FSharpPatterns
{
[TestFixture]
public class FSharpPatternTests
@ -15,17 +15,17 @@ namespace ICSharpCode.Decompiler.Tests.FS2CS @@ -15,17 +15,17 @@ namespace ICSharpCode.Decompiler.Tests.FS2CS
[Test]
public void FSharpUsingDecompilesToCSharpUsing_Debug()
{
var fsharpCode = FuzzyReadResource("FSharpUsing.fs");
var ilCode = FuzzyReadResource("FSharpUsing.fs.Debug.il");
var csharpCode = FuzzyReadResource("FSharpUsing.fs.Debug.cs");
Run(fsharpCode, csharpCode, false);
RunIL(ilCode, csharpCode);
}
[Test]
public void FSharpUsingDecompilesToCSharpUsing_Release()
{
var fsharpCode = FuzzyReadResource("FSharpUsing.fs");
var ilCode = FuzzyReadResource("FSharpUsing.fs.Release.il");
var csharpCode = FuzzyReadResource("FSharpUsing.fs.Release.cs");
Run(fsharpCode, csharpCode, true);
RunIL(ilCode, csharpCode);
}
}
}

11
ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Debug.cs

@ -1,9 +1,6 @@ @@ -1,9 +1,6 @@
using Microsoft.FSharp.Core;
using System;
using System;
using System.IO;
[assembly: FSharpInterfaceDataVersion(2, 0, 0)]
[CompilationMapping(SourceConstructFlags.Module)]
public static class FSharpUsingPatterns
{
public static void sample1()
@ -56,10 +53,10 @@ public static class FSharpUsingPatterns @@ -56,10 +53,10 @@ public static class FSharpUsingPatterns
}
int firstByte = num;
int num3;
using (FileStream fs2 = File.OpenRead("x.txt"))
using (FileStream fs = File.OpenRead("x.txt"))
{
int num2 = fs2.ReadByte();
num3 = fs2.ReadByte();
int num2 = fs.ReadByte();
num3 = fs.ReadByte();
}
int secondByte = num3;
Console.WriteLine("read: {0}, {1}", firstByte, secondByte);

344
ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Debug.il

@ -0,0 +1,344 @@ @@ -0,0 +1,344 @@
.class public auto ansi abstract sealed FSharpUsingPatterns
extends [mscorlib]System.Object
{
// Methods
.method public static
void sample1 () cil managed
{
// Method begins at RVA 0x2050
// Code size 53 (0x35)
.maxstack 4
.locals init (
[0] class [mscorlib]System.IO.FileStream fs,
[1] class [mscorlib]System.Object,
[2] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "x.txt"
IL_0006: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
IL_000b: stloc.0
.try
{
IL_000c: ldloc.0
IL_000d: ldc.i4.1
IL_000e: conv.u1
IL_000f: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
IL_0014: ldnull
IL_0015: stloc.1
IL_0016: leave.s IL_0032
} // end .try
finally
{
IL_0018: ldloc.0
IL_0019: isinst [mscorlib]System.IDisposable
IL_001e: stloc.2
IL_001f: ldloc.2
IL_0020: brfalse.s IL_0024
IL_0022: br.s IL_0026
IL_0024: br.s IL_002f
IL_0026: ldloc.2
IL_0027: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_002c: ldnull
IL_002d: pop
IL_002e: endfinally
IL_002f: ldnull
IL_0030: pop
IL_0031: endfinally
} // end handler
IL_0032: ldloc.1
IL_0033: pop
IL_0034: ret
} // end of method FSharpUsingPatterns::sample1
.method public static
void sample2 () cil managed
{
// Method begins at RVA 0x20a4
// Code size 73 (0x49)
.maxstack 4
.locals init (
[0] class [mscorlib]System.IO.FileStream fs,
[1] class [mscorlib]System.Object,
[2] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: ldstr "x.txt"
IL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
IL_0015: stloc.0
.try
{
IL_0016: ldloc.0
IL_0017: ldc.i4.2
IL_0018: conv.u1
IL_0019: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
IL_001e: ldstr "some text"
IL_0023: call void [mscorlib]System.Console::WriteLine(string)
IL_0028: ldnull
IL_0029: stloc.1
IL_002a: leave.s IL_0046
} // end .try
finally
{
IL_002c: ldloc.0
IL_002d: isinst [mscorlib]System.IDisposable
IL_0032: stloc.2
IL_0033: ldloc.2
IL_0034: brfalse.s IL_0038
IL_0036: br.s IL_003a
IL_0038: br.s IL_0043
IL_003a: ldloc.2
IL_003b: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0040: ldnull
IL_0041: pop
IL_0042: endfinally
IL_0043: ldnull
IL_0044: pop
IL_0045: endfinally
} // end handler
IL_0046: ldloc.1
IL_0047: pop
IL_0048: ret
} // end of method FSharpUsingPatterns::sample2
.method public static
void sample3 () cil managed
{
// Method begins at RVA 0x210c
// Code size 73 (0x49)
.maxstack 4
.locals init (
[0] class [mscorlib]System.IO.FileStream fs,
[1] class [mscorlib]System.Object,
[2] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: ldstr "x.txt"
IL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
IL_0015: stloc.0
.try
{
IL_0016: ldloc.0
IL_0017: ldc.i4.3
IL_0018: conv.u1
IL_0019: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
IL_001e: ldnull
IL_001f: stloc.1
IL_0020: leave.s IL_003c
} // end .try
finally
{
IL_0022: ldloc.0
IL_0023: isinst [mscorlib]System.IDisposable
IL_0028: stloc.2
IL_0029: ldloc.2
IL_002a: brfalse.s IL_002e
IL_002c: br.s IL_0030
IL_002e: br.s IL_0039
IL_0030: ldloc.2
IL_0031: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0036: ldnull
IL_0037: pop
IL_0038: endfinally
IL_0039: ldnull
IL_003a: pop
IL_003b: endfinally
} // end handler
IL_003c: ldloc.1
IL_003d: pop
IL_003e: ldstr "some text"
IL_0043: call void [mscorlib]System.Console::WriteLine(string)
IL_0048: ret
} // end of method FSharpUsingPatterns::sample3
.method public static
void sample4 () cil managed
{
// Method begins at RVA 0x2174
// Code size 89 (0x59)
.maxstack 4
.locals init (
[0] int32 firstByte,
[1] class [mscorlib]System.IO.FileStream fs,
[2] int32,
[3] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ldstr "x.txt"
IL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)
IL_0016: stloc.1
.try
{
IL_0017: ldloc.1
IL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_001d: stloc.2
IL_001e: leave.s IL_003a
} // end .try
finally
{
IL_0020: ldloc.1
IL_0021: isinst [mscorlib]System.IDisposable
IL_0026: stloc.3
IL_0027: ldloc.3
IL_0028: brfalse.s IL_002c
IL_002a: br.s IL_002e
IL_002c: br.s IL_0037
IL_002e: ldloc.3
IL_002f: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0034: ldnull
IL_0035: pop
IL_0036: endfinally
IL_0037: ldnull
IL_0038: pop
IL_0039: endfinally
} // end handler
IL_003a: ldloc.2
IL_003b: stloc.0
IL_003c: ldstr "read:"
IL_0041: ldloca.s firstByte
IL_0043: constrained. [mscorlib]System.Int32
IL_0049: callvirt instance string [mscorlib]System.Object::ToString()
IL_004e: call string [mscorlib]System.String::Concat(string, string)
IL_0053: call void [mscorlib]System.Console::WriteLine(string)
IL_0058: ret
} // end of method FSharpUsingPatterns::sample4
.method public static
void sample5 () cil managed
{
// Method begins at RVA 0x21ec
// Code size 155 (0x9b)
.maxstack 5
.locals init (
[0] int32 firstByte,
[1] class [mscorlib]System.IO.FileStream fs,
[2] int32,
[3] class [mscorlib]System.IDisposable,
[4] int32 secondByte,
[5] class [mscorlib]System.IO.FileStream fs,
[6] int32,
[7] int32,
[8] int32,
[9] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ldstr "x.txt"
IL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)
IL_0016: stloc.1
.try
{
IL_0017: ldloc.1
IL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_001d: stloc.2
IL_001e: leave.s IL_003a
} // end .try
finally
{
IL_0020: ldloc.1
IL_0021: isinst [mscorlib]System.IDisposable
IL_0026: stloc.3
IL_0027: ldloc.3
IL_0028: brfalse.s IL_002c
IL_002a: br.s IL_002e
IL_002c: br.s IL_0037
IL_002e: ldloc.3
IL_002f: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0034: ldnull
IL_0035: pop
IL_0036: endfinally
IL_0037: ldnull
IL_0038: pop
IL_0039: endfinally
} // end handler
IL_003a: ldloc.2
IL_003b: stloc.0
IL_003c: nop
IL_003d: ldstr "x.txt"
IL_0042: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)
IL_0047: stloc.s fs
.try
{
IL_0049: ldloc.s fs
IL_004b: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_0050: stloc.s 7
IL_0052: ldloc.s 7
IL_0054: stloc.s 8
IL_0056: ldloc.s fs
IL_0058: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_005d: stloc.s 6
IL_005f: leave.s IL_007f
} // end .try
finally
{
IL_0061: ldloc.s fs
IL_0063: isinst [mscorlib]System.IDisposable
IL_0068: stloc.s 9
IL_006a: ldloc.s 9
IL_006c: brfalse.s IL_0070
IL_006e: br.s IL_0072
IL_0070: br.s IL_007c
IL_0072: ldloc.s 9
IL_0074: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0079: ldnull
IL_007a: pop
IL_007b: endfinally
IL_007c: ldnull
IL_007d: pop
IL_007e: endfinally
} // end handler
IL_007f: ldloc.s 6
IL_0081: stloc.s secondByte
IL_0083: ldstr "read: {0}, {1}"
IL_0088: ldloc.0
IL_0089: box [mscorlib]System.Int32
IL_008e: ldloc.s secondByte
IL_0090: box [mscorlib]System.Int32
IL_0095: call void [mscorlib]System.Console::WriteLine(string, object, object)
IL_009a: ret
} // end of method FSharpUsingPatterns::sample5
} // end of class FSharpUsingPatterns

5
ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Release.cs

@ -1,9 +1,6 @@ @@ -1,9 +1,6 @@
using Microsoft.FSharp.Core;
using System;
using System;
using System.IO;
[assembly: FSharpInterfaceDataVersion(2, 0, 0)]
[CompilationMapping(SourceConstructFlags.Module)]
public static class FSharpUsingPatterns
{
public static void sample1()

311
ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Release.il

@ -0,0 +1,311 @@ @@ -0,0 +1,311 @@
.class public auto ansi abstract sealed FSharpUsingPatterns
extends [mscorlib]System.Object
{
// Methods
.method public static
void sample1 () cil managed
{
// Method begins at RVA 0x2050
// Code size 48 (0x30)
.maxstack 4
.locals init (
[0] class [mscorlib]System.IO.FileStream fs,
[1] class [mscorlib]System.Object,
[2] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "x.txt"
IL_0006: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
IL_000b: stloc.0
.try
{
IL_000c: ldloc.0
IL_000d: ldc.i4.1
IL_000e: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
IL_0013: ldnull
IL_0014: stloc.1
IL_0015: leave.s IL_002d
} // end .try
finally
{
IL_0017: ldloc.0
IL_0018: isinst [mscorlib]System.IDisposable
IL_001d: stloc.2
IL_001e: ldloc.2
IL_001f: brfalse.s IL_002a
IL_0021: ldloc.2
IL_0022: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0027: ldnull
IL_0028: pop
IL_0029: endfinally
IL_002a: ldnull
IL_002b: pop
IL_002c: endfinally
} // end handler
IL_002d: ldloc.1
IL_002e: pop
IL_002f: ret
} // end of method FSharpUsingPatterns::sample1
.method public static
void sample2 () cil managed
{
// Method begins at RVA 0x209c
// Code size 68 (0x44)
.maxstack 4
.locals init (
[0] class [mscorlib]System.IO.FileStream fs,
[1] class [mscorlib]System.Object,
[2] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: ldstr "x.txt"
IL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
IL_0015: stloc.0
.try
{
IL_0016: ldloc.0
IL_0017: ldc.i4.2
IL_0018: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
IL_001d: ldstr "some text"
IL_0022: call void [mscorlib]System.Console::WriteLine(string)
IL_0027: ldnull
IL_0028: stloc.1
IL_0029: leave.s IL_0041
} // end .try
finally
{
IL_002b: ldloc.0
IL_002c: isinst [mscorlib]System.IDisposable
IL_0031: stloc.2
IL_0032: ldloc.2
IL_0033: brfalse.s IL_003e
IL_0035: ldloc.2
IL_0036: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_003b: ldnull
IL_003c: pop
IL_003d: endfinally
IL_003e: ldnull
IL_003f: pop
IL_0040: endfinally
} // end handler
IL_0041: ldloc.1
IL_0042: pop
IL_0043: ret
} // end of method FSharpUsingPatterns::sample2
.method public static
void sample3 () cil managed
{
// Method begins at RVA 0x20fc
// Code size 68 (0x44)
.maxstack 4
.locals init (
[0] class [mscorlib]System.IO.FileStream fs,
[1] class [mscorlib]System.Object,
[2] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: ldstr "x.txt"
IL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
IL_0015: stloc.0
.try
{
IL_0016: ldloc.0
IL_0017: ldc.i4.3
IL_0018: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
IL_001d: ldnull
IL_001e: stloc.1
IL_001f: leave.s IL_0037
} // end .try
finally
{
IL_0021: ldloc.0
IL_0022: isinst [mscorlib]System.IDisposable
IL_0027: stloc.2
IL_0028: ldloc.2
IL_0029: brfalse.s IL_0034
IL_002b: ldloc.2
IL_002c: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0031: ldnull
IL_0032: pop
IL_0033: endfinally
IL_0034: ldnull
IL_0035: pop
IL_0036: endfinally
} // end handler
IL_0037: ldloc.1
IL_0038: pop
IL_0039: ldstr "some text"
IL_003e: call void [mscorlib]System.Console::WriteLine(string)
IL_0043: ret
} // end of method FSharpUsingPatterns::sample3
.method public static
void sample4 () cil managed
{
// Method begins at RVA 0x215c
// Code size 85 (0x55)
.maxstack 4
.locals init (
[0] int32 firstByte,
[1] class [mscorlib]System.IO.FileStream fs,
[2] int32,
[3] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ldstr "x.txt"
IL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)
IL_0016: stloc.1
.try
{
IL_0017: ldloc.1
IL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_001d: stloc.2
IL_001e: leave.s IL_0036
} // end .try
finally
{
IL_0020: ldloc.1
IL_0021: isinst [mscorlib]System.IDisposable
IL_0026: stloc.3
IL_0027: ldloc.3
IL_0028: brfalse.s IL_0033
IL_002a: ldloc.3
IL_002b: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0030: ldnull
IL_0031: pop
IL_0032: endfinally
IL_0033: ldnull
IL_0034: pop
IL_0035: endfinally
} // end handler
IL_0036: ldloc.2
IL_0037: stloc.0
IL_0038: ldstr "read:"
IL_003d: ldloca.s firstByte
IL_003f: constrained. [mscorlib]System.Int32
IL_0045: callvirt instance string [mscorlib]System.Object::ToString()
IL_004a: call string [mscorlib]System.String::Concat(string, string)
IL_004f: call void [mscorlib]System.Console::WriteLine(string)
IL_0054: ret
} // end of method FSharpUsingPatterns::sample4
.method public static
void sample5 () cil managed
{
// Method begins at RVA 0x21d0
// Code size 134 (0x86)
.maxstack 5
.locals init (
[0] int32 firstByte,
[1] class [mscorlib]System.IO.FileStream fs,
[2] int32 secondByte,
[3] class [mscorlib]System.IDisposable,
[4] int32,
[5] int32
)
IL_0000: nop
IL_0001: ldstr "some text"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ldstr "x.txt"
IL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)
IL_0016: stloc.1
.try
{
IL_0017: ldloc.1
IL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_001d: stloc.2
IL_001e: leave.s IL_0036
} // end .try
finally
{
IL_0020: ldloc.1
IL_0021: isinst [mscorlib]System.IDisposable
IL_0026: stloc.3
IL_0027: ldloc.3
IL_0028: brfalse.s IL_0033
IL_002a: ldloc.3
IL_002b: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0030: ldnull
IL_0031: pop
IL_0032: endfinally
IL_0033: ldnull
IL_0034: pop
IL_0035: endfinally
} // end handler
IL_0036: ldloc.2
IL_0037: stloc.0
IL_0038: nop
IL_0039: ldstr "x.txt"
IL_003e: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)
IL_0043: stloc.1
.try
{
IL_0044: ldloc.1
IL_0045: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_004a: stloc.s 5
IL_004c: ldloc.1
IL_004d: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()
IL_0052: stloc.s 4
IL_0054: leave.s IL_006c
} // end .try
finally
{
IL_0056: ldloc.1
IL_0057: isinst [mscorlib]System.IDisposable
IL_005c: stloc.3
IL_005d: ldloc.3
IL_005e: brfalse.s IL_0069
IL_0060: ldloc.3
IL_0061: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0066: ldnull
IL_0067: pop
IL_0068: endfinally
IL_0069: ldnull
IL_006a: pop
IL_006b: endfinally
} // end handler
IL_006c: ldloc.s 4
IL_006e: stloc.2
IL_006f: ldstr "read: {0}, {1}"
IL_0074: ldloc.0
IL_0075: box [mscorlib]System.Int32
IL_007a: ldloc.2
IL_007b: box [mscorlib]System.Int32
IL_0080: call void [mscorlib]System.Console::WriteLine(string, object, object)
IL_0085: ret
} // end of method FSharpUsingPatterns::sample5
} // end of class FSharpUsingPatterns

57
ICSharpCode.Decompiler/Tests/FSharpPatterns/TestRunner.cs → ICSharpCode.Decompiler/Tests/FSharpPatterns/TestHelpers.cs

@ -5,15 +5,16 @@ using Mono.Cecil; @@ -5,15 +5,16 @@ using Mono.Cecil;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.Tests.FS2CS
namespace ICSharpCode.Decompiler.Tests.FSharpPatterns
{
public class TestRunner
public class TestHelpers
{
public static string FuzzyReadResource(string resourceName)
{
@ -32,7 +33,7 @@ namespace ICSharpCode.Decompiler.Tests.FS2CS @@ -32,7 +33,7 @@ namespace ICSharpCode.Decompiler.Tests.FS2CS
File.WriteAllText(sourceFile, source);
var asmFile = Path.ChangeExtension(sourceFile, ".dll");
var sscs = new Microsoft.FSharp.Compiler.SimpleSourceCodeServices.SimpleSourceCodeServices();
var result = sscs.Compile(new[] { "fsc.exe", "--debug:full", $"--optimize{(optimize?"+" :"-")}", "--target:library", "-o", asmFile, sourceFile });
var result = sscs.Compile(new[] { "fsc.exe", "--debug:full", $"--optimize{(optimize ? "+" : "-")}", "--target:library", "-o", asmFile, sourceFile });
File.Delete(sourceFile);
Assert.AreEqual(0, result.Item1.Length);
Assert.AreEqual(0, result.Item2);
@ -40,22 +41,58 @@ namespace ICSharpCode.Decompiler.Tests.FS2CS @@ -40,22 +41,58 @@ namespace ICSharpCode.Decompiler.Tests.FS2CS
return asmFile;
}
public static void Run(string fsharpCode, string expectedCSharpCode, bool optimize)
static Lazy<string> ilasm = new Lazy<string>(() => ToolLocator.FindTool("ilasm.exe"));
static Lazy<string> ildasm = new Lazy<string>(() => ToolLocator.FindTool("ildasm.exe"));
public static string CompileIL(string source)
{
if (ilasm.Value == null)
Assert.NotNull(ilasm.Value, "Could not find ILASM.exe");
var tmp = Path.GetTempFileName();
File.Delete(tmp);
var sourceFile = Path.ChangeExtension(tmp, ".il");
File.WriteAllText(sourceFile, source);
var asmFile = Path.ChangeExtension(sourceFile, ".dll");
var args = $"{sourceFile} /dll /debug /output:{asmFile}";
using (var proc = Process.Start(new ProcessStartInfo(ilasm.Value, args) { UseShellExecute = false, }))
{
proc.WaitForExit();
Assert.AreEqual(0, proc.ExitCode);
}
File.Delete(sourceFile);
Assert.True(File.Exists(asmFile), "Assembly File does not exist");
return asmFile;
}
public static void RunIL(string ilCode, string expectedCSharpCode)
{
var asmFilePath = CompileIL(ilCode);
CompareAssemblyAgainstCSharp(expectedCSharpCode, asmFilePath);
}
public static void RunFSharp(string fsharpCode, string expectedCSharpCode, bool optimize)
{
var asmFilePath = CompileFsToAssembly(fsharpCode, optimize);
var assembly = AssemblyDefinition.ReadAssembly(asmFilePath);
CompareAssemblyAgainstCSharp(expectedCSharpCode, asmFilePath);
}
private static void CompareAssemblyAgainstCSharp(string expectedCSharpCode, string asmFilePath)
{
var module = ModuleDefinition.ReadModule(asmFilePath);
try
{
assembly.MainModule.ReadSymbols();
AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule));
decompiler.AddAssembly(assembly);
try { module.ReadSymbols(); } catch { }
AstBuilder decompiler = new AstBuilder(new DecompilerContext(module));
decompiler.AddAssembly(module);
new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
StringWriter output = new StringWriter();
// the F# assembly contains a namespace `<StartupCode$tmp6D55>` where the part after tmp is randomly generated.
// remove this from the ast to simplify the diff
var startupCodeNode = decompiler.SyntaxTree.Children.Single(d => (d as NamespaceDeclaration)?.Name?.StartsWith("<StartupCode$") ?? false);
startupCodeNode.Remove();
var startupCodeNode = decompiler.SyntaxTree.Children.SingleOrDefault(d => (d as NamespaceDeclaration)?.Name?.StartsWith("<StartupCode$") ?? false);
startupCodeNode?.Remove();
decompiler.GenerateCode(new PlainTextOutput(output));
var fullCSharpCode = output.ToString();

99
ICSharpCode.Decompiler/Tests/FSharpPatterns/ToolLocator.cs

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.Tests.FSharpPatterns
{
public class ToolLocator
{
public static string FindTool(string fileName)
{
var allPaths = FindPathForDotNetFramework().Concat(FindPathForWindowsSdk());
return allPaths.Select(dir => Path.Combine(dir, fileName)).FirstOrDefault(File.Exists);
}
private static IEnumerable<string> FindPathForWindowsSdk()
{
string[] windowsSdkPaths = new[]
{
@"Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\",
@"Microsoft SDKs\Windows\v8.0A\bin\",
@"Microsoft SDKs\Windows\v8.0\bin\NETFX 4.0 Tools\",
@"Microsoft SDKs\Windows\v8.0\bin\",
@"Microsoft SDKs\Windows\v7.1A\bin\NETFX 4.0 Tools\",
@"Microsoft SDKs\Windows\v7.1A\bin\",
@"Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\",
@"Microsoft SDKs\Windows\v7.0A\bin\",
@"Microsoft SDKs\Windows\v6.1A\bin\",
@"Microsoft SDKs\Windows\v6.0A\bin\",
@"Microsoft SDKs\Windows\v6.0\bin\",
@"Microsoft.NET\FrameworkSDK\bin"
};
foreach (var possiblePath in windowsSdkPaths)
{
string fullPath = string.Empty;
// Check alternate program file paths as well as 64-bit versions.
if (Environment.Is64BitProcess)
{
fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), possiblePath, "x64");
if (Directory.Exists(fullPath))
{
yield return fullPath;
}
fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), possiblePath, "x64");
if (Directory.Exists(fullPath))
{
yield return fullPath;
}
}
fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), possiblePath);
if (Directory.Exists(fullPath))
{
yield return fullPath;
}
fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), possiblePath);
if (Directory.Exists(fullPath))
{
yield return fullPath;
}
}
}
private static IEnumerable<string> FindPathForDotNetFramework()
{
string[] frameworkPaths = new[]
{
@"Microsoft.NET\Framework\v4.0.30319",
@"Microsoft.NET\Framework\v2.0.50727"
};
foreach (var possiblePath in frameworkPaths)
{
string fullPath = string.Empty;
if (Environment.Is64BitProcess)
{
fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), possiblePath.Replace(@"\Framework\", @"\Framework64\"));
if (Directory.Exists(fullPath))
{
yield return fullPath;
}
}
fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), possiblePath);
if (Directory.Exists(fullPath))
{
yield return fullPath;
}
}
}
}
}

7
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -89,10 +89,12 @@ @@ -89,10 +89,12 @@
<Compile Include="ControlFlow.cs" />
<Compile Include="DoubleConstants.cs" />
<Compile Include="ExpressionTrees.cs" />
<EmbeddedResource Include="FSharpPatterns\FSharpUsing.fs.Debug.il" />
<None Include="IL\SequenceOfNestedIfs.Output.cs" />
<Compile Include="FSharpPatterns\FSharpPatternTests.cs" />
<EmbeddedResource Include="FSharpPatterns\FSharpUsing.fs.Debug.cs" />
<Compile Include="FSharpPatterns\TestRunner.cs" />
<Compile Include="FSharpPatterns\TestHelpers.cs" />
<Compile Include="FSharpPatterns\ToolLocator.cs" />
<Compile Include="IL\ILTests.cs" />
<Compile Include="LiftedOperators.cs" />
<Compile Include="CustomShortCircuitOperators.cs" />
@ -168,5 +170,8 @@ @@ -168,5 +170,8 @@
<ItemGroup>
<EmbeddedResource Include="FSharpPatterns\FSharpUsing.fs.Release.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="FSharpPatterns\FSharpUsing.fs.Release.il" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>
Loading…
Cancel
Save