diff --git a/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/ICSharpCode.Decompiler/Ast/AstBuilder.cs index f0cbdcdcb..498a3e230 100644 --- a/ICSharpCode.Decompiler/Ast/AstBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstBuilder.cs @@ -256,7 +256,7 @@ namespace ICSharpCode.Decompiler.Ast transform.Run(astCompileUnit); } - string CleanName(string name) + internal static string CleanName(string name) { int pos = name.LastIndexOf('`'); if (pos >= 0) diff --git a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs index 862856915..cb9581624 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs @@ -41,6 +41,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms if (context.Settings.AutomaticEvents) TransformAutomaticEvents(compilationUnit); + TransformDestructor(compilationUnit); TransformTryCatchFinally(compilationUnit); } @@ -654,6 +655,38 @@ namespace ICSharpCode.Decompiler.Ast.Transforms } #endregion + #region Destructor + static readonly MethodDeclaration destructorPattern = new MethodDeclaration { + Attributes = { new Repeat(new AnyNode()) }, + Modifiers = Modifiers.Any, + ReturnType = new PrimitiveType("void"), + Name = "Finalize", + Body = new BlockStatement { + new TryCatchStatement { + TryBlock = new AnyNode("body"), + FinallyBlock = new BlockStatement { + new BaseReferenceExpression().Invoke("Finalize") + } + } + } + }; + + void TransformDestructor(AstNode compilationUnit) + { + foreach (var methodDef in compilationUnit.Descendants.OfType()) { + Match m = destructorPattern.Match(methodDef); + if (m != null) { + DestructorDeclaration dd = new DestructorDeclaration(); + methodDef.Attributes.MoveTo(dd.Attributes); + dd.Modifiers = methodDef.Modifiers & ~(Modifiers.Protected | Modifiers.Override); + dd.Body = m.Get("body").Single().Detach(); + dd.Name = AstBuilder.CleanName(context.CurrentType.Name); + methodDef.ReplaceWith(dd); + } + } + } + #endregion + #region Try-Catch-Finally static readonly TryCatchStatement tryCatchFinallyPattern = new TryCatchStatement { TryBlock = new BlockStatement { diff --git a/ICSharpCode.Decompiler/Tests/UnsafeCode.cs b/ICSharpCode.Decompiler/Tests/UnsafeCode.cs index 03b8b6ab5..83c292400 100644 --- a/ICSharpCode.Decompiler/Tests/UnsafeCode.cs +++ b/ICSharpCode.Decompiler/Tests/UnsafeCode.cs @@ -74,4 +74,9 @@ public class UnsafeCode } return PointerReferenceExpression((double*)a); } + + unsafe ~UnsafeCode() + { + PassPointerAsRefParameter(NullPointer); + } }