mirror of https://github.com/icsharpcode/ILSpy.git
93 changed files with 3029 additions and 594 deletions
@ -0,0 +1,30 @@ |
|||||||
|
using NUnit.Framework; |
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.FSharpPatterns |
||||||
|
{ |
||||||
|
[TestFixture] |
||||||
|
public class FSharpPatternTests |
||||||
|
{ |
||||||
|
[Test] |
||||||
|
public void FSharpUsingDecompilesToCSharpUsing_Debug() |
||||||
|
{ |
||||||
|
var ilCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Debug.il"); |
||||||
|
var csharpCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Debug.cs"); |
||||||
|
TestHelpers.RunIL(ilCode, csharpCode); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void FSharpUsingDecompilesToCSharpUsing_Release() |
||||||
|
{ |
||||||
|
var ilCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Release.il"); |
||||||
|
var csharpCode = TestHelpers.FuzzyReadResource("FSharpUsing.fs.Release.cs"); |
||||||
|
TestHelpers.RunIL(ilCode, csharpCode); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -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,64 @@ |
|||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
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 fs = File.OpenRead("x.txt")) |
||||||
|
{ |
||||||
|
int num2 = fs.ReadByte(); |
||||||
|
num3 = fs.ReadByte(); |
||||||
|
} |
||||||
|
int secondByte = num3; |
||||||
|
Console.WriteLine("read: {0}, {1}", firstByte, secondByte); |
||||||
|
} |
||||||
|
} |
||||||
@ -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 |
||||||
@ -0,0 +1,64 @@ |
|||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
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,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 |
||||||
@ -0,0 +1,87 @@ |
|||||||
|
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.Diagnostics; |
||||||
|
using System.IO; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace ICSharpCode.Decompiler.Tests.FSharpPatterns |
||||||
|
{ |
||||||
|
public class TestHelpers |
||||||
|
{ |
||||||
|
public static string FuzzyReadResource(string resourceName) |
||||||
|
{ |
||||||
|
var asm = Assembly.GetExecutingAssembly(); |
||||||
|
var allResources = asm.GetManifestResourceNames(); |
||||||
|
var fullResourceName = allResources.Single(r => r.EndsWith(resourceName, StringComparison.OrdinalIgnoreCase)); |
||||||
|
return new StreamReader(asm.GetManifestResourceStream(fullResourceName)).ReadToEnd(); |
||||||
|
} |
||||||
|
|
||||||
|
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 = string.Format("{0} /dll /debug /output:{1}", sourceFile, 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); |
||||||
|
} |
||||||
|
|
||||||
|
private static void CompareAssemblyAgainstCSharp(string expectedCSharpCode, string asmFilePath) |
||||||
|
{ |
||||||
|
var module = ModuleDefinition.ReadModule(asmFilePath); |
||||||
|
try |
||||||
|
{ |
||||||
|
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.OfType<NamespaceDeclaration>().SingleOrDefault(d => d.Name.StartsWith("<StartupCode$", StringComparison.Ordinal)); |
||||||
|
if (startupCodeNode != null) |
||||||
|
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,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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -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,4 +1,5 @@ |
|||||||
<?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="NUnitTestAdapter" version="2.0.0" targetFramework="net45" /> |
||||||
</packages> |
</packages> |
||||||
@ -0,0 +1,269 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.AddIn |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Provides XML documentation tags for Visual Studio CodeElements.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used to support the "/navigateTo" command line option when opening ILSpy. Must match
|
||||||
|
/// the logic of ICSharpCode.ILSpy.XmlDoc.XmlDocKeyProvider, which does the same thing for
|
||||||
|
/// a Mono.Cecil.MemberReference. See "ID string format" in Appendix A of the C# language
|
||||||
|
/// specification for formatting requirements, and Samples/ILSpyAddInSamples.cs for examples.
|
||||||
|
/// </remarks>
|
||||||
|
public static class CodeElementXmlDocKeyProvider |
||||||
|
{ |
||||||
|
#region GetKey
|
||||||
|
public static string GetKey(EnvDTE.CodeElement member) |
||||||
|
{ |
||||||
|
StringBuilder b = new StringBuilder(); |
||||||
|
if ((member.Kind == EnvDTE.vsCMElement.vsCMElementDelegate) || |
||||||
|
(member.Kind == EnvDTE.vsCMElement.vsCMElementEnum) || |
||||||
|
(member.Kind == EnvDTE.vsCMElement.vsCMElementInterface) || |
||||||
|
(member.Kind == EnvDTE.vsCMElement.vsCMElementStruct) || |
||||||
|
(member.Kind == EnvDTE.vsCMElement.vsCMElementClass)) { |
||||||
|
b.Append("T:"); |
||||||
|
AppendTypeName(b, member.FullName, true, false); |
||||||
|
} |
||||||
|
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementNamespace){ |
||||||
|
b.Append("N:"); |
||||||
|
b.Append(member.FullName); |
||||||
|
} |
||||||
|
else { |
||||||
|
if (member.Kind == EnvDTE.vsCMElement.vsCMElementVariable) |
||||||
|
b.Append("F:"); |
||||||
|
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementProperty) |
||||||
|
b.Append("P:"); |
||||||
|
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementEvent) |
||||||
|
b.Append("E:"); |
||||||
|
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementFunction) |
||||||
|
b.Append("M:"); |
||||||
|
|
||||||
|
int nameIndex = member.FullName.LastIndexOf(member.Name); |
||||||
|
string typeName = member.FullName.Substring(0, nameIndex - 1); |
||||||
|
string memberName = member.FullName.Substring(nameIndex); |
||||||
|
|
||||||
|
// Name substitutions for special cases.
|
||||||
|
if (member.Kind == EnvDTE.vsCMElement.vsCMElementFunction) { |
||||||
|
EnvDTE80.CodeFunction2 mr = (EnvDTE80.CodeFunction2)member; |
||||||
|
if (mr.FunctionKind == EnvDTE.vsCMFunction.vsCMFunctionConstructor) { |
||||||
|
memberName = memberName.Replace(member.Name, "#ctor"); |
||||||
|
} |
||||||
|
else if (mr.FunctionKind == EnvDTE.vsCMFunction.vsCMFunctionDestructor) { |
||||||
|
memberName = memberName.Replace(member.Name, "Finalize"); |
||||||
|
} |
||||||
|
else if (mr.FunctionKind == EnvDTE.vsCMFunction.vsCMFunctionOperator) { |
||||||
|
if (memberName.StartsWith("implicit operator")) { |
||||||
|
memberName = "op_Implicit"; |
||||||
|
} |
||||||
|
else if (memberName.StartsWith("explicit operator")) { |
||||||
|
memberName = "op_Explicit"; |
||||||
|
} |
||||||
|
else { |
||||||
|
// NRefactory has a handy mapping we can make use of, just need to extract the operator sybol first.
|
||||||
|
string[] memberNameWords = member.Name.Split(' '); |
||||||
|
if (memberNameWords.Length >= 2) { |
||||||
|
string operatorSymbol = memberNameWords[1]; |
||||||
|
string operatorName = ICSharpCode.NRefactory.MonoCSharp.Operator.GetMetadataName(operatorSymbol); |
||||||
|
if (operatorName != null) { |
||||||
|
memberName = memberName.Replace(member.Name, operatorName); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementProperty) { |
||||||
|
if (member.Name == "this") { |
||||||
|
memberName = memberName.Replace(member.Name, "Item"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
string[] genericTypeParameters = AppendTypeName(b, typeName, true, false); |
||||||
|
b.Append('.'); |
||||||
|
string[] genericMethodParameters = AppendTypeName(b, memberName.Replace('.', '#'), true, true); |
||||||
|
EnvDTE.CodeElements parameters; |
||||||
|
EnvDTE.CodeTypeRef explicitReturnType = null; |
||||||
|
if (member.Kind == EnvDTE.vsCMElement.vsCMElementProperty) { |
||||||
|
parameters = ((EnvDTE.CodeProperty)member).Getter.Parameters; |
||||||
|
} |
||||||
|
else if (member.Kind == EnvDTE.vsCMElement.vsCMElementFunction) { |
||||||
|
EnvDTE80.CodeFunction2 mr = (EnvDTE80.CodeFunction2)member; |
||||||
|
parameters = mr.Parameters; |
||||||
|
if (memberName == "op_Implicit" || memberName == "op_Explicit") { |
||||||
|
explicitReturnType = mr.Type; |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
parameters = null; |
||||||
|
} |
||||||
|
if (parameters != null && parameters.Count > 0) { |
||||||
|
b.Append('('); |
||||||
|
int i = 0; |
||||||
|
foreach (EnvDTE80.CodeParameter2 parameter in parameters) { |
||||||
|
if (i > 0) b.Append(','); |
||||||
|
AppendParameterTypeName(b, parameter, genericTypeParameters, genericMethodParameters); |
||||||
|
++i; |
||||||
|
} |
||||||
|
b.Append(')'); |
||||||
|
} |
||||||
|
if (explicitReturnType != null) { |
||||||
|
b.Append('~'); |
||||||
|
AppendTypeName(b, explicitReturnType.AsFullName, true, false); |
||||||
|
} |
||||||
|
} |
||||||
|
return b.ToString(); |
||||||
|
} |
||||||
|
|
||||||
|
static string[] AppendTypeName(StringBuilder b, string typeName, bool appendGenericParameterCount, bool isMethod) |
||||||
|
{ |
||||||
|
List<string> allGenericParameters = new List<string>(); |
||||||
|
StringBuilder genericParameterName = new StringBuilder(); |
||||||
|
|
||||||
|
bool inGenericParameters = false; |
||||||
|
int genericParameterCount = 0; |
||||||
|
foreach (char ch in typeName) { |
||||||
|
if (inGenericParameters) { |
||||||
|
switch (ch) { |
||||||
|
case ',': |
||||||
|
++genericParameterCount; |
||||||
|
allGenericParameters.Add(genericParameterName.ToString()); |
||||||
|
genericParameterName.Clear(); |
||||||
|
break; |
||||||
|
case '>': |
||||||
|
++genericParameterCount; |
||||||
|
allGenericParameters.Add(genericParameterName.ToString()); |
||||||
|
genericParameterName.Clear(); |
||||||
|
if (appendGenericParameterCount) { |
||||||
|
b.Append(genericParameterCount); |
||||||
|
} |
||||||
|
inGenericParameters = false; |
||||||
|
break; |
||||||
|
case ' ': |
||||||
|
break; |
||||||
|
default: |
||||||
|
genericParameterName.Append(ch); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
switch (ch) { |
||||||
|
case '<': |
||||||
|
if (appendGenericParameterCount) { |
||||||
|
b.Append('`'); |
||||||
|
if (isMethod) { |
||||||
|
b.Append('`'); |
||||||
|
} |
||||||
|
} |
||||||
|
inGenericParameters = true; |
||||||
|
genericParameterCount = 0; |
||||||
|
break; |
||||||
|
case '[': |
||||||
|
case ']': |
||||||
|
break; |
||||||
|
default: |
||||||
|
b.Append(ch); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return allGenericParameters.ToArray(); |
||||||
|
} |
||||||
|
|
||||||
|
private static void AppendParameterTypeName(StringBuilder b, EnvDTE80.CodeParameter2 parameter, string[] genericTypeParameters, string[] genericMethodParameters) |
||||||
|
{ |
||||||
|
EnvDTE80.CodeTypeRef2 parameterTypeRef = (EnvDTE80.CodeTypeRef2)parameter.Type; |
||||||
|
string parameterTypeString = parameterTypeRef.AsFullName; |
||||||
|
|
||||||
|
int substringStart = 0; |
||||||
|
for (int i = 0; i < parameterTypeString.Length; ++i) { |
||||||
|
char ch = parameterTypeString[i]; |
||||||
|
switch (ch) { |
||||||
|
case '<': |
||||||
|
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters); |
||||||
|
substringStart = i + 1; |
||||||
|
b.Append('{'); |
||||||
|
break; |
||||||
|
case '>': |
||||||
|
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters); |
||||||
|
substringStart = i + 1; |
||||||
|
b.Append('}'); |
||||||
|
break; |
||||||
|
|
||||||
|
case '[': |
||||||
|
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters); |
||||||
|
b.Append('['); |
||||||
|
|
||||||
|
// Skip ahead to the closing bracket, counting commas to determine array rank.
|
||||||
|
int rank = 1; |
||||||
|
do { |
||||||
|
++i; |
||||||
|
ch = parameterTypeString[i]; |
||||||
|
if (ch == ',') { |
||||||
|
++rank; |
||||||
|
} |
||||||
|
} |
||||||
|
while (ch != ']'); |
||||||
|
substringStart = i + 1; |
||||||
|
|
||||||
|
// For multi-dimensional arrays, add "0:" default array bounds. Note that non-standard bounds are not possible via C# declaration.
|
||||||
|
if (rank > 1) { |
||||||
|
for (int r = 0; r < rank; ++r) { |
||||||
|
if (r != 0) { |
||||||
|
b.Append(','); |
||||||
|
} |
||||||
|
b.Append("0:"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
b.Append(']'); |
||||||
|
break; |
||||||
|
|
||||||
|
case ',': |
||||||
|
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, i, genericTypeParameters, genericMethodParameters); |
||||||
|
substringStart = i + 1; |
||||||
|
// Skip space after comma if present. (e.g. System.Collections.Generic.KeyValuePair`2{System.String,System.String}.)
|
||||||
|
if (parameterTypeString[substringStart] == ' ') { |
||||||
|
++substringStart; |
||||||
|
} |
||||||
|
b.Append(','); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
AppendParameterTypeSubstring(b, parameterTypeString, substringStart, parameterTypeString.Length, genericTypeParameters, genericMethodParameters); |
||||||
|
|
||||||
|
// Append ref / out indicator if needed.
|
||||||
|
if ((parameter.ParameterKind == EnvDTE80.vsCMParameterKind.vsCMParameterKindRef) || |
||||||
|
(parameter.ParameterKind == EnvDTE80.vsCMParameterKind.vsCMParameterKindOut)) { |
||||||
|
b.Append('@'); |
||||||
|
} |
||||||
|
|
||||||
|
// Note there is no need to append a '*' for pointers, as this is included in the full name of the type.
|
||||||
|
// Multi-dimensional and jagged arrays are handled above during string parsing.
|
||||||
|
} |
||||||
|
|
||||||
|
private static void AppendParameterTypeSubstring(StringBuilder b, string parameterTypeString, int substringStart, int substringStop, string[] genericTypeParameters, string[] genericMethodParameters) |
||||||
|
{ |
||||||
|
if (substringStart < substringStop) { |
||||||
|
string substring = parameterTypeString.Substring(substringStart, substringStop - substringStart); |
||||||
|
int indexOfGenericTypeParameter = Array.IndexOf(genericTypeParameters, substring); |
||||||
|
int indexOfGenericMethodParameter = Array.IndexOf(genericMethodParameters, substring); |
||||||
|
if (indexOfGenericTypeParameter >= 0) { |
||||||
|
b.Append("`"); |
||||||
|
b.Append(indexOfGenericTypeParameter); |
||||||
|
} |
||||||
|
else if (indexOfGenericMethodParameter >= 0) { |
||||||
|
b.Append("``"); |
||||||
|
b.Append(indexOfGenericMethodParameter); |
||||||
|
} |
||||||
|
else { |
||||||
|
b.Append(substring); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion
|
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,414 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.Collections.Generic; |
||||||
|
|
||||||
|
/// Sample source file indicating a wide variety of code elements that should work
|
||||||
|
/// with the "Open code in ILSpy" Visual Studio add-in feature. Each code element is
|
||||||
|
/// commented with the string generated by CodeElementXmlDocKeyProvider.GetKey and
|
||||||
|
/// used with the ILSpy /navigateTo command line option.
|
||||||
|
///
|
||||||
|
/// Note that this code is not compiled or used in the project in any way, it is
|
||||||
|
/// only provided for reference.
|
||||||
|
|
||||||
|
|
||||||
|
// N:ILSpy.AddIn.Tests
|
||||||
|
namespace ILSpy.AddIn.Tests |
||||||
|
{ |
||||||
|
// T:ILSpy.AddIn.Tests.SomeClass
|
||||||
|
public class SomeClass |
||||||
|
{ |
||||||
|
// E:ILSpy.AddIn.Tests.SomeClass.OnEvent
|
||||||
|
public event Action OnEvent; |
||||||
|
|
||||||
|
// F:ILSpy.AddIn.Tests.SomeClass.mField
|
||||||
|
private int mField; |
||||||
|
|
||||||
|
// P:ILSpy.AddIn.Tests.SomeClass.Property
|
||||||
|
private int Property |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return mField; |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
mField = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// P:ILSpy.AddIn.Tests.SomeClass.Item(System.Int32,System.Int32)
|
||||||
|
public int this[int x, int y] |
||||||
|
{ |
||||||
|
get { return x + y + mField; } |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.#ctor
|
||||||
|
public SomeClass() |
||||||
|
{ |
||||||
|
mField = 0; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.#ctor(System.Int32)
|
||||||
|
public SomeClass(int x) |
||||||
|
{ |
||||||
|
mField = x; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.#ctor(System.Int32,System.Int32)
|
||||||
|
public SomeClass(int x, int y) |
||||||
|
{ |
||||||
|
mField = x + y; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.Method
|
||||||
|
public int Method() |
||||||
|
{ |
||||||
|
return mField; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.MethodWithGenericParameter(System.IEquatable{System.String})
|
||||||
|
public void MethodWithGenericParameter(IEquatable<string> x) |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.MethodWithGenericParameter(System.IEquatable{System.String},System.Int32)
|
||||||
|
public void MethodWithGenericParameter(IEquatable<string> x, int y) |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.GenericMethod``1(``0)
|
||||||
|
public int GenericMethod<T>(T x) |
||||||
|
{ |
||||||
|
return mField + x.GetHashCode(); |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.GenericOverloadedMethod``1(System.Int32,``0)
|
||||||
|
public int GenericOverloadedMethod<T1>(int x, T1 y) |
||||||
|
{ |
||||||
|
return mField + x + y.GetHashCode(); |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.GenericOverloadedMethod``2(System.Int32,``0,``1)
|
||||||
|
public int GenericOverloadedMethod<T1, T2>(int x, T1 y, T2 z) |
||||||
|
{ |
||||||
|
return mField + x + y.GetHashCode() + z.GetHashCode(); |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedMethod
|
||||||
|
public int OverloadedMethod() |
||||||
|
{ |
||||||
|
return mField * mField; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedMethod(System.Int32)
|
||||||
|
public int OverloadedMethod(int m) |
||||||
|
{ |
||||||
|
return mField * m; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedMethod(System.Int32,System.Int32)
|
||||||
|
public int OverloadedMethod(int m1, int m2) |
||||||
|
{ |
||||||
|
return mField * m1 * m2; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1
|
||||||
|
public int OverloadedGenericMethod<T>() |
||||||
|
{ |
||||||
|
return mField * mField; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32)
|
||||||
|
public int OverloadedGenericMethod<T>(int m) |
||||||
|
{ |
||||||
|
return mField * m; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32)
|
||||||
|
public int OverloadedGenericMethod<T>(int m1, int m2) |
||||||
|
{ |
||||||
|
return mField * m1 * m2; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32,System.Collections.IEnumerable)
|
||||||
|
public int OverloadedGenericMethod<T>(int m1, int m2, IEnumerable m3) |
||||||
|
{ |
||||||
|
return mField * m1 * m2; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32,System.Collections.Generic.IEnumerable{``0})
|
||||||
|
public int OverloadedGenericMethod<T>(int m1, int m2, IEnumerable<T> m3) |
||||||
|
{ |
||||||
|
return mField * m1 * m2; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Int32,System.Int32,System.Collections.Generic.IEnumerable{System.String})
|
||||||
|
public int OverloadedGenericMethod<T>(int m1, int m2, IEnumerable<string> m3) |
||||||
|
{ |
||||||
|
return mField * m1 * m2; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{ILSpy.AddIn.Tests.SomeGenericClass{System.String,``0}}})
|
||||||
|
public int OverloadedGenericMethod<T>(IEnumerable<IEnumerable<SomeGenericClass<string, T>>> m3) |
||||||
|
{ |
||||||
|
return mField; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.OverloadedGenericMethod``1(ILSpy.AddIn.Tests.SomeGenericClass{``0,ILSpy.AddIn.Tests.SomeGenericClass{``0,``0}}.NestedGeneric{System.String,``0})
|
||||||
|
public void OverloadedGenericMethod<T>(SomeGenericClass<T, SomeGenericClass<T, T>>.NestedGeneric<string, T> wow) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// T:ILSpy.AddIn.Tests.SomeClass.NestedEnum
|
||||||
|
public enum NestedEnum |
||||||
|
{ |
||||||
|
// F:ILSpy.AddIn.Tests.SomeClass.NestedEnum.First
|
||||||
|
First = 1, |
||||||
|
Second = 2, |
||||||
|
Third = 3 |
||||||
|
} |
||||||
|
|
||||||
|
// T:ILSpy.AddIn.Tests.SomeClass.NestedInterface
|
||||||
|
public interface NestedInterface |
||||||
|
{ |
||||||
|
// P:ILSpy.AddIn.Tests.SomeClass.NestedInterface.SomeProperty
|
||||||
|
int SomeProperty { get; } |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.NestedInterface.SomeMethod
|
||||||
|
int SomeMethod(); |
||||||
|
} |
||||||
|
|
||||||
|
// T:ILSpy.AddIn.Tests.SomeClass.NestedClass
|
||||||
|
public class NestedClass : NestedInterface |
||||||
|
{ |
||||||
|
// F:ILSpy.AddIn.Tests.SomeClass.NestedClass.mX
|
||||||
|
private int mX; |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.NestedClass.#ctor(System.Int32)
|
||||||
|
public NestedClass(int x) |
||||||
|
{ |
||||||
|
mX = x; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.NestedClass.#ctor(ILSpy.AddIn.Tests.SomeClass.NestedEnum)
|
||||||
|
public NestedClass(NestedEnum x) |
||||||
|
{ |
||||||
|
mX = (int)x; |
||||||
|
} |
||||||
|
|
||||||
|
// P:ILSpy.AddIn.Tests.SomeClass.NestedClass.SomeProperty
|
||||||
|
public int SomeProperty |
||||||
|
{ |
||||||
|
get { return mX; } |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.NestedClass.SomeMethod
|
||||||
|
public int SomeMethod() |
||||||
|
{ |
||||||
|
return mX * mX; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// T:ILSpy.AddIn.Tests.SomeClass.NestedStruct
|
||||||
|
public struct NestedStruct : NestedInterface |
||||||
|
{ |
||||||
|
// F:ILSpy.AddIn.Tests.SomeClass.NestedStruct.X
|
||||||
|
public int X; |
||||||
|
// F:ILSpy.AddIn.Tests.SomeClass.NestedStruct.Y
|
||||||
|
public int Y; |
||||||
|
|
||||||
|
// P:ILSpy.AddIn.Tests.SomeClass.NestedStruct.SomeProperty
|
||||||
|
public int SomeProperty |
||||||
|
{ |
||||||
|
get { return X + Y; } |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeClass.NestedStruct.SomeMethod
|
||||||
|
public int SomeMethod() |
||||||
|
{ |
||||||
|
return X * Y; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// T:ILSpy.AddIn.Tests.SomeGenericClass`2
|
||||||
|
public class SomeGenericClass<T1, T2> |
||||||
|
{ |
||||||
|
// F:ILSpy.AddIn.Tests.SomeGenericClass`2.mField1
|
||||||
|
T1 mField1; |
||||||
|
// F:ILSpy.AddIn.Tests.SomeGenericClass`2.mField2
|
||||||
|
T2 mField2; |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.#ctor(`0,`1)
|
||||||
|
public SomeGenericClass(T1 a, T2 b) |
||||||
|
{ |
||||||
|
mField1 = a; |
||||||
|
mField2 = b; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.#ctor(`0)
|
||||||
|
public SomeGenericClass(T1 a) |
||||||
|
{ |
||||||
|
mField1 = a; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.#ctor
|
||||||
|
public SomeGenericClass() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.Finalize
|
||||||
|
~SomeGenericClass() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(`0,`1)
|
||||||
|
public void GenericClassMethod(T1 a, T2 b) |
||||||
|
{ |
||||||
|
mField1 = a; |
||||||
|
mField2 = b; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(System.Int32*)
|
||||||
|
unsafe public void GenericClassMethod(int* x) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(System.Int32*[])
|
||||||
|
unsafe public void GenericClassMethod(int*[] x) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(`0[]@)
|
||||||
|
unsafe public void GenericClassMethod(out T1[] x) |
||||||
|
{ |
||||||
|
x = null; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassMethod(System.Int32@)
|
||||||
|
public void GenericClassMethod(ref int a) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``1(``0@)
|
||||||
|
public T3 GenericClassGenericMethod<T3>(ref T3 x) |
||||||
|
{ |
||||||
|
return x; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``1
|
||||||
|
public T3 GenericClassGenericMethod<T3>() |
||||||
|
{ |
||||||
|
return default(T3); |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``1(System.Int32)
|
||||||
|
public void GenericClassGenericMethod<T3>(int x) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``1,System.Int32,`1@)
|
||||||
|
public T4 GenericClassGenericMethod<T3, T4>(T1 x, T4 y, int z, out T2 result) |
||||||
|
{ |
||||||
|
mField1 = x; |
||||||
|
string foo = y.ToString() + z.ToString(); |
||||||
|
result = mField2; |
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,System.Int32[])
|
||||||
|
public T3 GenericClassGenericMethod<T3, T4>(T1 x, T3 y, int[] z) |
||||||
|
{ |
||||||
|
mField1 = x; |
||||||
|
string foo = y.ToString() + z.ToString(); |
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[],System.Int32[])
|
||||||
|
public void ArrayMethod(T1[] x, int[] y) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[0:,0:],System.Int32[0:,0:])
|
||||||
|
public void ArrayMethod(T1[,] x, int[,] y) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(System.Int32[0:,0:],System.Int32[0:,0:])
|
||||||
|
public void ArrayMethod(int[,] x, int[,] y) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.ArrayMethod(`0[][],System.Int32[][])
|
||||||
|
public void ArrayMethod(T1[][] x, int[][] y) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,ILSpy.AddIn.Tests.SomeClass)
|
||||||
|
public T3 GenericClassGenericMethod<T3, T4>(T1 x, T3 y, SomeClass z) |
||||||
|
{ |
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(`0,``0,ILSpy.AddIn.Tests.SomeClass[]@)
|
||||||
|
public T3 GenericClassGenericMethod<T3, T4>(T1 x, T3 y, out SomeClass[] z) |
||||||
|
{ |
||||||
|
z = null; |
||||||
|
return y; |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.GenericClassGenericMethod``2(System.Int32[],ILSpy.AddIn.Tests.SomeGenericClass{``0[],``1[0:,0:,0:]}[0:,0:,0:])
|
||||||
|
public void GenericClassGenericMethod<T3, T4>(int[] x, SomeGenericClass<T3[], T4[,,]>[,,] y) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.op_Addition(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1},ILSpy.AddIn.Tests.SomeGenericClass{`0,`1})
|
||||||
|
public static SomeGenericClass<T1, T2> operator +(SomeGenericClass<T1, T2> a, SomeGenericClass<T1, T2> b) |
||||||
|
{ |
||||||
|
return new SomeGenericClass<T1, T2>(); |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.op_Explicit(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1})~ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2
|
||||||
|
public static explicit operator NestedGeneric<T1, T2>(SomeGenericClass<T1, T2> sgc) |
||||||
|
{ |
||||||
|
return new NestedGeneric<T1, T2>(); |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.op_Implicit(ILSpy.AddIn.Tests.SomeGenericClass{`0,`1})~ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2
|
||||||
|
public static implicit operator NestedGeneric<T2, T1>(SomeGenericClass<T1, T2> sgc) |
||||||
|
{ |
||||||
|
return new NestedGeneric<T2, T1>(); |
||||||
|
} |
||||||
|
|
||||||
|
// T:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2
|
||||||
|
public class NestedGeneric<T3, T4> |
||||||
|
{ |
||||||
|
// T:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2.NestedDelegate
|
||||||
|
public delegate int NestedDelegate(T3 x, IEnumerable<T4> y); |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2.NestedGenericMethod``1(`0,``0)
|
||||||
|
public void NestedGenericMethod<T5>(T1 x, T5 y) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
// M:ILSpy.AddIn.Tests.SomeGenericClass`2.NestedGeneric`2.NestedGenericMethod``3(`0,`3,``0[],System.Collections.Generic.IEnumerable{``2})
|
||||||
|
public void NestedGenericMethod<T5, T6, T7>(T1 x, T4 y, T5[] z, IEnumerable<T7> w) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// T:SpaceFreeClass
|
||||||
|
class SpaceFreeClass |
||||||
|
{ |
||||||
|
// F:SpaceFreeClass.mField
|
||||||
|
int mField; |
||||||
|
|
||||||
|
// M:SpaceFreeClass.Method
|
||||||
|
private void Method() |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy |
||||||
|
{ |
||||||
|
[ExportMainMenuCommand(Menu = "_Help", Header = "_Check for Updates", MenuOrder = 5000)] |
||||||
|
sealed class CheckForUpdatesCommand : SimpleCommand |
||||||
|
{ |
||||||
|
public override void Execute(object parameter) |
||||||
|
{ |
||||||
|
MainWindow.Instance.ShowMessageIfUpdatesAvailableAsync(ILSpySettings.Load(), forceCheck: true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy |
||||||
|
{ |
||||||
|
[ExportMainMenuCommand(Menu = "_View", Header = "Sort assembly list by name", MenuIcon = "Images/Sort.png", MenuCategory = "View")] |
||||||
|
[ExportToolbarCommand(ToolTip = "Sort assembly list by name", ToolbarIcon = "Images/Sort.png", ToolbarCategory = "View")] |
||||||
|
class SortAssemblyListCommand : SimpleCommand, IComparer<LoadedAssembly> |
||||||
|
{ |
||||||
|
public override void Execute(object parameter) |
||||||
|
{ |
||||||
|
using (MainWindow.Instance.treeView.LockUpdates()) |
||||||
|
MainWindow.Instance.CurrentAssemblyList.Sort(this); |
||||||
|
} |
||||||
|
|
||||||
|
int IComparer<LoadedAssembly>.Compare(LoadedAssembly x, LoadedAssembly y) |
||||||
|
{ |
||||||
|
return string.Compare(x.ShortName, y.ShortName, StringComparison.CurrentCulture); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 417 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 347 B |
|
After Width: | Height: | Size: 710 B |
|
After Width: | Height: | Size: 380 B |
@ -0,0 +1,30 @@ |
|||||||
|
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
|
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||||
|
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||||
|
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||||
|
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy |
||||||
|
{ |
||||||
|
public interface IResourceFileHandler |
||||||
|
{ |
||||||
|
string EntryType { get; } |
||||||
|
bool CanHandle(string name, DecompilationOptions options); |
||||||
|
string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, DecompilationOptions options); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
# ILSpy |
||||||
|
|
||||||
|
[](https://gitter.im/icsharpcode/ILSpy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
||||||
|
|
||||||
|
[@ilspy](https://twitter.com/ilspy) | [ilspy.net](http://ilspy.net/) |
||||||
|
|
||||||
|
Downloads |
||||||
|
------- |
||||||
|
|
||||||
|
Xcopy-deployable binaries via [ilspy.net](http://ilspy.net/) |
||||||
|
|
||||||
|
Visual Studio extension via [VS Gallery](https://visualstudiogallery.msdn.microsoft.com/8ef1d688-f80c-4380-8004-2ec7f814e7de) |
||||||
|
|
||||||
|
Decompiler NuGet package via [NuGet](https://www.nuget.org/packages/ICSharpCode.Decompiler/) |
||||||
|
|
||||||
|
Get a recent nightly build from [here](http://build.sharpdevelop.net/BuildArtefacts/#ILSpyMaster) |
||||||
|
|
||||||
|
License |
||||||
|
------- |
||||||
|
|
||||||
|
ILSpy is distributed under the MIT License. |
||||||
|
|
||||||
|
Included open-source libraries: |
||||||
|
* Mono.Cecil: MIT License (thanks to Jb Evain) |
||||||
|
* AvalonEdit: LGPL |
||||||
|
* SharpTreeView: LGPL |
||||||
|
* ICSharpCode.Decompiler: MIT License (developed as part of ILSpy) |
||||||
|
* Ricciolo.StylesExplorer: MS-PL (part of ILSpy.BamlDecompiler.Plugin) |
||||||
Loading…
Reference in new issue