Browse Source

Use annotations to mark lifted operators that can't be transformed by PushNegation

pull/205/head
Pent Ploompuu 14 years ago
parent
commit
7c3fd3afda
  1. 7
      ICSharpCode.Decompiler/Ast/Annotations.cs
  2. 2
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 25
      ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs

7
ICSharpCode.Decompiler/Ast/Annotations.cs

@ -12,11 +12,4 @@ namespace ICSharpCode.Decompiler.Ast
this.InferredType = inferredType; this.InferredType = inferredType;
} }
} }
sealed class InvisibleParenthesis
{
InvisibleParenthesis() { }
public static readonly InvisibleParenthesis Value = new InvisibleParenthesis();
}
} }

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -815,7 +815,7 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.InitializedObject: case ILCode.InitializedObject:
return new InitializedObjectExpression(); return new InitializedObjectExpression();
case ILCode.Wrap: case ILCode.Wrap:
return new ParenthesizedExpression(arg1).WithAnnotation(InvisibleParenthesis.Value); return arg1.WithAnnotation(PushNegation.LiftedOperatorAnnotation);
case ILCode.AddressOf: case ILCode.AddressOf:
return MakeRef(arg1); return MakeRef(arg1);
case ILCode.NullableOf: case ILCode.NullableOf:

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

@ -26,8 +26,18 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
{ {
public class PushNegation: DepthFirstAstVisitor<object, object>, IAstTransform 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) 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 // Remove double negation
// !!a // !!a
if (unary.Operator == UnaryOperatorType.Not && if (unary.Operator == UnaryOperatorType.Not &&
@ -108,6 +118,10 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) 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; BinaryOperatorType op = binaryOperatorExpression.Operator;
bool? rightOperand = null; bool? rightOperand = null;
if (binaryOperatorExpression.Right is PrimitiveExpression) if (binaryOperatorExpression.Right is PrimitiveExpression)
@ -146,16 +160,5 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
{ {
node.AcceptVisitor(this, null); node.AcceptVisitor(this, null);
} }
public override object VisitParenthesizedExpression(ParenthesizedExpression expr, object data)
{
// extra parentheses are redundant after this transformation
if(expr.Annotation<InvisibleParenthesis>() != null) {
var res = expr.Expression;
expr.ReplaceWith(res);
return res.AcceptVisitor(this, data);
}
return base.VisitParenthesizedExpression(expr, data);
}
} }
} }

Loading…
Cancel
Save