diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs index 419e549b5..e4da79407 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs @@ -1,4 +1,20 @@ -using System; +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il index 8b95ef8de..35cd026a6 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly org2btap +.assembly lb3mdocq { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module org2btap.dll -// MVID: {C17EE898-3151-4FD3-9C62-06322F89471A} +.module lb3mdocq.dll +// MVID: {4412C112-CBEB-40EB-BC42-5C82526C8657} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x02570000 +// Image base: 0x03060000 // =============== CLASS MEMBERS DECLARATION =================== @@ -135,13 +135,14 @@ IL_0026: ret } // end of method Generics::New - .method public hidebysig static bool IsNull(!!T t) cil managed + .method public hidebysig instance bool + IsNull(!!T t) cil managed { // Code size 15 (0xf) .maxstack 2 .locals init (bool V_0) IL_0000: nop - IL_0001: ldarg.0 + IL_0001: ldarg.1 IL_0002: box !!T IL_0007: ldnull IL_0008: ceq diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il index 9f393ac11..9f5537892 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.il @@ -10,7 +10,7 @@ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } -.assembly '4ebood3j' +.assembly sxsfxc4c { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx @@ -20,15 +20,15 @@ .hash algorithm 0x00008004 .ver 0:0:0:0 } -.module '4ebood3j.dll' -// MVID: {EFF51081-05A0-430F-B639-218464AEAF1E} +.module sxsfxc4c.dll +// MVID: {4BDFEFB1-623B-4D1C-B489-AE8EC4D00CF2} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00C40000 +// Image base: 0x02FA0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -122,11 +122,12 @@ IL_001f: ret } // end of method Generics::New - .method public hidebysig static bool IsNull(!!T t) cil managed + .method public hidebysig instance bool + IsNull(!!T t) cil managed { // Code size 10 (0xa) .maxstack 8 - IL_0000: ldarg.0 + IL_0000: ldarg.1 IL_0001: box !!T IL_0006: ldnull IL_0007: ceq diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il index d343424dc..e52e38966 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.opt.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module Generics.dll -// MVID: {A68CE966-2788-410B-9ADC-67827754D69A} +// MVID: {6515FC2D-ED0B-41CF-9FD2-8CD5192CF5A1} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x007F0000 +// Image base: 0x01880000 // =============== CLASS MEMBERS DECLARATION =================== @@ -113,11 +113,12 @@ IL_0005: ret } // end of method Generics::New - .method public hidebysig static bool IsNull(!!T t) cil managed + .method public hidebysig instance bool + IsNull(!!T t) cil managed { // Code size 10 (0xa) .maxstack 8 - IL_0000: ldarg.0 + IL_0000: ldarg.1 IL_0001: box !!T IL_0006: ldnull IL_0007: ceq diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il index 0db4d7c7a..2fcbc212e 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.roslyn.il @@ -25,14 +25,14 @@ .ver 0:0:0:0 } .module Generics.dll -// MVID: {ADEAC82A-8D93-4D9A-B37E-3FC39CBDC54B} +// MVID: {9BC41AF0-27DC-4022-8C9C-4D7039122350} .custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x007E0000 +// Image base: 0x03030000 // =============== CLASS MEMBERS DECLARATION =================== @@ -129,13 +129,14 @@ IL_000a: ret } // end of method Generics::New - .method public hidebysig static bool IsNull(!!T t) cil managed + .method public hidebysig instance bool + IsNull(!!T t) cil managed { // Code size 15 (0xf) .maxstack 2 .locals init (bool V_0) IL_0000: nop - IL_0001: ldarg.0 + IL_0001: ldarg.1 IL_0002: box !!T IL_0007: ldnull IL_0008: ceq diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs b/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs index 6b16a7273..96e9a9516 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs @@ -98,6 +98,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } } break; + case "System.Activator.CreateInstance": + if (method.TypeArguments.Count == 1 && arguments.Length == 0 && method.TypeArguments[0].Kind == TypeKind.TypeParameter) { + invocationExpression.ReplaceWith(new ObjectCreateExpression(context.TypeSystemAstBuilder.ConvertType(method.TypeArguments.First()))); + } + break; } BinaryOperatorType? bop = GetBinaryOperatorTypeFromMetadataName(method.Name); diff --git a/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs index 93812a5b2..fff964228 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs @@ -143,6 +143,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms // (a.GetValueOrDefault() == b.GetValueOrDefault()) ? (a.HasValue != b.HasValue) : true // => a != b return LiftCSharpEqualityComparison(comp, ComparisonKind.Inequality, trueInst); + } else if (IsGenericNewPattern(condition, trueInst, falseInst)) { + // (default(T) == null) ? Activator.CreateInstance() : default(T) + // => Activator.CreateInstance() + return trueInst; } } else { // Not (in)equality, but one of < <= > >=. @@ -233,6 +237,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms return null; } + private bool IsGenericNewPattern(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst) + { + // (default(T) == null) ? Activator.CreateInstance() : default(T) + return falseInst.MatchDefaultValue(out var type) && + (trueInst is Call c && c.Method.FullName == "System.Activator.CreateInstance" && c.Method.TypeArguments.Count == 1) && + type.Kind == TypeKind.TypeParameter && + condition.MatchCompEquals(out var left, out var right) && + left.MatchDefaultValue(out var type2) && + type.Equals(type2) && + right.MatchLdNull(); + } + private bool MatchThreeValuedLogicConditionPattern(ILInstruction condition, out ILVariable nullable1, out ILVariable nullable2) { // Try to match: nullable1.GetValueOrDefault() || (!nullable2.GetValueOrDefault() && !nullable1.HasValue)