Browse Source

Simplify "x == false" to "!x" in PushNegation.

pull/37/head
Daniel Grunwald 15 years ago
parent
commit
d6f94bbc75
  1. 74
      ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs
  2. 4
      ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs

74
ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs

@ -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;
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 (sucessful) {
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);
}
}
}
}

4
ICSharpCode.Decompiler/Ast/Transforms/TransformationPipeline.cs

@ -12,9 +12,10 @@ namespace Decompiler.Transforms @@ -12,9 +12,10 @@ namespace Decompiler.Transforms
public static IAstVisitor<object, object>[] CreatePipeline(CancellationToken cancellationToken)
{
return new IAstVisitor<object, object>[] {
new PushNegation(),
new DelegateConstruction() { CancellationToken = cancellationToken },
new ConvertConstructorCallIntoInitializer(),
new ReplaceMethodCallsWithOperators()
new ReplaceMethodCallsWithOperators(),
};
}
@ -33,7 +34,6 @@ namespace Decompiler.Transforms @@ -33,7 +34,6 @@ namespace Decompiler.Transforms
}
if (Options.ReduceAstOther) {
node.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null);
node.AcceptVisitor(new Transforms.Ast.PushNegation(), null);
}
}

Loading…
Cancel
Save