.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

73 lines
2.7 KiB

using System;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
namespace Decompiler.Transforms.Ast
{
public class RestoreLoop: DepthFirstAstVisitor<object, object>
{
public override object VisitForStatement(ForStatement forStatement, object data)
{
base.VisitForStatement(forStatement, data);
// Restore loop initializer
if (!forStatement.Initializers.Any()) {
VariableDeclarationStatement varDeclr = forStatement.PrevSibling as VariableDeclarationStatement;
if (varDeclr != null) {
varDeclr.ReplaceWith(Statement.Null);
forStatement.Initializers.Add(varDeclr);
}
}
// Restore loop condition
if (forStatement.Condition.IsNull &&
forStatement.EmbeddedStatement.Children.Count() >= 3)
{
IfElseStatement condition = forStatement.EmbeddedStatement.Children.First() as IfElseStatement;
BreakStatement breakStmt = forStatement.EmbeddedStatement.Children.Skip(1).First() as BreakStatement;
LabelStatement label = forStatement.EmbeddedStatement.Children.Skip(2).First() as LabelStatement;
if (condition != null && breakStmt != null && label != null &&
condition.TrueStatement.Children.Count() == 1)
{
GotoStatement gotoStmt = condition.TrueStatement.FirstChild as GotoStatement;
if (gotoStmt != null && gotoStmt.Label == label.Label) {
condition.Remove();
breakStmt.Remove();
forStatement.Condition = condition.Condition;
}
}
}
// Restore loop condition (version 2)
if (forStatement.Condition.IsNull) {
IfElseStatement condition = forStatement.EmbeddedStatement.FirstChild as IfElseStatement;
if (condition != null &&
condition.TrueStatement.Children.Any() &&
condition.TrueStatement.FirstChild is BlockStatement &&
condition.TrueStatement.Children.Count() == 1 &&
condition.TrueStatement.FirstChild.FirstChild is BreakStatement &&
condition.FalseStatement.Children.Any() &&
condition.FalseStatement.FirstChild is BlockStatement &&
condition.FalseStatement.Children.Count() == 0)
{
condition.Remove();
forStatement.Condition = new UnaryOperatorExpression() { Expression = condition.Condition, Operator = UnaryOperatorType.Not };
}
}
// Restore loop iterator
if (forStatement.EmbeddedStatement.Children.Any() &&
!forStatement.Iterators.Any())
{
ExpressionStatement lastStmt = forStatement.EmbeddedStatement.LastChild as ExpressionStatement;
if (lastStmt != null &&
(lastStmt.Expression is AssignmentExpression || lastStmt.Expression is UnaryOperatorExpression)) {
lastStmt.Remove();
forStatement.Iterators.Add(lastStmt);
}
}
return null;
}
}
}