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 @@ -501,7 +501,7 @@ namespace Decompiler
case Code.Endfinally: return null;
case Code.Initblk: 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.Ldarg:
if (methodDef.HasThis && ((ParameterDefinition)operand).Index < 0) {

6
ICSharpCode.Decompiler/Ast/NRefactoryExtensions.cs

@ -14,5 +14,11 @@ namespace Decompiler @@ -14,5 +14,11 @@ namespace Decompiler
node.AddAnnotation(annotation);
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 @@ @@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.PatternMatching;
namespace Decompiler.Transforms
{
@ -75,6 +76,18 @@ namespace Decompiler.Transforms @@ -75,6 +76,18 @@ namespace Decompiler.Transforms
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)
{
BinaryOperatorType op = binaryOperatorExpression.Operator;
@ -94,7 +107,21 @@ namespace Decompiler.Transforms @@ -94,7 +107,21 @@ namespace Decompiler.Transforms
binaryOperatorExpression.ReplaceWith(uoe);
return uoe.AcceptVisitor(this, data);
} 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)

Loading…
Cancel
Save