diff options
Diffstat (limited to 'ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs')
-rw-r--r-- | ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs | 164 |
1 files changed, 0 insertions, 164 deletions
diff --git a/ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs b/ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs deleted file mode 100644 index 193c5e69..00000000 --- a/ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Linq; -using ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.PatternMatching; - -namespace ICSharpCode.Decompiler.Ast.Transforms -{ - public class PushNegation: DepthFirstAstVisitor<object, object>, IAstTransform - { - sealed class LiftedOperator { } - /// <summary> - /// Annotation for lifted operators that cannot be transformed by PushNegation - /// </summary> - public static readonly object LiftedOperatorAnnotation = new LiftedOperator(); - - public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unary, object data) - { - // lifted operators can't be transformed - if (unary.Annotation<LiftedOperator>() != null || unary.Expression.Annotation<LiftedOperator>() != null) - return base.VisitUnaryOperatorExpression(unary, data); - - // Remove double negation - // !!a - if (unary.Operator == UnaryOperatorType.Not && - unary.Expression is UnaryOperatorExpression && - (unary.Expression as UnaryOperatorExpression).Operator == UnaryOperatorType.Not) - { - AstNode newNode = (unary.Expression as UnaryOperatorExpression).Expression; - unary.ReplaceWith(newNode); - return newNode.AcceptVisitor(this, data); - } - - // Push through binary operation - // !((a) op (b)) - BinaryOperatorExpression binaryOp = unary.Expression as BinaryOperatorExpression; - if (unary.Operator == UnaryOperatorType.Not && binaryOp != null) { - bool successful = true; - switch (binaryOp.Operator) { - 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); - } - - successful = true; - switch (binaryOp.Operator) { - case BinaryOperatorType.ConditionalAnd: - binaryOp.Operator = BinaryOperatorType.ConditionalOr; - break; - case BinaryOperatorType.ConditionalOr: - binaryOp.Operator = BinaryOperatorType.ConditionalAnd; - break; - default: - successful = false; - break; - } - if (successful) { - binaryOp.Left.ReplaceWith(e => new UnaryOperatorExpression(UnaryOperatorType.Not, e)); - binaryOp.Right.ReplaceWith(e => new UnaryOperatorExpression(UnaryOperatorType.Not, e)); - unary.ReplaceWith(binaryOp); - return binaryOp.AcceptVisitor(this, data); - } - } - return base.VisitUnaryOperatorExpression(unary, data); - } - - readonly static AstNode asCastIsNullPattern = new BinaryOperatorExpression( - new AnyNode("expr").ToExpression().CastAs(new AnyNode("type")), - BinaryOperatorType.Equality, - new NullReferenceExpression() - ); - - readonly static AstNode asCastIsNotNullPattern = new BinaryOperatorExpression( - new AnyNode("expr").ToExpression().CastAs(new AnyNode("type")), - BinaryOperatorType.InEquality, - new NullReferenceExpression() - ); - - public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) - { - // lifted operators can't be transformed - if (binaryOperatorExpression.Annotation<LiftedOperator>() != null) - return base.VisitBinaryOperatorExpression(binaryOperatorExpression, 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.Left.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 { - bool negate = false; - Match m = asCastIsNotNullPattern.Match(binaryOperatorExpression); - if (!m.Success) { - m = asCastIsNullPattern.Match(binaryOperatorExpression); - negate = true; - } - if (m.Success) { - Expression expr = m.Get<Expression>("expr").Single().Detach().IsType(m.Get<AstType>("type").Single().Detach()); - if (negate) - expr = new UnaryOperatorExpression(UnaryOperatorType.Not, expr); - binaryOperatorExpression.ReplaceWith(expr); - return expr.AcceptVisitor(this, data); - } else { - return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data); - } - } - } - void IAstTransform.Run(AstNode node) - { - node.AcceptVisitor(this, null); - } - } -} |