From 483a8661f65339feb5343155266534a453c8dea7 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 15 Sep 2026 19:16:29 +0200 Subject: [PATCH] Add VB tests for On Error and Try/Catch/Finally VB lowers error handling differently from C# and no fixture covered it: every Catch brackets its body with SetProjectError/ClearProjectError, Catch...When moves that call into the filter, and On Error becomes one try block with a dispatch switch driven by line and handler state. The expected output is the current decompilation, rough spots included (delegate-invoked filter blocks; gotos into the dispatch switch that leave unreachable code, which keeps VBOnError.cs out of the warnings-as-errors project), so improvements show up as diffs. IL offset labels differ per compiler and optimization level, hence the per-method #if variants. Legacy vbc output was verified on Windows. The correctness test covers what a pretty test cannot: catching object made the decompiled On Error code fail to recompile with CS0155, and the round trip shows the rewritten dispatch code still runs the same. Like the mcs configurations, the legacy and Roslyn 2.10/.NET Core 2.2 ones recompile the decompiled VB code with the latest Roslyn: C# 5 cannot express the exception filters VB error handling compiles to, and the .NET Core 2.2 Microsoft.VisualBasic.dll lacks Information.Err and ProjectData.CreateProjectError. Assisted-by: Claude:claude-opus-5:Claude Code --- .../CorrectnessTestRunner.cs | 18 + .../ICSharpCode.Decompiler.Tests.csproj | 5 + .../Correctness/VBOnErrorCorrectness.vb | 91 + .../TestCases/VBPretty/VBOnError.cs | 3120 +++++++++++++++++ .../TestCases/VBPretty/VBOnError.vb | 107 + .../TestCases/VBPretty/VBTryCatchFinally.cs | 619 ++++ .../TestCases/VBPretty/VBTryCatchFinally.vb | 308 ++ .../VBPrettyTestRunner.cs | 14 + 8 files changed, 4282 insertions(+) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Correctness/VBOnErrorCorrectness.vb create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.vb create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.vb diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index 37fea77c9..2d6970fc7 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -277,6 +277,12 @@ namespace ICSharpCode.Decompiler.Tests await RunVB(options: options); } + [Test] + public async Task VBOnErrorCorrectness([ValueSource(nameof(noMonoOptions))] CompilerOptions options) + { + await RunVB(options: options); + } + [Test] public async Task MemberLookup([ValueSource(nameof(defaultOptions))] CompilerOptions options) { @@ -497,6 +503,18 @@ namespace ICSharpCode.Decompiler.Tests outputFile = await Tester.CompileVB(Path.Combine(TestCasePath, testFileName), options, outputFileName: testOutputFileName).ConfigureAwait(false); string decompiledCodeFile = await Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)).ConfigureAwait(false); + if ((options & CompilerOptions.UseRoslynMask) == 0) + { + // For second pass, use roslyn instead of the legacy csc. + // VB error handling compiles to exception filters, which C# 5 cannot express. + options |= CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40; + } + else if ((options & CompilerOptions.UseRoslyn2_10_0) != 0 && (options & CompilerOptions.TargetNet40) == 0) + { + // The .NET Core 2.2 Microsoft.VisualBasic.dll lacks most of the VB runtime + // that decompiled VB code calls, such as Information.Err. + options = (options & ~CompilerOptions.UseRoslyn2_10_0) | CompilerOptions.UseRoslynLatest; + } decompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false); await Tester.RunAndCompareOutput(testFileName, outputFile.PathToAssembly, decompiledOutputFile.PathToAssembly, decompiledCodeFile, (options & CompilerOptions.UseTestRunner) != 0, (options & CompilerOptions.Force32Bit) != 0); diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 5accf84e3..7bbdf3087 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -109,6 +109,7 @@ + @@ -161,6 +162,8 @@ + + @@ -306,6 +309,8 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/VBOnErrorCorrectness.vb b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/VBOnErrorCorrectness.vb new file mode 100644 index 000000000..23e430f0a --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/VBOnErrorCorrectness.vb @@ -0,0 +1,91 @@ +Imports System +Imports Microsoft.VisualBasic + +Module VBOnErrorCorrectness + Sub Main() + ResumeNext() + GoToHandler() + GoToHandlerResumeNext() + Console.WriteLine(GoToHandlerResume(3)) + GoToHandlerResumeLabel() + Try + GoToZero() + Catch ex As InvalidOperationException + Console.WriteLine("outer: " & ex.Message) + End Try + Console.WriteLine(GoToHandlerWithResult()) + End Sub + + Sub FailWhilePositive(retries As Integer) + If retries > 0 Then Fail("retry " & retries) + End Sub + + Sub Fail(message As String) + Throw New InvalidOperationException(message) + End Sub + + Sub ResumeNext() + On Error Resume Next + Fail("a") + Console.WriteLine("after a: " & Err.Number & " " & Err.Description) + Err.Clear() + Console.WriteLine("cleared: " & Err.Number) + End Sub + + Sub GoToHandler() + On Error GoTo Handler + Fail("b") + Console.WriteLine("unreachable") + Exit Sub +Handler: + Console.WriteLine("handler: " & Err.Description) + End Sub + + Sub GoToHandlerResumeNext() + On Error GoTo Handler + Fail("c1") + Console.WriteLine("between") + Fail("c2") + Console.WriteLine("done") + Exit Sub +Handler: + Console.WriteLine("handler: " & Err.Description) + Resume Next + End Sub + + Function GoToHandlerResume(retries As Integer) As Integer + On Error GoTo Handler + FailWhilePositive(retries) + Return retries +Handler: + retries -= 1 + Resume + End Function + + Sub GoToHandlerResumeLabel() + On Error GoTo Handler + Fail("d") +Done: + Console.WriteLine("done") + Exit Sub +Handler: + Console.WriteLine("handler: " & Err.Description) + Resume Done + End Sub + + Sub GoToZero() + On Error Resume Next + Fail("e1") + Console.WriteLine("swallowed") + On Error GoTo 0 + Fail("e2") + Console.WriteLine("unreachable") + End Sub + + Function GoToHandlerWithResult() As Integer + On Error GoTo Handler + Return Integer.Parse("x") +Handler: + Return -1 + End Function +End Module diff --git a/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.cs b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.cs new file mode 100644 index 000000000..b97926380 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.cs @@ -0,0 +1,3120 @@ +using System; +using Microsoft.VisualBasic; +using Microsoft.VisualBasic.CompilerServices; + +public class VBOnError +{ +#if OPT + public static void ResumeNext() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 65: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 4: + goto end_IL_0000_3; + } + goto default; + } + IL_0007: + num2 = 2; + Console.WriteLine("A"); + break; + end_IL_0000_2: + break; + } + num2 = 3; + Console.WriteLine("B"); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 65; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (LEGACY_VBC && !OPT) + public static void ResumeNext() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 68: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 4: + goto end_IL_0000_3; + } + goto default; + } + IL_0007: + num2 = 2; + Console.WriteLine("A"); + break; + end_IL_0000_2: + break; + } + num2 = 3; + Console.WriteLine("B"); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 68; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void ResumeNext() + { + int try0001_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = -2; + goto IL_000b; + case 71: + { + num = num2; + switch ((num3 <= -2) ? 1 : num3) + { + case 1: + break; + default: + goto end_IL_0001; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_000b; + case 3: + goto end_IL_0001_2; + default: + goto end_IL_0001; + case 4: + goto end_IL_0001_3; + } + goto default; + } + IL_000b: + num2 = 2; + Console.WriteLine("A"); + break; + end_IL_0001_2: + break; + } + num2 = 3; + Console.WriteLine("B"); + break; + end_IL_0001:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 71; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if (LEGACY_VBC && OPT) + public static int ResumeNextWithResult() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + int num5 = default; + int num6 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 64: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_000c; + case 4: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 5: + goto end_IL_0000_3; + } + goto default; + } + IL_000c: + num2 = 3; + num5 /= 0; + break; + IL_0007: + num2 = 2; + num5 = 1; + goto IL_000c; + end_IL_0000_2: + break; + } + num2 = 4; + num6 = num5; + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 64; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + int result = num6; + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#elif (LEGACY_VBC && !OPT) + public static int ResumeNextWithResult() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + int num5 = default; + int num6 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 67: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_000c; + case 4: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 5: + goto end_IL_0000_3; + } + goto default; + } + IL_000c: + num2 = 3; + num5 /= 0; + break; + IL_0007: + num2 = 2; + num5 = 1; + goto IL_000c; + end_IL_0000_2: + break; + } + num2 = 4; + num6 = num5; + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 67; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + int result = num6; + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#elif (!LEGACY_VBC && OPT) + public static int ResumeNextWithResult() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + int num5 = default; + int result = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 63: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_000c; + case 4: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 5: + goto end_IL_0000_3; + } + goto default; + } + IL_000c: + num2 = 3; + num5 /= 0; + break; + IL_0007: + num2 = 2; + num5 = 1; + goto IL_000c; + end_IL_0000_2: + break; + } + num2 = 4; + result = num5; + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 63; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#else + public static int ResumeNextWithResult() + { + int try0001_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + int num5 = default; + int result = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = -2; + goto IL_000b; + case 69: + { + num = num2; + switch ((num3 <= -2) ? 1 : num3) + { + case 1: + break; + default: + goto end_IL_0001; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_000b; + case 3: + goto IL_0010; + case 4: + goto end_IL_0001_2; + default: + goto end_IL_0001; + case 5: + goto end_IL_0001_3; + } + goto default; + } + IL_000b: + num2 = 2; + num5 = 1; + goto IL_0010; + IL_0010: + num2 = 3; + num5 /= 0; + break; + end_IL_0001_2: + break; + } + num2 = 4; + result = num5; + break; + end_IL_0001:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 69; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#endif + +#if (LEGACY_VBC && OPT) + public static void ResumeNextErrNumber() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 109: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto IL_0022; + case 5: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 6: + case 7: + goto end_IL_0000_3; + } + goto default; + } + IL_0022: + num2 = 4; + Console.WriteLine(Information.Err().Description); + break; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + IL_0013: + num2 = 3; + if (Information.Err().Number == 0) + { + goto end_IL_0000_3; + } + goto IL_0022; + end_IL_0000_2: + break; + } + num2 = 5; + Information.Err().Clear(); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 109; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (LEGACY_VBC && !OPT) + public static void ResumeNextErrNumber() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 112: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto IL_0022; + case 5: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 6: + case 7: + goto end_IL_0000_3; + } + goto default; + } + IL_0022: + num2 = 4; + Console.WriteLine(Information.Err().Description); + break; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + IL_0013: + num2 = 3; + if (Information.Err().Number == 0) + { + goto end_IL_0000_3; + } + goto IL_0022; + end_IL_0000_2: + break; + } + num2 = 5; + Information.Err().Clear(); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 112; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (!LEGACY_VBC && OPT) + public static void ResumeNextErrNumber() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 104: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto IL_0021; + case 5: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 6: + goto end_IL_0000_3; + } + goto default; + } + IL_0021: + num2 = 4; + Console.WriteLine(Information.Err().Description); + break; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + IL_0013: + num2 = 3; + if (Information.Err().Number == 0) + { + goto end_IL_0000_3; + } + goto IL_0021; + end_IL_0000_2: + break; + } + num2 = 5; + Information.Err().Clear(); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 104; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void ResumeNextErrNumber() + { + int try0001_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = -2; + goto IL_000b; + case 122: + { + num = num2; + switch ((num3 <= -2) ? 1 : num3) + { + case 1: + break; + default: + goto end_IL_0001; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_000b; + case 3: + goto IL_0018; + case 4: + goto IL_002b; + case 5: + goto end_IL_0001_2; + default: + goto end_IL_0001; + case 6: + case 7: + goto end_IL_0001_3; + } + goto default; + } + IL_000b: + num2 = 2; + Console.WriteLine("A"); + goto IL_0018; + IL_0018: + num2 = 3; + if (Information.Err().Number == 0) + { + goto end_IL_0001_3; + } + goto IL_002b; + IL_002b: + num2 = 4; + Console.WriteLine(Information.Err().Description); + break; + end_IL_0001_2: + break; + } + num2 = 5; + Information.Err().Clear(); + break; + end_IL_0001:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 122; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if LEGACY_VBC || OPT + public static void GoToHandler() + { + int try0000_dispatch = -1; + int num2 = default; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + Console.WriteLine("Body"); + goto end_IL_0000; + case 36: + num = -1; + switch (num2) + { + case 2: + Console.WriteLine(Information.Err().Description); + goto end_IL_0000; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 36; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void GoToHandler() + { + int try0001_dispatch = -1; + int num2 = default; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + Console.WriteLine("Body"); + goto end_IL_0001; + case 42: + num = -1; + switch (num2) + { + case 2: + Console.WriteLine(Information.Err().Description); + goto end_IL_0001; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 42; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if (LEGACY_VBC && OPT) + public static void GoToHandlerResumeNext() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 120: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_004c; + default: + goto end_IL_0000; + } + goto IL_0024; + } + IL_0024: + num2 = 5; + Console.WriteLine(Information.Err().Number); + goto IL_0035; + IL_0035: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_004c; + IL_0013: + num2 = 3; + Console.WriteLine("B"); + goto end_IL_0000_2; + IL_004c: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 5: + goto IL_0024; + case 6: + goto IL_0035; + default: + goto end_IL_0000; + case 4: + case 7: + goto end_IL_0000_2; + } + goto default; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 120; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (LEGACY_VBC && !OPT) + public static void GoToHandlerResumeNext() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 125: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_0051; + default: + goto end_IL_0000; + } + goto IL_0024; + } + IL_0024: + num2 = 5; + Console.WriteLine(Information.Err().Number); + goto IL_0035; + IL_0035: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_0051; + IL_0013: + num2 = 3; + Console.WriteLine("B"); + goto end_IL_0000_2; + IL_0051: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 5: + goto IL_0024; + case 6: + goto IL_0035; + default: + goto end_IL_0000; + case 4: + case 7: + goto end_IL_0000_2; + } + goto default; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 125; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (!LEGACY_VBC && OPT) + public static void GoToHandlerResumeNext() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 117: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_0049; + default: + goto end_IL_0000; + } + goto IL_0021; + } + IL_0021: + num2 = 5; + Console.WriteLine(Information.Err().Number); + goto IL_0032; + IL_0032: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_0049; + IL_0013: + num2 = 3; + Console.WriteLine("B"); + goto end_IL_0000_2; + IL_0049: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 5: + goto IL_0021; + case 6: + goto IL_0032; + default: + goto end_IL_0000; + case 4: + case 7: + goto end_IL_0000_2; + } + goto default; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 117; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void GoToHandlerResumeNext() + { + int try0001_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_000a; + case 127: + { + num = num2; + switch ((num3 <= -2) ? 1 : num3) + { + case 2: + break; + case 1: + goto IL_0053; + default: + goto end_IL_0001; + } + goto IL_0027; + } + IL_000a: + num2 = 2; + Console.WriteLine("A"); + goto IL_0017; + IL_0053: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_000a; + case 3: + goto IL_0017; + case 5: + goto IL_0027; + case 6: + goto IL_0039; + default: + goto end_IL_0001; + case 4: + case 7: + goto end_IL_0001_2; + } + goto default; + IL_0027: + num2 = 5; + Console.WriteLine(Information.Err().Number); + goto IL_0039; + IL_0039: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_0053; + IL_0017: + num2 = 3; + Console.WriteLine("B"); + goto end_IL_0001_2; + end_IL_0001: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 127; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if (LEGACY_VBC && OPT) + public static void GoToHandlerResume(int retries) + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 115: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_003f; + default: + goto end_IL_0000; + } + goto IL_0018; + } + IL_003f: + num4 = num + 1; + goto IL_0042; + IL_0018: + num2 = 4; + retries = checked(retries - 1); + goto IL_001f; + IL_001f: + num2 = 5; + if (retries <= 0) + { + goto end_IL_0000_2; + } + goto IL_0025; + IL_0025: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num4 = num; + goto IL_0042; + IL_0007: + num2 = 2; + Console.WriteLine("Body"); + goto end_IL_0000_2; + IL_0042: + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 4: + goto IL_0018; + case 5: + goto IL_001f; + case 6: + goto IL_0025; + default: + goto end_IL_0000; + case 3: + case 7: + case 8: + case 9: + goto end_IL_0000_2; + } + goto default; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 115; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (LEGACY_VBC && !OPT) + public static void GoToHandlerResume(int retries) + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 117: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_0041; + default: + goto end_IL_0000; + } + goto IL_0018; + } + IL_0041: + num4 = num + 1; + goto IL_0044; + IL_0018: + num2 = 4; + retries = checked(retries - 1); + goto IL_001f; + IL_001f: + num2 = 5; + if (retries <= 0) + { + goto end_IL_0000_2; + } + goto IL_0025; + IL_0025: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num4 = num; + goto IL_0044; + IL_0007: + num2 = 2; + Console.WriteLine("Body"); + goto end_IL_0000_2; + IL_0044: + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 4: + goto IL_0018; + case 5: + goto IL_001f; + case 6: + goto IL_0025; + default: + goto end_IL_0000; + case 3: + case 7: + case 8: + case 9: + goto end_IL_0000_2; + } + goto default; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 117; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (!LEGACY_VBC && OPT) + public static void GoToHandlerResume(int retries) + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 104: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_003c; + default: + goto end_IL_0000; + } + goto IL_0015; + } + IL_003c: + num4 = num + 1; + goto IL_003f; + IL_0015: + num2 = 4; + retries = checked(retries - 1); + goto IL_001c; + IL_001c: + num2 = 5; + if (retries <= 0) + { + goto end_IL_0000_2; + } + goto IL_0022; + IL_0022: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num4 = num; + goto IL_003f; + IL_0007: + num2 = 2; + Console.WriteLine("Body"); + goto end_IL_0000_2; + IL_003f: + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 4: + goto IL_0015; + case 5: + goto IL_001c; + case 6: + goto IL_0022; + default: + goto end_IL_0000; + case 3: + case 7: + goto end_IL_0000_2; + } + goto default; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 104; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void GoToHandlerResume(int retries) + { + int try0001_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_000a; + case 122: + { + num = num2; + switch ((num3 <= -2) ? 1 : num3) + { + case 2: + break; + case 1: + goto IL_004a; + default: + goto end_IL_0001; + } + goto IL_001a; + } + IL_000a: + num2 = 2; + Console.WriteLine("Body"); + goto end_IL_0001_2; + IL_004d: + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_000a; + case 4: + goto IL_001a; + case 5: + goto IL_0021; + case 6: + goto IL_002b; + default: + goto end_IL_0001; + case 3: + case 7: + case 8: + goto end_IL_0001_2; + } + goto default; + IL_004a: + num4 = num + 1; + goto IL_004d; + IL_001a: + num2 = 4; + retries = checked(retries - 1); + goto IL_0021; + IL_0021: + num2 = 5; + if (retries <= 0) + { + goto end_IL_0001_2; + } + goto IL_002b; + IL_002b: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num4 = num; + goto IL_004d; + end_IL_0001: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 122; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if (LEGACY_VBC && OPT) + public static void GoToHandlerResumeLabel() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 128: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_0050; + default: + goto end_IL_0000; + } + goto IL_0024; + } + IL_0050: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + case 7: + goto IL_0013; + case 5: + goto IL_0024; + case 6: + goto IL_0035; + default: + goto end_IL_0000; + case 4: + case 8: + goto end_IL_0000_2; + } + goto default; + IL_0024: + num2 = 5; + Console.WriteLine(Information.Err().Description); + goto IL_0035; + IL_0035: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num = 0; + goto IL_0013; + IL_0007: + num2 = 2; + Console.WriteLine("Body"); + goto IL_0013; + IL_0013: + num2 = 3; + Console.WriteLine("Done"); + goto end_IL_0000_2; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 128; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (LEGACY_VBC && !OPT) + public static void GoToHandlerResumeLabel() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 131: + { + num = num2; + switch (num3) + { + case 2: + break; + case 1: + goto IL_0053; + default: + goto end_IL_0000; + } + goto IL_0024; + } + IL_0053: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + case 7: + goto IL_0013; + case 5: + goto IL_0024; + case 6: + goto IL_0035; + default: + goto end_IL_0000; + case 4: + case 8: + goto end_IL_0000_2; + } + goto default; + IL_0024: + num2 = 5; + Console.WriteLine(Information.Err().Description); + goto IL_0035; + IL_0035: + num2 = 6; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num = 0; + goto IL_0013; + IL_0007: + num2 = 2; + Console.WriteLine("Body"); + goto IL_0013; + IL_0013: + num2 = 3; + Console.WriteLine("Done"); + goto end_IL_0000_2; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 131; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (!LEGACY_VBC && OPT) + public static void GoToHandlerResumeLabel() + { + int try0000_dispatch = -1; + int num2 = default; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + Console.WriteLine("Body"); + break; + case 69: + num = -1; + switch (num2) + { + case 2: + Console.WriteLine(Information.Err().Description); + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num = 0; + break; + default: + goto end_IL_0000; + } + break; + } + Console.WriteLine("Done"); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 69; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void GoToHandlerResumeLabel() + { + int try0001_dispatch = -1; + int num2 = default; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + Console.WriteLine("Body"); + break; + case 78: + num = -1; + switch (num2) + { + case 2: + Console.WriteLine(Information.Err().Description); + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + num = 0; + break; + default: + goto end_IL_0001; + } + break; + } + Console.WriteLine("Done"); + break; + end_IL_0001:; + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 78; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if OPT + public static void GoToZero() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 76: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 5: + goto end_IL_0000_3; + } + goto default; + } + IL_0013: + ProjectData.ClearProjectError(); + num3 = 0; + break; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000_2: + break; + } + num2 = 4; + Console.WriteLine("B"); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 76; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (LEGACY_VBC && !OPT) + public static void GoToZero() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 1; + goto IL_0007; + case 79: + { + num = num2; + switch (num3) + { + case 1: + break; + default: + goto end_IL_0000; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto end_IL_0000_2; + default: + goto end_IL_0000; + case 5: + goto end_IL_0000_3; + } + goto default; + } + IL_0013: + ProjectData.ClearProjectError(); + num3 = 0; + break; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000_2: + break; + } + num2 = 4; + Console.WriteLine("B"); + break; + end_IL_0000:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 79; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void GoToZero() + { + int try0001_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = -2; + goto IL_000b; + case 83: + { + num = num2; + switch ((num3 <= -2) ? 1 : num3) + { + case 1: + break; + default: + goto end_IL_0001; + } + int num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_000b; + case 3: + goto IL_0018; + case 4: + goto end_IL_0001_2; + default: + goto end_IL_0001; + case 5: + goto end_IL_0001_3; + } + goto default; + } + IL_000b: + num2 = 2; + Console.WriteLine("A"); + goto IL_0018; + IL_0018: + ProjectData.ClearProjectError(); + num3 = 0; + break; + end_IL_0001_2: + break; + } + num2 = 4; + Console.WriteLine("B"); + break; + end_IL_0001:; + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 83; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001_3: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if LEGACY_VBC || OPT + public static void GoToMinusOne() + { + int try0000_dispatch = -1; + int num2 = default; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + Console.WriteLine("A"); + goto end_IL_0000; + case 57: + num = -1; + switch (num2) + { + case 2: + ProjectData.ClearProjectError(); + num = 0; + ProjectData.ClearProjectError(); + num2 = 3; + Console.WriteLine("B"); + goto end_IL_0000; + case 3: + Console.WriteLine("C"); + goto end_IL_0000; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 57; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void GoToMinusOne() + { + int try0001_dispatch = -1; + int num2 = default; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + Console.WriteLine("A"); + goto end_IL_0001; + case 67: + num = -1; + switch (num2) + { + case 2: + ProjectData.ClearProjectError(); + num = 0; + ProjectData.ClearProjectError(); + num2 = 3; + Console.WriteLine("B"); + goto end_IL_0001; + case 3: + Console.WriteLine("C"); + goto end_IL_0001; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 67; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if (LEGACY_VBC && OPT) + public static void SwitchHandlers() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 176: + { + num = num2; + switch (num3) + { + case 2: + break; + case 3: + goto IL_004c; + case 1: + goto IL_0074; + default: + goto end_IL_0000; + } + goto IL_002b; + } + IL_002b: + num2 = 6; + Console.WriteLine("Handler1"); + goto IL_0037; + IL_0037: + num2 = 7; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_0074; + IL_001a: + num2 = 4; + Console.WriteLine("B"); + goto end_IL_0000_2; + IL_0074: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto IL_001a; + case 6: + goto IL_002b; + case 7: + goto IL_0037; + case 8: + case 9: + goto IL_004c; + case 10: + goto IL_0059; + default: + goto end_IL_0000; + case 5: + case 11: + goto end_IL_0000_2; + } + goto default; + IL_004c: + num2 = 9; + Console.WriteLine("Handler2"); + goto IL_0059; + IL_0059: + num2 = 10; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_0074; + IL_0013: + ProjectData.ClearProjectError(); + num3 = 3; + goto IL_001a; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 176; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (LEGACY_VBC && !OPT) + public static void SwitchHandlers() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 183: + { + num = num2; + switch (num3) + { + case 2: + break; + case 3: + goto IL_004e; + case 1: + goto IL_007b; + default: + goto end_IL_0000; + } + goto IL_002b; + } + IL_002b: + num2 = 6; + Console.WriteLine("Handler1"); + goto IL_0037; + IL_0037: + num2 = 7; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_007b; + IL_001a: + num2 = 4; + Console.WriteLine("B"); + goto end_IL_0000_2; + IL_007b: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto IL_001a; + case 6: + goto IL_002b; + case 7: + goto IL_0037; + case 8: + case 9: + goto IL_004e; + case 10: + goto IL_005b; + default: + goto end_IL_0000; + case 5: + case 11: + goto end_IL_0000_2; + } + goto default; + IL_004e: + num2 = 9; + Console.WriteLine("Handler2"); + goto IL_005b; + IL_005b: + num2 = 10; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_007b; + IL_0013: + ProjectData.ClearProjectError(); + num3 = 3; + goto IL_001a; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 183; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#elif (!LEGACY_VBC && OPT) + public static void SwitchHandlers() + { + int try0000_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_0007; + case 165: + { + num = num2; + switch (num3) + { + case 2: + break; + case 3: + goto IL_0049; + case 1: + goto IL_006d; + default: + goto end_IL_0000; + } + goto IL_0028; + } + IL_0028: + num2 = 6; + Console.WriteLine("Handler1"); + goto IL_0034; + IL_0034: + num2 = 7; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_006d; + IL_001a: + num2 = 4; + Console.WriteLine("B"); + goto end_IL_0000_2; + IL_006d: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_0007; + case 3: + goto IL_0013; + case 4: + goto IL_001a; + case 6: + goto IL_0028; + case 7: + goto IL_0034; + case 8: + goto IL_0049; + case 9: + goto IL_0055; + default: + goto end_IL_0000; + case 5: + case 10: + goto end_IL_0000_2; + } + goto default; + IL_0049: + num2 = 8; + Console.WriteLine("Handler2"); + goto IL_0055; + IL_0055: + num2 = 9; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_006d; + IL_0013: + ProjectData.ClearProjectError(); + num3 = 3; + goto IL_001a; + IL_0007: + num2 = 2; + Console.WriteLine("A"); + goto IL_0013; + end_IL_0000: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 165; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#else + public static void SwitchHandlers() + { + int try0001_dispatch = -1; + int num3 = default; + int num = default; + int num2 = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + int num4; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num3 = 2; + goto IL_000a; + case 184: + { + num = num2; + switch ((num3 <= -2) ? 1 : num3) + { + case 2: + break; + case 3: + goto IL_0055; + case 1: + goto IL_0080; + default: + goto end_IL_0001; + } + goto IL_002f; + } + IL_000a: + num2 = 2; + Console.WriteLine("A"); + goto IL_0017; + IL_0017: + ProjectData.ClearProjectError(); + num3 = 3; + goto IL_001f; + IL_002f: + num2 = 6; + Console.WriteLine("Handler1"); + goto IL_003c; + IL_003c: + num2 = 7; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_0080; + IL_001f: + num2 = 4; + Console.WriteLine("B"); + goto end_IL_0001_2; + IL_0080: + num4 = num + 1; + num = 0; + switch (num4) + { + case 1: + break; + case 2: + goto IL_000a; + case 3: + goto IL_0017; + case 4: + goto IL_001f; + case 6: + goto IL_002f; + case 7: + goto IL_003c; + case 8: + goto IL_0055; + case 9: + goto IL_0062; + default: + goto end_IL_0001; + case 5: + case 10: + goto end_IL_0001_2; + } + goto default; + IL_0055: + num2 = 8; + Console.WriteLine("Handler2"); + goto IL_0062; + IL_0062: + num2 = 9; + ProjectData.ClearProjectError(); + if (num == 0) + { + throw ProjectData.CreateProjectError(-2146828268); + } + goto IL_0080; + end_IL_0001: + break; + } + } + catch (Exception ex) when ((num3 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 184; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001_2: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + } +#endif + +#if (LEGACY_VBC && OPT) + public static int GoToHandlerWithResult() + { + int try0000_dispatch = -1; + int num2 = default; + int num3; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + num3 = int.Parse("x"); + goto end_IL_0000; + case 24: + num = -1; + switch (num2) + { + case 2: + num3 = -1; + goto end_IL_0000; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 24; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000: + break; + } + int result = num3; + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#elif (LEGACY_VBC && !OPT) + public static int GoToHandlerWithResult() + { + int try0000_dispatch = -1; + int num2 = default; + int num3; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + num3 = int.Parse("x"); + goto end_IL_0000; + case 26: + num = -1; + switch (num2) + { + case 2: + num3 = -1; + goto end_IL_0000; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 26; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000: + break; + } + int result = num3; + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#elif (!LEGACY_VBC && OPT) + public static int GoToHandlerWithResult() + { + int try0000_dispatch = -1; + int num2 = default; + int result; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0000_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + result = int.Parse("x"); + goto end_IL_0000; + case 24: + num = -1; + switch (num2) + { + case 2: + result = -1; + goto end_IL_0000; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0000_dispatch = 24; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0000: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#else + public static int GoToHandlerWithResult() + { + int try0001_dispatch = -1; + int num2 = default; + int result; + int num = default; + while (true) + { + try + { + /*Note: ILSpy has introduced the following switch to emulate a goto from catch-block to try-block*/; + switch (try0001_dispatch) + { + default: + ProjectData.ClearProjectError(); + num2 = 2; + result = int.Parse("x"); + goto end_IL_0001; + case 30: + num = -1; + switch (num2) + { + case 2: + result = -1; + goto end_IL_0001; + } + break; + } + } + catch (Exception ex) when ((num2 != 0) & (num == 0)) + { + ProjectData.SetProjectError(ex); + try0001_dispatch = 30; + continue; + } + throw ProjectData.CreateProjectError(-2146828237); + continue; + end_IL_0001: + break; + } + if (num != 0) + { + ProjectData.ClearProjectError(); + } + return result; + } +#endif +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.vb b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.vb new file mode 100644 index 000000000..ed82ac645 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBOnError.vb @@ -0,0 +1,107 @@ +Imports System +Imports Microsoft.VisualBasic + +Public Class VBOnError + Public Shared Sub ResumeNext() + On Error Resume Next + Console.WriteLine("A") + Console.WriteLine("B") + End Sub + + Public Shared Function ResumeNextWithResult() As Integer + On Error Resume Next + Dim x As Integer = 1 + x = x \ 0 + Return x + End Function + + Public Shared Sub ResumeNextErrNumber() + On Error Resume Next + Console.WriteLine("A") + If Err.Number <> 0 Then + Console.WriteLine(Err.Description) + Err.Clear() + End If + End Sub + + Public Shared Sub GoToHandler() + On Error GoTo Handler + Console.WriteLine("Body") + Exit Sub +Handler: + Console.WriteLine(Err.Description) + End Sub + + Public Shared Sub GoToHandlerResumeNext() + On Error GoTo Handler + Console.WriteLine("A") + Console.WriteLine("B") + Exit Sub +Handler: + Console.WriteLine(Err.Number) + Resume Next + End Sub + + Public Shared Sub GoToHandlerResume(retries As Integer) + On Error GoTo Handler + Console.WriteLine("Body") + Exit Sub +Handler: + retries -= 1 + If retries > 0 Then + Resume + End If + End Sub + + Public Shared Sub GoToHandlerResumeLabel() + On Error GoTo Handler + Console.WriteLine("Body") +Done: + Console.WriteLine("Done") + Exit Sub +Handler: + Console.WriteLine(Err.Description) + Resume Done + End Sub + + Public Shared Sub GoToZero() + On Error Resume Next + Console.WriteLine("A") + On Error GoTo 0 + Console.WriteLine("B") + End Sub + + Public Shared Sub GoToMinusOne() + On Error GoTo Handler + Console.WriteLine("A") + Exit Sub +Handler: + On Error GoTo -1 + On Error GoTo Handler2 + Console.WriteLine("B") + Exit Sub +Handler2: + Console.WriteLine("C") + End Sub + + Public Shared Sub SwitchHandlers() + On Error GoTo Handler1 + Console.WriteLine("A") + On Error GoTo Handler2 + Console.WriteLine("B") + Exit Sub +Handler1: + Console.WriteLine("Handler1") + Resume Next +Handler2: + Console.WriteLine("Handler2") + Resume Next + End Sub + + Public Shared Function GoToHandlerWithResult() As Integer + On Error GoTo Handler + Return Integer.Parse("x") +Handler: + Return -1 + End Function +End Class diff --git a/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.cs b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.cs new file mode 100644 index 000000000..4a61a242f --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.cs @@ -0,0 +1,619 @@ +using System; +using System.IO; + +using Microsoft.VisualBasic.CompilerServices; + +public class VBTryCatchFinally +{ + private static bool Condition() + { + return true; + } + + public static void TryFinally() + { + try + { + Console.WriteLine("Try"); + } + finally + { + Console.WriteLine("Finally"); + } + } + + public static void TryCatchBare() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + } + + public static void TryCatchVariable() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception ex2 = ex; + Console.WriteLine(ex2.Message); + ProjectData.ClearProjectError(); + } + } + + public static void TryCatchSpecificType() + { + try + { + Console.WriteLine("Try"); + } + catch (IOException ex) + { + ProjectData.SetProjectError(ex); + IOException ex2 = ex; + Console.WriteLine(ex2.Message); + ProjectData.ClearProjectError(); + } + } + + public static void TryCatchUnusedVariable() + { + try + { + Console.WriteLine("Try"); + } + catch (InvalidOperationException ex) + { + ProjectData.SetProjectError(ex); + InvalidOperationException ex2 = ex; + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + } + + public static void TryCatchWhen() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception projectError) when (((Func)delegate { + // Could not convert BlockContainer to single expression + ProjectData.SetProjectError(projectError); + return Condition(); + }).Invoke()) + { + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + } + + public static void TryCatchVariableWhen() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) when (((Func)delegate { + // Could not convert BlockContainer to single expression + ProjectData.SetProjectError(ex); + return ex.Message != null; + }).Invoke()) + { + Console.WriteLine(ex.Message); + ProjectData.ClearProjectError(); + } + } + + public static void TryCatchSpecificTypeWhen() + { + try + { + Console.WriteLine("Try"); + } + catch (IOException ex) when (((Func)delegate { + // Could not convert BlockContainer to single expression + ProjectData.SetProjectError(ex); + return Condition(); + }).Invoke()) + { + Console.WriteLine(ex.Message); + ProjectData.ClearProjectError(); + } + } + + public static void TryCatchExistingLocal() + { + Exception value = null; + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + value = ex; + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + Console.WriteLine(value); + } + + public static void TryCatchExistingLocalWhen() + { + Exception value = null; + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) when (((Func)delegate { + // Could not convert BlockContainer to single expression +#if LEGACY_VBC + value = ex; + ProjectData.SetProjectError(ex); +#else + ProjectData.SetProjectError(ex); + value = ex; +#endif + return ex.Message != null; + }).Invoke()) + { + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + Console.WriteLine(value); + } + + public static void TryCatchFinally() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception ex2 = ex; + Console.WriteLine(ex2.Message); + ProjectData.ClearProjectError(); + } + finally + { + Console.WriteLine("Finally"); + } + } + + public static void TryCatchBareFinally() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + finally + { + Console.WriteLine("Finally"); + } + } + + public static void TryCatchWhenFinally() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) when (((Func)delegate { + // Could not convert BlockContainer to single expression + ProjectData.SetProjectError(ex); + return Condition(); + }).Invoke()) + { + Console.WriteLine(ex.Message); + ProjectData.ClearProjectError(); + } + finally + { + Console.WriteLine("Finally"); + } + } + + public static void TryMultipleCatch() + { + try + { + Console.WriteLine("Try"); + } + catch (FileNotFoundException ex) + { + ProjectData.SetProjectError(ex); + FileNotFoundException ex2 = ex; + Console.WriteLine(ex2.FileName); + ProjectData.ClearProjectError(); + } + catch (IOException ex3) + { + ProjectData.SetProjectError(ex3); + IOException ex4 = ex3; + Console.WriteLine(ex4.Message); + ProjectData.ClearProjectError(); + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + } + + public static void TryMultipleCatchFinally() + { + try + { + Console.WriteLine("Try"); + } + catch (FileNotFoundException ex) + { + ProjectData.SetProjectError(ex); + FileNotFoundException ex2 = ex; + Console.WriteLine(ex2.FileName); + ProjectData.ClearProjectError(); + } + catch (IOException ex3) + { + ProjectData.SetProjectError(ex3); + IOException ex4 = ex3; + Console.WriteLine(ex4.Message); + ProjectData.ClearProjectError(); + } + finally + { + Console.WriteLine("Finally"); + } + } + + public static void TryMultipleCatchWhen() + { + try + { + Console.WriteLine("Try"); + } + catch (IOException ex) when (((Func)delegate { + // Could not convert BlockContainer to single expression + ProjectData.SetProjectError(ex); + return Condition(); + }).Invoke()) + { + Console.WriteLine(ex.Message); + ProjectData.ClearProjectError(); + } + catch (Exception projectError) when (((Func)delegate { + // Could not convert BlockContainer to single expression + ProjectData.SetProjectError(projectError); + return Condition(); + }).Invoke()) + { + Console.WriteLine("Catch When"); + ProjectData.ClearProjectError(); + } + catch (Exception ex2) + { + ProjectData.SetProjectError(ex2); + Exception ex3 = ex2; + Console.WriteLine(ex3.Message); + ProjectData.ClearProjectError(); + } + } + + public static void EmptyTryFinally() + { + try + { + } + finally + { + Console.WriteLine("Finally"); + } + } + + public static void EmptyCatch() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + ProjectData.ClearProjectError(); + } + } + + public static void EmptyFinally() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception ex2 = ex; + Console.WriteLine(ex2.Message); + ProjectData.ClearProjectError(); + } +#if !OPT || LEGACY_VBC + finally + { + } +#endif + } + + public static void ExitTryInTry(bool b) + { + try + { + if (!b) + { + Console.WriteLine("Try"); + } + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + Console.WriteLine("End"); + } + + public static void ExitTryInCatch(bool b) + { + try + { + Console.WriteLine("Try"); + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + if (b) + { + ProjectData.ClearProjectError(); + } + else + { + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + } + Console.WriteLine("End"); + } + + public static void ExitTryWithFinally(bool b) + { + try + { + if (!b) + { + Console.WriteLine("Try"); + } + } + finally + { + Console.WriteLine("Finally"); + } + Console.WriteLine("End"); + } + + public static void Rethrow() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception ex2 = ex; + Console.WriteLine(ex2.Message); + throw; + } + } + + public static void ThrowNew() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception innerException = ex; + throw new InvalidOperationException("Catch", innerException); + } + } + + public static int ReturnFromTry() + { + int result; + try + { + result = 1; + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + result = 2; + ProjectData.ClearProjectError(); + } + finally + { + Console.WriteLine("Finally"); + } + return result; + } + + public static int ReturnAfterTry() + { +#if !(LEGACY_VBC && OPT) + int result; +#endif + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception ex2 = ex; + Console.WriteLine(ex2.Message); +#if LEGACY_VBC && OPT + int result = -1; + ProjectData.ClearProjectError(); + return result; + } + return 0; +#else + result = -1; + ProjectData.ClearProjectError(); +#if LEGACY_VBC + goto IL_0032; +#elif OPT + goto IL_0029; +#else + goto IL_0031; +#endif + } + result = 0; +#if LEGACY_VBC + goto IL_0032; + IL_0032: +#elif OPT + goto IL_0029; + IL_0029: +#else + goto IL_0031; + IL_0031: +#endif + return result; +#endif + } + + public static void NestedTryInTry() + { + try + { + try + { + Console.WriteLine("Inner Try"); + } + catch (IOException ex) + { + ProjectData.SetProjectError(ex); + IOException ex2 = ex; + Console.WriteLine(ex2.Message); + ProjectData.ClearProjectError(); + } + } + catch (Exception ex3) + { + ProjectData.SetProjectError(ex3); + Exception ex4 = ex3; + Console.WriteLine(ex4.Message); + ProjectData.ClearProjectError(); + } + } + + public static void NestedTryInCatch() + { + try + { + Console.WriteLine("Try"); + } + catch (Exception ex) + { + ProjectData.SetProjectError(ex); + Exception ex2 = ex; + try + { + Console.WriteLine(ex2.Message); + } + catch (Exception ex3) + { + ProjectData.SetProjectError(ex3); + Exception ex4 = ex3; + Console.WriteLine(ex4.Message); + ProjectData.ClearProjectError(); + } + ProjectData.ClearProjectError(); + } + } + + public static void NestedTryInFinally() + { + try + { + Console.WriteLine("Try"); + } + finally + { + try + { + Console.WriteLine("Inner Try"); + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + Console.WriteLine("Inner Catch"); + ProjectData.ClearProjectError(); + } + } + } + + public static void TryInLoop() + { + int num = 0; + do + { + try + { + switch (num) + { + case 5: + break; + case 8: + return; + default: + Console.WriteLine(num); + break; + } + } + catch (Exception projectError) + { + ProjectData.SetProjectError(projectError); + Console.WriteLine("Catch"); + ProjectData.ClearProjectError(); + } + finally + { + Console.WriteLine("Finally"); + } + num = checked(num + 1); + } while (num <= 9); + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.vb b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.vb new file mode 100644 index 000000000..27f2e53c1 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBTryCatchFinally.vb @@ -0,0 +1,308 @@ +Imports System +Imports System.IO + +Public Class VBTryCatchFinally + Private Shared Function Condition() As Boolean + Return True + End Function + + Public Shared Sub TryFinally() + Try + Console.WriteLine("Try") + Finally + Console.WriteLine("Finally") + End Try + End Sub + + Public Shared Sub TryCatchBare() + Try + Console.WriteLine("Try") + Catch + Console.WriteLine("Catch") + End Try + End Sub + + Public Shared Sub TryCatchVariable() + Try + Console.WriteLine("Try") + Catch ex As Exception + Console.WriteLine(ex.Message) + End Try + End Sub + + Public Shared Sub TryCatchSpecificType() + Try + Console.WriteLine("Try") + Catch ex As IOException + Console.WriteLine(ex.Message) + End Try + End Sub + + Public Shared Sub TryCatchUnusedVariable() + Try + Console.WriteLine("Try") + Catch ex As InvalidOperationException + Console.WriteLine("Catch") + End Try + End Sub + + Public Shared Sub TryCatchWhen() + Try + Console.WriteLine("Try") + Catch When Condition() + Console.WriteLine("Catch") + End Try + End Sub + + Public Shared Sub TryCatchVariableWhen() + Try + Console.WriteLine("Try") + Catch ex As Exception When ex.Message IsNot Nothing + Console.WriteLine(ex.Message) + End Try + End Sub + + Public Shared Sub TryCatchSpecificTypeWhen() + Try + Console.WriteLine("Try") + Catch ex As IOException When Condition() + Console.WriteLine(ex.Message) + End Try + End Sub + + Public Shared Sub TryCatchExistingLocal() + Dim ex As Exception = Nothing + Try + Console.WriteLine("Try") + Catch ex + Console.WriteLine("Catch") + End Try + Console.WriteLine(ex) + End Sub + + Public Shared Sub TryCatchExistingLocalWhen() + Dim ex As Exception = Nothing + Try + Console.WriteLine("Try") + Catch ex When ex.Message IsNot Nothing + Console.WriteLine("Catch") + End Try + Console.WriteLine(ex) + End Sub + + Public Shared Sub TryCatchFinally() + Try + Console.WriteLine("Try") + Catch ex As Exception + Console.WriteLine(ex.Message) + Finally + Console.WriteLine("Finally") + End Try + End Sub + + Public Shared Sub TryCatchBareFinally() + Try + Console.WriteLine("Try") + Catch + Console.WriteLine("Catch") + Finally + Console.WriteLine("Finally") + End Try + End Sub + + Public Shared Sub TryCatchWhenFinally() + Try + Console.WriteLine("Try") + Catch ex As Exception When Condition() + Console.WriteLine(ex.Message) + Finally + Console.WriteLine("Finally") + End Try + End Sub + + Public Shared Sub TryMultipleCatch() + Try + Console.WriteLine("Try") + Catch ex As FileNotFoundException + Console.WriteLine(ex.FileName) + Catch ex As IOException + Console.WriteLine(ex.Message) + Catch + Console.WriteLine("Catch") + End Try + End Sub + + Public Shared Sub TryMultipleCatchFinally() + Try + Console.WriteLine("Try") + Catch ex As FileNotFoundException + Console.WriteLine(ex.FileName) + Catch ex As IOException + Console.WriteLine(ex.Message) + Finally + Console.WriteLine("Finally") + End Try + End Sub + + Public Shared Sub TryMultipleCatchWhen() + Try + Console.WriteLine("Try") + Catch ex As IOException When Condition() + Console.WriteLine(ex.Message) + Catch When Condition() + Console.WriteLine("Catch When") + Catch ex As Exception + Console.WriteLine(ex.Message) + End Try + End Sub + + Public Shared Sub EmptyTryFinally() + Try + Finally + Console.WriteLine("Finally") + End Try + End Sub + + Public Shared Sub EmptyCatch() + Try + Console.WriteLine("Try") + Catch + End Try + End Sub + + Public Shared Sub EmptyFinally() + Try + Console.WriteLine("Try") + Catch ex As Exception + Console.WriteLine(ex.Message) + Finally + End Try + End Sub + + Public Shared Sub ExitTryInTry(b As Boolean) + Try + If b Then + Exit Try + End If + Console.WriteLine("Try") + Catch + Console.WriteLine("Catch") + End Try + Console.WriteLine("End") + End Sub + + Public Shared Sub ExitTryInCatch(b As Boolean) + Try + Console.WriteLine("Try") + Catch + If b Then + Exit Try + End If + Console.WriteLine("Catch") + End Try + Console.WriteLine("End") + End Sub + + Public Shared Sub ExitTryWithFinally(b As Boolean) + Try + If b Then + Exit Try + End If + Console.WriteLine("Try") + Finally + Console.WriteLine("Finally") + End Try + Console.WriteLine("End") + End Sub + + Public Shared Sub Rethrow() + Try + Console.WriteLine("Try") + Catch ex As Exception + Console.WriteLine(ex.Message) + Throw + End Try + End Sub + + Public Shared Sub ThrowNew() + Try + Console.WriteLine("Try") + Catch ex As Exception + Throw New InvalidOperationException("Catch", ex) + End Try + End Sub + + Public Shared Function ReturnFromTry() As Integer + Try + Return 1 + Catch + Return 2 + Finally + Console.WriteLine("Finally") + End Try + End Function + + Public Shared Function ReturnAfterTry() As Integer + Try + Console.WriteLine("Try") + Catch ex As Exception + Console.WriteLine(ex.Message) + Return -1 + End Try + Return 0 + End Function + + Public Shared Sub NestedTryInTry() + Try + Try + Console.WriteLine("Inner Try") + Catch ex As IOException + Console.WriteLine(ex.Message) + End Try + Catch ex As Exception + Console.WriteLine(ex.Message) + End Try + End Sub + + Public Shared Sub NestedTryInCatch() + Try + Console.WriteLine("Try") + Catch ex As Exception + Try + Console.WriteLine(ex.Message) + Catch ex2 As Exception + Console.WriteLine(ex2.Message) + End Try + End Try + End Sub + + Public Shared Sub NestedTryInFinally() + Try + Console.WriteLine("Try") + Finally + Try + Console.WriteLine("Inner Try") + Catch + Console.WriteLine("Inner Catch") + End Try + End Try + End Sub + + Public Shared Sub TryInLoop() + For i = 0 To 9 + Try + If i = 5 Then + Continue For + End If + If i = 8 Then + Exit For + End If + Console.WriteLine(i) + Catch + Console.WriteLine("Catch") + Finally + Console.WriteLine("Finally") + End Try + Next + End Sub +End Class diff --git a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs index f608cca35..3b3bcd78b 100644 --- a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs @@ -151,6 +151,13 @@ namespace ICSharpCode.Decompiler.Tests await Run(options: options | CompilerOptions.Library); } + [Test] + public async Task VBOnError([ValueSource(nameof(defaultOptions))] CompilerOptions options) + { + IgnoreIfVbRuntimeSubstituted(options); + await Run(options: options | CompilerOptions.Library); + } + [Test] public async Task VBPropertiesTest([ValueSource(nameof(defaultOptions))] CompilerOptions options) { @@ -170,6 +177,13 @@ namespace ICSharpCode.Decompiler.Tests await Run(options: options | CompilerOptions.Library); } + [Test] + public async Task VBTryCatchFinally([ValueSource(nameof(defaultOptions))] CompilerOptions options) + { + IgnoreIfVbRuntimeSubstituted(options); + await Run(options: options | CompilerOptions.Library); + } + [Test] public async Task YieldReturn([ValueSource(nameof(defaultOptions))] CompilerOptions options) {