Browse Source

fix #524 - Mistake ILSpy decompile: delegate instantiation is only removed if an implicit conversion exists.

pull/488/merge
Siegfried Pammer 11 years ago
parent
commit
4a4cc2e689
  1. 4
      ICSharpCode.Decompiler/Ast/Annotations.cs
  2. 2
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 25
      ICSharpCode.Decompiler/Ast/Transforms/DelegateConstruction.cs

4
ICSharpCode.Decompiler/Ast/Annotations.cs

@ -10,10 +10,12 @@ namespace ICSharpCode.Decompiler.Ast
public class TypeInformation public class TypeInformation
{ {
public readonly TypeReference InferredType; public readonly TypeReference InferredType;
public readonly TypeReference ExpectedType;
public TypeInformation(TypeReference inferredType) public TypeInformation(TypeReference inferredType, TypeReference expectedType)
{ {
this.InferredType = inferredType; this.InferredType = inferredType;
this.ExpectedType = expectedType;
} }
} }

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -262,7 +262,7 @@ namespace ICSharpCode.Decompiler.Ast
result = node; result = node;
if (result != null) if (result != null)
result = result.WithAnnotation(new TypeInformation(expr.InferredType)); result = result.WithAnnotation(new TypeInformation(expr.InferredType, expr.ExpectedType));
if (result != null) if (result != null)
return result.WithAnnotation(ilRanges); return result.WithAnnotation(ilRanges);

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

@ -180,8 +180,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
foreach (AstNode node in body.Descendants) { foreach (AstNode node in body.Descendants) {
if (node is ThisReferenceExpression) if (node is ThisReferenceExpression)
node.ReplaceWith(target.Clone()); node.ReplaceWith(target.Clone());
} }
Expression replacement;
if (isLambda) { if (isLambda) {
LambdaExpression lambda = new LambdaExpression(); LambdaExpression lambda = new LambdaExpression();
lambda.CopyAnnotationsFrom(ame); lambda.CopyAnnotationsFrom(ame);
@ -189,13 +189,32 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression; Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression;
returnExpr.Remove(); returnExpr.Remove();
lambda.Body = returnExpr; lambda.Body = returnExpr;
objectCreateExpression.ReplaceWith(lambda); replacement = lambda;
} else { } else {
ame.Body = body; ame.Body = body;
objectCreateExpression.ReplaceWith(ame); replacement = ame;
}
var expectedType = objectCreateExpression.Annotation<TypeInformation>().ExpectedType.Resolve();
if (expectedType != null && !IsDelegate(expectedType)) {
var simplifiedDelegateCreation = (ObjectCreateExpression)objectCreateExpression.Clone();
simplifiedDelegateCreation.Arguments.Clear();
simplifiedDelegateCreation.Arguments.Add(replacement);
replacement = simplifiedDelegateCreation;
} }
objectCreateExpression.ReplaceWith(replacement);
return true; return true;
} }
static bool IsDelegate(TypeDefinition type)
{
if (type.BaseType != null && type.BaseType.Namespace == "System") {
if (type.BaseType.Name == "MulticastDelegate")
return true;
if (type.BaseType.Name == "Delegate" && type.Name != "MulticastDelegate")
return true;
}
return false;
}
internal static bool IsPotentialClosure(DecompilerContext context, TypeDefinition potentialDisplayClass) internal static bool IsPotentialClosure(DecompilerContext context, TypeDefinition potentialDisplayClass)
{ {

Loading…
Cancel
Save