mirror of https://github.com/icsharpcode/ILSpy.git
9 changed files with 331 additions and 3 deletions
@ -0,0 +1,31 @@ |
|||||||
|
using NUnit.Framework; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using static ICSharpCode.Decompiler.Tests.FS2CS.TestRunner; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.FS2CS |
||||||
|
{ |
||||||
|
[TestFixture] |
||||||
|
public class FSharpPatternTests |
||||||
|
{ |
||||||
|
[Test] |
||||||
|
public void FSharpUsingDecompilesToCSharpUsing_Debug() |
||||||
|
{ |
||||||
|
var fsharpCode = FuzzyReadResource("FSharpUsing.fs"); |
||||||
|
var csharpCode = FuzzyReadResource("FSharpUsing.fs.Debug.cs"); |
||||||
|
Run(fsharpCode, csharpCode, false); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void FSharpUsingDecompilesToCSharpUsing_Release() |
||||||
|
{ |
||||||
|
var fsharpCode = FuzzyReadResource("FSharpUsing.fs"); |
||||||
|
var csharpCode = FuzzyReadResource("FSharpUsing.fs.Release.cs"); |
||||||
|
Run(fsharpCode, csharpCode, true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
module FSharpUsingPatterns |
||||||
|
|
||||||
|
open System |
||||||
|
open System.IO |
||||||
|
|
||||||
|
let sample1() = |
||||||
|
use fs = File.Create("x.txt") |
||||||
|
fs.WriteByte(byte 1) |
||||||
|
|
||||||
|
let sample2() = |
||||||
|
Console.WriteLine("some text") |
||||||
|
use fs = File.Create("x.txt") |
||||||
|
fs.WriteByte(byte 2) |
||||||
|
Console.WriteLine("some text") |
||||||
|
|
||||||
|
let sample3() = |
||||||
|
Console.WriteLine("some text") |
||||||
|
do use fs = File.Create("x.txt") |
||||||
|
fs.WriteByte(byte 3) |
||||||
|
Console.WriteLine("some text") |
||||||
|
|
||||||
|
let sample4() = |
||||||
|
Console.WriteLine("some text") |
||||||
|
let firstByte = |
||||||
|
use fs = File.OpenRead("x.txt") |
||||||
|
fs.ReadByte() |
||||||
|
Console.WriteLine("read:" + firstByte.ToString()) |
||||||
|
|
||||||
|
let sample5() = |
||||||
|
Console.WriteLine("some text") |
||||||
|
let firstByte = |
||||||
|
use fs = File.OpenRead("x.txt") |
||||||
|
fs.ReadByte() |
||||||
|
let secondByte = |
||||||
|
use fs = File.OpenRead("x.txt") |
||||||
|
fs.ReadByte() |> ignore |
||||||
|
fs.ReadByte() |
||||||
|
Console.WriteLine("read: {0}, {1}", firstByte, secondByte) |
@ -0,0 +1,67 @@ |
|||||||
|
using Microsoft.FSharp.Core; |
||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
[assembly: FSharpInterfaceDataVersion(2, 0, 0)] |
||||||
|
[CompilationMapping(SourceConstructFlags.Module)] |
||||||
|
public static class FSharpUsingPatterns |
||||||
|
{ |
||||||
|
public static void sample1() |
||||||
|
{ |
||||||
|
using (FileStream fs = File.Create("x.txt")) |
||||||
|
{ |
||||||
|
fs.WriteByte((byte)1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample2() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
using (FileStream fs = File.Create("x.txt")) |
||||||
|
{ |
||||||
|
fs.WriteByte((byte)2); |
||||||
|
Console.WriteLine("some text"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample3() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
using (FileStream fs = File.Create("x.txt")) |
||||||
|
{ |
||||||
|
fs.WriteByte((byte)3); |
||||||
|
} |
||||||
|
Console.WriteLine("some text"); |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample4() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
int num; |
||||||
|
using (FileStream fs = File.OpenRead("x.txt")) |
||||||
|
{ |
||||||
|
num = fs.ReadByte(); |
||||||
|
} |
||||||
|
int firstByte = num; |
||||||
|
Console.WriteLine("read:" + firstByte.ToString()); |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample5() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
int num; |
||||||
|
using (FileStream fs = File.OpenRead("x.txt")) |
||||||
|
{ |
||||||
|
num = fs.ReadByte(); |
||||||
|
} |
||||||
|
int firstByte = num; |
||||||
|
int num3; |
||||||
|
using (FileStream fs2 = File.OpenRead("x.txt")) |
||||||
|
{ |
||||||
|
int num2 = fs2.ReadByte(); |
||||||
|
num3 = fs2.ReadByte(); |
||||||
|
} |
||||||
|
int secondByte = num3; |
||||||
|
Console.WriteLine("read: {0}, {1}", firstByte, secondByte); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
using Microsoft.FSharp.Core; |
||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
[assembly: FSharpInterfaceDataVersion(2, 0, 0)] |
||||||
|
[CompilationMapping(SourceConstructFlags.Module)] |
||||||
|
public static class FSharpUsingPatterns |
||||||
|
{ |
||||||
|
public static void sample1() |
||||||
|
{ |
||||||
|
using (FileStream fs = File.Create("x.txt")) |
||||||
|
{ |
||||||
|
fs.WriteByte(1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample2() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
using (FileStream fs = File.Create("x.txt")) |
||||||
|
{ |
||||||
|
fs.WriteByte(2); |
||||||
|
Console.WriteLine("some text"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample3() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
using (FileStream fs = File.Create("x.txt")) |
||||||
|
{ |
||||||
|
fs.WriteByte(3); |
||||||
|
} |
||||||
|
Console.WriteLine("some text"); |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample4() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
int num; |
||||||
|
using (FileStream fs = File.OpenRead("x.txt")) |
||||||
|
{ |
||||||
|
num = fs.ReadByte(); |
||||||
|
} |
||||||
|
int firstByte = num; |
||||||
|
Console.WriteLine("read:" + firstByte.ToString()); |
||||||
|
} |
||||||
|
|
||||||
|
public static void sample5() |
||||||
|
{ |
||||||
|
Console.WriteLine("some text"); |
||||||
|
int secondByte; |
||||||
|
using (FileStream fs = File.OpenRead("x.txt")) |
||||||
|
{ |
||||||
|
secondByte = fs.ReadByte(); |
||||||
|
} |
||||||
|
int firstByte = secondByte; |
||||||
|
int num2; |
||||||
|
using (FileStream fs = File.OpenRead("x.txt")) |
||||||
|
{ |
||||||
|
int num = fs.ReadByte(); |
||||||
|
num2 = fs.ReadByte(); |
||||||
|
} |
||||||
|
secondByte = num2; |
||||||
|
Console.WriteLine("read: {0}, {1}", firstByte, secondByte); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
using ICSharpCode.Decompiler.Ast; |
||||||
|
using ICSharpCode.Decompiler.Tests.Helpers; |
||||||
|
using ICSharpCode.NRefactory.CSharp; |
||||||
|
using Mono.Cecil; |
||||||
|
using NUnit.Framework; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.IO; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.FS2CS |
||||||
|
{ |
||||||
|
public class TestRunner |
||||||
|
{ |
||||||
|
public static string FuzzyReadResource(string resourceName) |
||||||
|
{ |
||||||
|
var asm = Assembly.GetExecutingAssembly(); |
||||||
|
var allResources = asm.GetManifestResourceNames(); |
||||||
|
var fullResourceName = allResources.Single(r => r.ToLowerInvariant().EndsWith(resourceName.ToLowerInvariant())); |
||||||
|
return new StreamReader(asm.GetManifestResourceStream(fullResourceName)).ReadToEnd(); |
||||||
|
} |
||||||
|
|
||||||
|
// see https://fsharp.github.io/FSharp.Compiler.Service/compiler.html
|
||||||
|
public static string CompileFsToAssembly(string source, bool optimize) |
||||||
|
{ |
||||||
|
var tmp = Path.GetTempFileName(); |
||||||
|
File.Delete(tmp); |
||||||
|
var sourceFile = Path.ChangeExtension(tmp, ".fs"); |
||||||
|
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 }); |
||||||
|
File.Delete(sourceFile); |
||||||
|
Assert.AreEqual(0, result.Item1.Length); |
||||||
|
Assert.AreEqual(0, result.Item2); |
||||||
|
Assert.True(File.Exists(asmFile), "Assembly File does not exist"); |
||||||
|
return asmFile; |
||||||
|
} |
||||||
|
|
||||||
|
public static void Run(string fsharpCode, string expectedCSharpCode, bool optimize) |
||||||
|
{ |
||||||
|
var asmFilePath = CompileFsToAssembly(fsharpCode, optimize); |
||||||
|
var assembly = AssemblyDefinition.ReadAssembly(asmFilePath); |
||||||
|
try |
||||||
|
{ |
||||||
|
assembly.MainModule.ReadSymbols(); |
||||||
|
AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule)); |
||||||
|
decompiler.AddAssembly(assembly); |
||||||
|
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(); |
||||||
|
|
||||||
|
decompiler.GenerateCode(new PlainTextOutput(output)); |
||||||
|
var fullCSharpCode = output.ToString(); |
||||||
|
|
||||||
|
CodeAssert.AreEqual(expectedCSharpCode, output.ToString()); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
File.Delete(asmFilePath); |
||||||
|
File.Delete(Path.ChangeExtension(asmFilePath, ".pdb")); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests |
||||||
|
{ |
||||||
|
public class NotUsingBlock |
||||||
|
{ |
||||||
|
public void ThisIsNotAUsingBlock() |
||||||
|
{ |
||||||
|
object obj = File.OpenRead("..."); |
||||||
|
IDisposable disposable; |
||||||
|
try |
||||||
|
{ |
||||||
|
(obj as FileStream).WriteByte(2); |
||||||
|
Console.WriteLine("some text"); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
disposable = (obj as IDisposable); |
||||||
|
if (disposable != null) |
||||||
|
{ |
||||||
|
disposable.Dispose(); |
||||||
|
} |
||||||
|
} |
||||||
|
Console.WriteLine(disposable); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,5 +1,6 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||||
<packages> |
<packages> |
||||||
<package id="DiffLib" version="1.0.0.55" /> |
<package id="DiffLib" version="1.0.0.55" /> |
||||||
|
<package id="FSharp.Compiler.Service" version="2.0.0.2" targetFramework="net45" /> |
||||||
<package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" /> |
<package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" /> |
||||||
</packages> |
</packages> |
Loading…
Reference in new issue