Skip to content

Commit

Permalink
Fix decompilation of as/is operators.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgrunwald committed Feb 19, 2011
1 parent 1ee35ab commit 735dec5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
2 changes: 1 addition & 1 deletion ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ AstNode TransformByteCode_Internal(ILExpression byteCode, List<Ast.Expression> a
case Code.Endfinally: return null; case Code.Endfinally: return null;
case Code.Initblk: throw new NotImplementedException(); case Code.Initblk: throw new NotImplementedException();
case Code.Initobj: throw new NotImplementedException(); case Code.Initobj: throw new NotImplementedException();
case Code.Isinst: return arg1.IsType(AstBuilder.ConvertType((Cecil.TypeReference)operand)); case Code.Isinst: return arg1.CastAs(AstBuilder.ConvertType((Cecil.TypeReference)operand));
case Code.Jmp: throw new NotImplementedException(); case Code.Jmp: throw new NotImplementedException();
case Code.Ldarg: case Code.Ldarg:
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) { if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) {
Expand Down
6 changes: 6 additions & 0 deletions ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,5 +14,11 @@ public static T WithAnnotation<T>(this T node, object annotation) where T : AstN
node.AddAnnotation(annotation); node.AddAnnotation(annotation);
return node; return node;
} }

public static T Detach<T>(this T node) where T : AstNode
{
node.Remove();
return node;
}
} }
} }
31 changes: 29 additions & 2 deletions ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

using System.Linq;
using ICSharpCode.NRefactory.CSharp; using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching;


namespace Decompiler.Transforms namespace Decompiler.Transforms
{ {
Expand Down Expand Up @@ -75,6 +76,18 @@ unary.Expression is UnaryOperatorExpression &&
return base.VisitUnaryOperatorExpression(unary, data); return base.VisitUnaryOperatorExpression(unary, data);
} }


readonly static AstNode asCastIsNullPattern = new BinaryOperatorExpression(
new AnyNode("expr").ToExpression().CastAs(new AnyNode("type").ToType()),
BinaryOperatorType.Equality,
new NullReferenceExpression()
);

readonly static AstNode asCastIsNotNullPattern = new BinaryOperatorExpression(
new AnyNode("expr").ToExpression().CastAs(new AnyNode("type").ToType()),
BinaryOperatorType.InEquality,
new NullReferenceExpression()
);

public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
{ {
BinaryOperatorType op = binaryOperatorExpression.Operator; BinaryOperatorType op = binaryOperatorExpression.Operator;
Expand All @@ -94,7 +107,21 @@ public override object VisitBinaryOperatorExpression(BinaryOperatorExpression bi
binaryOperatorExpression.ReplaceWith(uoe); binaryOperatorExpression.ReplaceWith(uoe);
return uoe.AcceptVisitor(this, data); return uoe.AcceptVisitor(this, data);
} else { } else {
return base.VisitBinaryOperatorExpression(binaryOperatorExpression, data); bool negate = false;
Match m = asCastIsNotNullPattern.Match(binaryOperatorExpression);
if (m == null) {
m = asCastIsNullPattern.Match(binaryOperatorExpression);
negate = true;
}
if (m != null) {
Expression expr = ((Expression)m["expr"].Single()).Detach().IsType((AstType)m["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) void IAstTransform.Run(AstNode node)
Expand Down

0 comments on commit 735dec5

Please sign in to comment.