Browse Source

fix #167 - Incorrect decompilation of null as extension method this parameter

pull/252/merge
Siegfried Pammer 14 years ago
parent
commit
beff26761e
  1. 25
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 6
      ICSharpCode.Decompiler/Ast/Transforms/IntroduceExtensionMethods.cs

25
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -397,7 +397,7 @@ namespace ICSharpCode.Decompiler.Ast
ace.Initializer.Elements.AddRange(args); ace.Initializer.Elements.AddRange(args);
return ace; return ace;
} }
case ILCode.Ldlen: return arg1.Member("Length"); case ILCode.Ldlen: return arg1.Member("Length");
case ILCode.Ldelem_I: case ILCode.Ldelem_I:
case ILCode.Ldelem_I1: case ILCode.Ldelem_I1:
case ILCode.Ldelem_I2: case ILCode.Ldelem_I2:
@ -906,14 +906,21 @@ namespace ICSharpCode.Decompiler.Ast
target = ((DirectionExpression)target).Expression; target = ((DirectionExpression)target).Expression;
target.Remove(); // detach from DirectionExpression target.Remove(); // detach from DirectionExpression
} }
if (cecilMethodDef != null && cecilMethodDef.DeclaringType.IsInterface) {
TypeReference tr = byteCode.Arguments[0].InferredType; if (cecilMethodDef != null) {
if (tr != null) { // convert null.ToLower() to ((string)null).ToLower()
TypeDefinition td = tr.Resolve(); if (target is NullReferenceExpression)
if (td != null && !td.IsInterface) { target = target.CastTo(AstBuilder.ConvertType(cecilMethod.DeclaringType));
// Calling an interface method on a non-interface object:
// we need to introduce an explicit cast if (cecilMethodDef.DeclaringType.IsInterface) {
target = target.CastTo(AstBuilder.ConvertType(cecilMethod.DeclaringType)); TypeReference tr = byteCode.Arguments[0].InferredType;
if (tr != null) {
TypeDefinition td = tr.Resolve();
if (td != null && !td.IsInterface) {
// Calling an interface method on a non-interface object:
// we need to introduce an explicit cast
target = target.CastTo(AstBuilder.ConvertType(cecilMethod.DeclaringType));
}
} }
} }
} }

6
ICSharpCode.Decompiler/Ast/Transforms/IntroduceExtensionMethods.cs

@ -45,7 +45,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
if (d != null) { if (d != null) {
foreach (var ca in d.CustomAttributes) { foreach (var ca in d.CustomAttributes) {
if (ca.AttributeType.Name == "ExtensionAttribute" && ca.AttributeType.Namespace == "System.Runtime.CompilerServices") { if (ca.AttributeType.Name == "ExtensionAttribute" && ca.AttributeType.Namespace == "System.Runtime.CompilerServices") {
mre.Target = invocation.Arguments.First().Detach(); var firstArgument = invocation.Arguments.First();
if (firstArgument is NullReferenceExpression)
firstArgument = firstArgument.ReplaceWith(expr => expr.CastTo(AstBuilder.ConvertType(d.Parameters.First().ParameterType)));
else
mre.Target = firstArgument.Detach();
if (invocation.Arguments.Any()) { if (invocation.Arguments.Any()) {
// HACK: removing type arguments should be done indepently from whether a method is an extension method, // HACK: removing type arguments should be done indepently from whether a method is an extension method,
// just by testing whether the arguments can be inferred // just by testing whether the arguments can be inferred

Loading…
Cancel
Save