|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
using ICSharpCode.NRefactory.CSharp; |
|
|
|
|
|
|
|
|
|
namespace Decompiler.Transforms.Ast |
|
|
|
|
namespace Decompiler.Transforms |
|
|
|
|
{ |
|
|
|
|
public class PushNegation: DepthFirstAstVisitor<object, object> |
|
|
|
|
{ |
|
|
|
@ -24,29 +24,48 @@ namespace Decompiler.Transforms.Ast
@@ -24,29 +24,48 @@ namespace Decompiler.Transforms.Ast
|
|
|
|
|
// !((a) op (b))
|
|
|
|
|
BinaryOperatorExpression binaryOp = unary.Expression as BinaryOperatorExpression; |
|
|
|
|
if (unary.Operator == UnaryOperatorType.Not && binaryOp != null) { |
|
|
|
|
bool sucessful = true; |
|
|
|
|
bool successful = true; |
|
|
|
|
switch (binaryOp.Operator) { |
|
|
|
|
case BinaryOperatorType.Equality: binaryOp.Operator = BinaryOperatorType.InEquality; break; |
|
|
|
|
case BinaryOperatorType.InEquality: binaryOp.Operator = BinaryOperatorType.Equality; break; |
|
|
|
|
// TODO: these are invalid for floats (stupid NaN)
|
|
|
|
|
case BinaryOperatorType.GreaterThan: binaryOp.Operator = BinaryOperatorType.LessThanOrEqual; break; |
|
|
|
|
case BinaryOperatorType.GreaterThanOrEqual: binaryOp.Operator = BinaryOperatorType.LessThan; break; |
|
|
|
|
case BinaryOperatorType.LessThanOrEqual: binaryOp.Operator = BinaryOperatorType.GreaterThan; break; |
|
|
|
|
case BinaryOperatorType.LessThan: binaryOp.Operator = BinaryOperatorType.GreaterThanOrEqual; break; |
|
|
|
|
default: sucessful = false; break; |
|
|
|
|
} |
|
|
|
|
if (sucessful) { |
|
|
|
|
case BinaryOperatorType.Equality: |
|
|
|
|
binaryOp.Operator = BinaryOperatorType.InEquality; |
|
|
|
|
break; |
|
|
|
|
case BinaryOperatorType.InEquality: |
|
|
|
|
binaryOp.Operator = BinaryOperatorType.Equality; |
|
|
|
|
break; |
|
|
|
|
case BinaryOperatorType.GreaterThan: // TODO: these are invalid for floats (stupid NaN)
|
|
|
|
|
binaryOp.Operator = BinaryOperatorType.LessThanOrEqual; |
|
|
|
|
break; |
|
|
|
|
case BinaryOperatorType.GreaterThanOrEqual: |
|
|
|
|
binaryOp.Operator = BinaryOperatorType.LessThan; |
|
|
|
|
break; |
|
|
|
|
case BinaryOperatorType.LessThanOrEqual: |
|
|
|
|
binaryOp.Operator = BinaryOperatorType.GreaterThan; |
|
|
|
|
break; |
|
|
|
|
case BinaryOperatorType.LessThan: |
|
|
|
|
binaryOp.Operator = BinaryOperatorType.GreaterThanOrEqual; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
successful = false; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (successful) { |
|
|
|
|
unary.ReplaceWith(binaryOp); |
|
|
|
|
return binaryOp.AcceptVisitor(this, data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sucessful = true; |
|
|
|
|
successful = true; |
|
|
|
|
switch (binaryOp.Operator) { |
|
|
|
|
case BinaryOperatorType.ConditionalAnd: binaryOp.Operator = BinaryOperatorType.ConditionalOr; break; |
|
|
|
|
case BinaryOperatorType.ConditionalOr: binaryOp.Operator = BinaryOperatorType.ConditionalAnd; break; |
|
|
|
|
default: sucessful = false; break; |
|
|
|
|
case BinaryOperatorType.ConditionalAnd: |
|
|
|
|
binaryOp.Operator = BinaryOperatorType.ConditionalOr; |
|
|
|
|
break; |
|
|
|
|
case BinaryOperatorType.ConditionalOr: |
|
|
|
|
binaryOp.Operator = BinaryOperatorType.ConditionalAnd; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
successful = false; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (sucessful) { |
|
|
|
|
if (successful) { |
|
|
|
|
binaryOp.Left.ReplaceWith(e => new UnaryOperatorExpression(UnaryOperatorType.Not, e)); |
|
|
|
|
binaryOp.Right.ReplaceWith(e => new UnaryOperatorExpression(UnaryOperatorType.Not, e)); |
|
|
|
|
unary.ReplaceWith(binaryOp); |
|
|
|
@ -55,5 +74,28 @@ namespace Decompiler.Transforms.Ast
@@ -55,5 +74,28 @@ namespace Decompiler.Transforms.Ast
|
|
|
|
|
} |
|
|
|
|
return base.VisitUnaryOperatorExpression(unary, data); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) |
|
|
|
|
{ |
|
|
|
|
BinaryOperatorType op = binaryOperatorExpression.Operator; |
|
|
|
|
bool? rightOperand = null; |
|
|
|
|
if (binaryOperatorExpression.Right is PrimitiveExpression) |
|
|
|
|
rightOperand = ((PrimitiveExpression)binaryOperatorExpression.Right).Value as bool?; |
|
|
|
|
if (op == BinaryOperatorType.Equality && rightOperand == true || op == BinaryOperatorType.InEquality && rightOperand == false) { |
|
|
|
|
// 'b == true' or 'b != false' is useless
|
|
|
|
|
binaryOperatorExpression.AcceptVisitor(this, data); |
|
|
|
|
binaryOperatorExpression.ReplaceWith(binaryOperatorExpression.Left); |
|
|
|
|
return null; |
|
|
|
|
} else if (op == BinaryOperatorType.Equality && rightOperand == false || op == BinaryOperatorType.InEquality && rightOperand == true) { |
|
|
|
|
// 'b == false' or 'b != true' is a negation:
|
|
|
|
|
Expression left = binaryOperatorExpression.Left; |
|
|
|
|
left.Remove(); |
|
|
|
|
UnaryOperatorExpression uoe = new UnaryOperatorExpression(UnaryOperatorType.Not, left); |
|
|
|
|
binaryOperatorExpression.ReplaceWith(uoe); |
|
|
|
|
return uoe.AcceptVisitor(this, data); |
|
|
|
|
} else { |
|
|
|
|
return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|