diff --git a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index cab334432..3235a08ed 100644 --- a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -397,7 +397,7 @@ namespace ICSharpCode.Decompiler.Ast ace.Initializer.Elements.AddRange(args); return ace; } - case ILCode.Ldlen: return arg1.Member("Length"); + case ILCode.Ldlen: return arg1.Member("Length"); case ILCode.Ldelem_I: case ILCode.Ldelem_I1: case ILCode.Ldelem_I2: @@ -906,14 +906,21 @@ namespace ICSharpCode.Decompiler.Ast target = ((DirectionExpression)target).Expression; target.Remove(); // detach from DirectionExpression } - if (cecilMethodDef != null && cecilMethodDef.DeclaringType.IsInterface) { - 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)); + + if (cecilMethodDef != null) { + // convert null.ToLower() to ((string)null).ToLower() + if (target is NullReferenceExpression) + target = target.CastTo(AstBuilder.ConvertType(cecilMethod.DeclaringType)); + + if (cecilMethodDef.DeclaringType.IsInterface) { + 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)); + } } } } diff --git a/ICSharpCode.Decompiler/Ast/Transforms/IntroduceExtensionMethods.cs b/ICSharpCode.Decompiler/Ast/Transforms/IntroduceExtensionMethods.cs index c42677d74..9f05285ec 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/IntroduceExtensionMethods.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/IntroduceExtensionMethods.cs @@ -45,7 +45,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms if (d != null) { foreach (var ca in d.CustomAttributes) { 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()) { // 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