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 @@ -10,10 +10,12 @@ namespace ICSharpCode.Decompiler.Ast
public class TypeInformation
{
public readonly TypeReference InferredType;
public readonly TypeReference ExpectedType;
public TypeInformation(TypeReference inferredType)
public TypeInformation(TypeReference inferredType, TypeReference expectedType)
{
this.InferredType = inferredType;
this.ExpectedType = expectedType;
}
}

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

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

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

@ -180,8 +180,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -180,8 +180,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
foreach (AstNode node in body.Descendants) {
if (node is ThisReferenceExpression)
node.ReplaceWith(target.Clone());
}
Expression replacement;
if (isLambda) {
LambdaExpression lambda = new LambdaExpression();
lambda.CopyAnnotationsFrom(ame);
@ -189,13 +189,32 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -189,13 +189,32 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression;
returnExpr.Remove();
lambda.Body = returnExpr;
objectCreateExpression.ReplaceWith(lambda);
replacement = lambda;
} else {
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;
}
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)
{

Loading…
Cancel
Save