diff --git a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs index 33786fcc2..862856915 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs @@ -40,6 +40,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms TransformAutomaticProperties(compilationUnit); if (context.Settings.AutomaticEvents) TransformAutomaticEvents(compilationUnit); + + TransformTryCatchFinally(compilationUnit); } /// @@ -652,6 +654,33 @@ namespace ICSharpCode.Decompiler.Ast.Transforms } #endregion + #region Try-Catch-Finally + static readonly TryCatchStatement tryCatchFinallyPattern = new TryCatchStatement { + TryBlock = new BlockStatement { + new TryCatchStatement { + TryBlock = new AnyNode(), + CatchClauses = { new Repeat(new AnyNode()) } + } + }, + FinallyBlock = new AnyNode() + }; + + /// + /// Simplify nested 'try { try {} catch {} } finally {}'. + /// This transformation must run after the using/lock tranformations. + /// + void TransformTryCatchFinally(AstNode compilationUnit) + { + foreach (var tryFinally in compilationUnit.Descendants.OfType()) { + if (tryCatchFinallyPattern.Match(tryFinally) != null) { + TryCatchStatement tryCatch = (TryCatchStatement)tryFinally.TryBlock.Statements.Single(); + tryFinally.TryBlock = tryCatch.TryBlock.Detach(); + tryCatch.CatchClauses.MoveTo(tryFinally.CatchClauses); + } + } + } + #endregion + #region Pattern Matching Helpers sealed class TypePattern : Pattern { diff --git a/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs b/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs index 21b259126..65717b2bb 100644 --- a/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs +++ b/ICSharpCode.Decompiler/Tests/ExceptionHandling.cs @@ -22,4 +22,28 @@ public class ExceptionHandling throw; } } + + public void TryCatchFinally() + { + try { + Console.WriteLine("Try"); + } catch (Exception ex) { + Console.WriteLine(ex.Message); + } finally { + Console.WriteLine("Finally"); + } + } + + public void TryCatchMultipleHandlers() + { + try { + Console.WriteLine("Try"); + } catch (InvalidOperationException ex) { + Console.WriteLine(ex.Message); + } catch (Exception ex) { + Console.WriteLine(ex.Message); + } catch { + Console.WriteLine("other"); + } + } }