Browse Source

test that the "F# using" does not get applied if the 'disposable' variable is used afterwards

add F# to C# decompilation unit tests
pull/671/head
lrieger 9 years ago
parent
commit
d059c02ba3
  1. 31
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpPatternTests.cs
  2. 38
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs
  3. 67
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Debug.cs
  4. 67
      ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs.Release.cs
  5. 72
      ICSharpCode.Decompiler/Tests/FSharpPatterns/TestRunner.cs
  6. 19
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  7. 28
      ICSharpCode.Decompiler/Tests/NotUsingBlock.cs
  8. 11
      ICSharpCode.Decompiler/Tests/TestRunner.cs
  9. 1
      ICSharpCode.Decompiler/Tests/packages.config

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

@ -0,0 +1,31 @@ @@ -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);
}
}
}

38
ICSharpCode.Decompiler/Tests/FSharpPatterns/FSharpUsing.fs

@ -0,0 +1,38 @@ @@ -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)

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

@ -0,0 +1,67 @@ @@ -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);
}
}

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

@ -0,0 +1,67 @@ @@ -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);
}
}

72
ICSharpCode.Decompiler/Tests/FSharpPatterns/TestRunner.cs

@ -0,0 +1,72 @@ @@ -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"));
}
}
}
}

19
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -49,6 +49,10 @@ @@ -49,6 +49,10 @@
<Reference Include="DiffLib">
<HintPath>..\..\packages\DiffLib.1.0.0.55\lib\net35-Client\DiffLib.dll</HintPath>
</Reference>
<Reference Include="FSharp.Compiler.Service, Version=2.0.0.2, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\FSharp.Compiler.Service.2.0.0.2\lib\net45\FSharp.Compiler.Service.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.core, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll</HintPath>
<Private>False</Private>
@ -86,12 +90,16 @@ @@ -86,12 +90,16 @@
<Compile Include="DoubleConstants.cs" />
<Compile Include="ExpressionTrees.cs" />
<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="IL\ILTests.cs" />
<Compile Include="LiftedOperators.cs" />
<Compile Include="CustomShortCircuitOperators.cs" />
<Compile Include="Helpers\CodeAssert.cs" />
<Compile Include="IncrementDecrement.cs" />
<Compile Include="Lock.cs" />
<Compile Include="NotUsingBlock.cs" />
<Compile Include="PInvoke.cs" />
<Compile Include="QueryExpressions.cs" />
<Compile Include="Switch.cs" />
@ -131,6 +139,10 @@ @@ -131,6 +139,10 @@
<Project>{d68133bd-1e63-496e-9ede-4fbdbf77b486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
<ProjectReference Include="..\..\cecil\symbols\pdb\Mono.Cecil.Pdb.csproj">
<Project>{63e6915c-7ea4-4d76-ab28-0d7191eea626}</Project>
<Name>Mono.Cecil.Pdb</Name>
</ProjectReference>
<ProjectReference Include="..\..\NRefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53dca265-3c3c-42f9-b647-f72ba678122b}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
@ -144,12 +156,17 @@ @@ -144,12 +156,17 @@
<Name>ICSharpCode.Decompiler</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<EmbeddedResource Include="FSharpPatterns\FSharpUsing.fs" />
</ItemGroup>
<ItemGroup>
<None Include="BooleanConsumedAsInteger.il" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="FSharpPatterns\FSharpUsing.fs.Release.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

28
ICSharpCode.Decompiler/Tests/NotUsingBlock.cs

@ -0,0 +1,28 @@ @@ -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);
}
}
}

11
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -180,13 +180,20 @@ namespace ICSharpCode.Decompiler.Tests @@ -180,13 +180,20 @@ namespace ICSharpCode.Decompiler.Tests
{
TestFile(@"..\..\Tests\YieldReturn.cs");
}
[Test]
public void TypeAnalysis()
{
TestFile(@"..\..\Tests\TypeAnalysisTests.cs");
}
// see https://github.com/icsharpcode/ILSpy/pull/671
[Test]
public void NotUsingBlock()
{
TestFile(@"..\..\Tests\NotUsingBlock.cs");
}
static void TestFile(string fileName, bool useDebug = false, int compilerVersion = 4)
{
AssertRoundtripCode(fileName, optimize: false, useDebug: useDebug, compilerVersion: compilerVersion);

1
ICSharpCode.Decompiler/Tests/packages.config

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<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" />
</packages>
Loading…
Cancel
Save