Browse Source

Fix decompilation of as/is operators.

pull/37/head
Daniel Grunwald 15 years ago
parent
commit
735dec5491
  1. 2
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 6
      ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs
  3. 31
      ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -501,7 +501,7 @@ namespace Decompiler
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) {

6
ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs

@ -14,5 +14,11 @@ namespace Decompiler
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
ICSharpCode.Decompiler/Ast/Transforms/PushNegation.cs

@ -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
{ {
@ -75,6 +76,18 @@ namespace Decompiler.Transforms
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;
@ -94,7 +107,21 @@ namespace Decompiler.Transforms
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)

Loading…
Cancel
Save