diff --git a/src/AstBuilder.cs b/src/AstBuilder.cs index 216a69a44..5db7367f4 100644 --- a/src/AstBuilder.cs +++ b/src/AstBuilder.cs @@ -22,6 +22,8 @@ namespace Decompiler { CSharpOutputVisitor csOutVisitor = new CSharpOutputVisitor(); + astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null); + astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.SimplifyTypeReferences(), null); diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs index b75b45c0e..bb5cb9ff0 100644 --- a/src/AstMetodBodyBuilder.cs +++ b/src/AstMetodBodyBuilder.cs @@ -116,6 +116,7 @@ namespace Decompiler // Sugested content trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody)); ifElseStmt.TrueStatement.Add(trueBlock); + trueBlock.Parent = ifElseStmt; Ast.MyBlockStatement falseBlock = new Ast.MyBlockStatement(); // The block entry code @@ -123,6 +124,7 @@ namespace Decompiler // Sugested content falseBlock.Children.AddRange(TransformNode(conditionalNode.FalseBody)); ifElseStmt.FalseStatement.Add(falseBlock); + falseBlock.Parent = ifElseStmt; } else { throw new Exception("Bad node type"); } diff --git a/src/Transforms/Ast/RemoveDeadLabels.cs b/src/Transforms/Ast/RemoveDeadLabels.cs index 18b742d91..99a251ac8 100644 --- a/src/Transforms/Ast/RemoveDeadLabels.cs +++ b/src/Transforms/Ast/RemoveDeadLabels.cs @@ -1,5 +1,6 @@ using System; +using Ast = ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Visitors; diff --git a/src/Transforms/Ast/RemoveGotos.cs b/src/Transforms/Ast/RemoveGotos.cs index 7290b36eb..cea72cfdb 100644 --- a/src/Transforms/Ast/RemoveGotos.cs +++ b/src/Transforms/Ast/RemoveGotos.cs @@ -7,6 +7,49 @@ namespace Decompiler.Transforms.Ast { public class RemoveGotos: AbstractAstTransformer { + public override object VisitBlockStatement(BlockStatement blockStatement, object data) + { + base.VisitBlockStatement(blockStatement, data); + + // Remove redundant jump at the end of block + INode lastStmt = blockStatement.Children[blockStatement.Children.Count - 1]; + // End of loop + if (lastStmt is ContinueStatement && + blockStatement.Parent is DoLoopStatement) + { + blockStatement.Children.Remove(lastStmt); + return null; + } + // End of method + if (lastStmt is ReturnStatement && + blockStatement.Parent is MethodDeclaration && + ((ReturnStatement)lastStmt).Expression.IsNull) + { + blockStatement.Children.Remove(lastStmt); + return null; + } + // End of if body + if (lastStmt is GotoStatement && + blockStatement.Parent is IfElseStatement) + { + INode ifParent = blockStatement.Parent.Parent; + int ifIndex = ifParent.Children.IndexOf(blockStatement.Parent); + if (ifIndex + 1 < ifParent.Children.Count) { + MyLabelStatement nextNodeAsLabel = ifParent.Children[ifIndex + 1] as MyLabelStatement; + if (nextNodeAsLabel != null) { + if (nextNodeAsLabel.NodeLabel == ((MyGotoStatement)lastStmt).NodeLabel) { + ((MyGotoStatement)lastStmt).NodeLabel.ReferenceCount--; + blockStatement.Children.Remove(lastStmt); + } + } + } + + return null; + } + + return null; + } + public override object VisitGotoStatement(GotoStatement gotoStatement, object data) { MyGotoStatement myGoto = (MyGotoStatement)gotoStatement; diff --git a/src/Transforms/Ast/SimplifyTypeReferences.cs b/src/Transforms/Ast/SimplifyTypeReferences.cs index 5be0b9a06..cb76fd9c9 100644 --- a/src/Transforms/Ast/SimplifyTypeReferences.cs +++ b/src/Transforms/Ast/SimplifyTypeReferences.cs @@ -1,5 +1,6 @@ using System; +using Ast = ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Visitors;