From 9479e8af13d5860069c42f899f3498ca0c0fc791 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 21 Jul 2018 23:39:26 +0200 Subject: [PATCH] Support overloaded operator &&/||. --- .../CustomShortCircuitOperators.cs | 88 --- .../ICSharpCode.Decompiler.Tests.csproj | 1 + .../PrettyTestRunner.cs | 6 + .../Pretty/CustomShortCircuitOperators.cs | 171 +++++ .../Pretty/CustomShortCircuitOperators.il | 646 ++++++++++++++++ .../Pretty/CustomShortCircuitOperators.opt.il | 485 ++++++++++++ .../CustomShortCircuitOperators.opt.roslyn.il | 563 ++++++++++++++ .../CustomShortCircuitOperators.roslyn.il | 723 ++++++++++++++++++ .../CSharp/CSharpDecompiler.cs | 3 +- ICSharpCode.Decompiler/CSharp/CallBuilder.cs | 15 + .../CSharp/ExpressionBuilder.cs | 21 +- .../CSharp/Resolver/CSharpResolver.cs | 2 +- .../ICSharpCode.Decompiler.csproj | 3 +- ICSharpCode.Decompiler/IL/ILTypeExtensions.cs | 14 +- ICSharpCode.Decompiler/IL/InstructionFlags.cs | 2 +- ICSharpCode.Decompiler/IL/Instructions.cs | 191 ++++- ICSharpCode.Decompiler/IL/Instructions.tt | 18 +- ...icInstructions.cs => LogicInstructions.cs} | 20 +- .../IL/Transforms/AssignVariableNames.cs | 2 +- .../IL/Transforms/ExpressionTransforms.cs | 9 + .../IL/Transforms/ILInlining.cs | 2 + .../IL/Transforms/NullableLiftingTransform.cs | 14 +- .../Transforms/UserDefinedLogicTransform.cs | 150 ++++ 23 files changed, 3009 insertions(+), 140 deletions(-) delete mode 100644 ICSharpCode.Decompiler.Tests/CustomShortCircuitOperators.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.roslyn.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.roslyn.il rename ICSharpCode.Decompiler/IL/Instructions/{ThreeValuedLogicInstructions.cs => LogicInstructions.cs} (78%) create mode 100644 ICSharpCode.Decompiler/IL/Transforms/UserDefinedLogicTransform.cs diff --git a/ICSharpCode.Decompiler.Tests/CustomShortCircuitOperators.cs b/ICSharpCode.Decompiler.Tests/CustomShortCircuitOperators.cs deleted file mode 100644 index 5bd0ec516..000000000 --- a/ICSharpCode.Decompiler.Tests/CustomShortCircuitOperators.cs +++ /dev/null @@ -1,88 +0,0 @@ -// 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. - -using System; - -public static class CustomShortCircuitOperators -{ - // TODO: Restore base class after https://roslyn.codeplex.com/workitem/358 is fixed. - private class C - { - public static bool operator true(CustomShortCircuitOperators.C x) - { - return true; - } - - public static bool operator false(CustomShortCircuitOperators.C x) - { - return false; - } - - public static CustomShortCircuitOperators.C operator &(CustomShortCircuitOperators.C x, CustomShortCircuitOperators.C y) - { - return null; - } - - public static CustomShortCircuitOperators.C operator |(CustomShortCircuitOperators.C x, CustomShortCircuitOperators.C y) - { - return null; - } - - public static bool operator !(CustomShortCircuitOperators.C x) - { - return false; - } - - private static void Main() - { - CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); - CustomShortCircuitOperators.C c2 = new CustomShortCircuitOperators.C(); - CustomShortCircuitOperators.C c3 = c && c2; - CustomShortCircuitOperators.C c4 = c || c2; - Console.WriteLine(c3.ToString()); - Console.WriteLine(c4.ToString()); - } - - private static void Test2() - { - CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); - if (c && c) - { - Console.WriteLine(c.ToString()); - } - - if (!(c && c)) - { - Console.WriteLine(c.ToString()); - } - } - - private static void Test3() - { - CustomShortCircuitOperators.C c = new CustomShortCircuitOperators.C(); - if (c) - { - Console.WriteLine(c.ToString()); - } - if (!c) - { - Console.WriteLine(c.ToString()); - } - } - } -} \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 8946c9ecb..4af2803c0 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -69,6 +69,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index 8b64d0573..c156299b2 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -102,6 +102,12 @@ namespace ICSharpCode.Decompiler.Tests RunForLibrary(cscOptions: cscOptions); } + [Test] + public void CustomShortCircuitOperators([ValueSource("defaultOptions")] CSharpCompilerOptions cscOptions) + { + RunForLibrary(cscOptions: cscOptions); + } + [Test] public void ExceptionHandling([ValueSource("defaultOptions")] CSharpCompilerOptions cscOptions) { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.cs new file mode 100644 index 000000000..b9351b9d4 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.cs @@ -0,0 +1,171 @@ +// 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. + +using System; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators +{ + internal class BaseClass + { + public static bool operator true(BaseClass x) + { + return true; + } + + public static bool operator false(BaseClass x) + { + return false; + } + } + + internal class C : BaseClass + { + public static C operator &(C x, C y) + { + return null; + } + + public static C operator |(C x, C y) + { + return null; + } + + public static C operator !(C x) + { + return x; + } + + public static C GetC(int a) + { + return new C(); + } + + public static C LogicAnd() + { + return GetC(1) && GetC(2); + } + + public static C LogicOr() + { + return GetC(1) || GetC(2); + } + + public static C Complex() + { + return (GetC(1) || GetC(2)) && GetC(3) && !(GetC(4) || GetC(5)); + } + + private static void Main() + { + C c = new C(); + C c2 = new C(); + C c3 = c && c2; + C c4 = c || c2; + Console.WriteLine(c3.ToString()); + Console.WriteLine(c4.ToString()); + } + + private static void Test2() + { + C c = new C(); + if (c && c) { + Console.WriteLine(c.ToString()); + } + + if (!(c && c)) { + Console.WriteLine(c.ToString()); + } + } + + private static void Test3() + { + C c = new C(); + if (c) { + Console.WriteLine(c.ToString()); + } + if (!c) { + Console.WriteLine(c.ToString()); + } + } + } + + internal struct S + { + private readonly bool val; + + public S(bool val) + { + this.val = val; + } + + public static bool operator true(S x) + { + return x.val; + } + + public static bool operator false(S x) + { + return x.val; + } + + public static S operator &(S x, S y) + { + return new S(x.val & y.val); + } + + public static S operator |(S x, S y) + { + return new S(x.val | y.val); + } + + public static S operator !(S x) + { + return new S(!x.val); + } + + public static S Get(int i) + { + return new S(i > 0); + } + + public static S LogicAnd() + { + return Get(1) && Get(2); + } + + public static S LogicOr() + { + return Get(1) || Get(2); + } + + public void InConditionDetection() + { + Console.WriteLine("a"); + if (Get(1) && Get(2)) { + Console.WriteLine("b"); + } else { + Console.WriteLine("c"); + } + if (Get(1) || Get(2)) { + Console.WriteLine("d"); + } else { + Console.WriteLine("e"); + } + } + } +} \ No newline at end of file diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.il new file mode 100644 index 000000000..51011f2c8 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.il @@ -0,0 +1,646 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly CustomShortCircuitOperators +{ + .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 + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CustomShortCircuitOperators.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + extends [mscorlib]System.Object +{ + .method public hidebysig specialname static + bool op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method BaseClass::op_True + + .method public hidebysig specialname static + bool op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method BaseClass::op_False + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method BaseClass::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + extends ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass +{ + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method C::op_BitwiseAnd + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method C::op_BitwiseOr + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method C::op_LogicalNot + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + GetC(int32 a) cil managed + { + // Code size 11 (0xb) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method C::GetC + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicAnd() cil managed + { + // Code size 31 (0x1f) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0007: dup + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: brtrue.s IL_001a + + IL_000f: ldc.i4.2 + IL_0010: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0015: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001a: stloc.0 + IL_001b: br.s IL_001d + + IL_001d: ldloc.0 + IL_001e: ret + } // end of method C::LogicAnd + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicOr() cil managed + { + // Code size 31 (0x1f) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0007: dup + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: brtrue.s IL_001a + + IL_000f: ldc.i4.2 + IL_0010: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0015: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001a: stloc.0 + IL_001b: br.s IL_001d + + IL_001d: ldloc.0 + IL_001e: ret + } // end of method C::LogicOr + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + Complex() cil managed + { + // Code size 93 (0x5d) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0007: dup + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: brtrue.s IL_001a + + IL_000f: ldc.i4.2 + IL_0010: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0015: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001a: dup + IL_001b: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0020: brtrue.s IL_002d + + IL_0022: ldc.i4.3 + IL_0023: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0028: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_002d: dup + IL_002e: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0033: brtrue.s IL_0058 + + IL_0035: ldc.i4.4 + IL_0036: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_003b: dup + IL_003c: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0041: brtrue.s IL_004e + + IL_0043: ldc.i4.5 + IL_0044: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0049: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_004e: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0053: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0058: stloc.0 + IL_0059: br.s IL_005b + + IL_005b: ldloc.0 + IL_005c: ret + } // end of method C::Complex + + .method private hidebysig static void Main() cil managed + { + // Code size 70 (0x46) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_2, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_3) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_000c: stloc.1 + IL_000d: ldloc.0 + IL_000e: dup + IL_000f: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0014: brtrue.s IL_001c + + IL_0016: ldloc.1 + IL_0017: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001c: stloc.2 + IL_001d: ldloc.0 + IL_001e: dup + IL_001f: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0024: brtrue.s IL_002c + + IL_0026: ldloc.1 + IL_0027: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_002c: stloc.3 + IL_002d: ldloc.2 + IL_002e: callvirt instance string [mscorlib]System.Object::ToString() + IL_0033: call void [mscorlib]System.Console::WriteLine(string) + IL_0038: nop + IL_0039: ldloc.3 + IL_003a: callvirt instance string [mscorlib]System.Object::ToString() + IL_003f: call void [mscorlib]System.Console::WriteLine(string) + IL_0044: nop + IL_0045: ret + } // end of method C::Main + + .method private hidebysig static void Test2() cil managed + { + // Code size 95 (0x5f) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + bool V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: dup + IL_0009: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000e: brtrue.s IL_0016 + + IL_0010: ldloc.0 + IL_0011: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0016: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_001b: ldc.i4.0 + IL_001c: ceq + IL_001e: stloc.1 + IL_001f: ldloc.1 + IL_0020: brtrue.s IL_0030 + + IL_0022: nop + IL_0023: ldloc.0 + IL_0024: callvirt instance string [mscorlib]System.Object::ToString() + IL_0029: call void [mscorlib]System.Console::WriteLine(string) + IL_002e: nop + IL_002f: nop + IL_0030: ldloc.0 + IL_0031: dup + IL_0032: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0037: brtrue.s IL_003f + + IL_0039: ldloc.0 + IL_003a: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_003f: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0044: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0049: ldc.i4.0 + IL_004a: ceq + IL_004c: stloc.1 + IL_004d: ldloc.1 + IL_004e: brtrue.s IL_005e + + IL_0050: nop + IL_0051: ldloc.0 + IL_0052: callvirt instance string [mscorlib]System.Object::ToString() + IL_0057: call void [mscorlib]System.Console::WriteLine(string) + IL_005c: nop + IL_005d: nop + IL_005e: ret + } // end of method C::Test2 + + .method private hidebysig static void Test3() cil managed + { + // Code size 67 (0x43) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + bool V_1) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: ldc.i4.0 + IL_000e: ceq + IL_0010: stloc.1 + IL_0011: ldloc.1 + IL_0012: brtrue.s IL_0022 + + IL_0014: nop + IL_0015: ldloc.0 + IL_0016: callvirt instance string [mscorlib]System.Object::ToString() + IL_001b: call void [mscorlib]System.Console::WriteLine(string) + IL_0020: nop + IL_0021: nop + IL_0022: ldloc.0 + IL_0023: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0028: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_002d: ldc.i4.0 + IL_002e: ceq + IL_0030: stloc.1 + IL_0031: ldloc.1 + IL_0032: brtrue.s IL_0042 + + IL_0034: nop + IL_0035: ldloc.0 + IL_0036: callvirt instance string [mscorlib]System.Object::ToString() + IL_003b: call void [mscorlib]System.Console::WriteLine(string) + IL_0040: nop + IL_0041: nop + IL_0042: ret + } // end of method C::Test3 + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::.ctor() + IL_0006: ret + } // end of method C::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + +.class private sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + extends [mscorlib]System.ValueType +{ + .field private initonly bool val + .method public hidebysig specialname rtspecialname + instance void .ctor(bool val) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: stfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0008: ret + } // end of method S::.ctor + + .method public hidebysig specialname static + bool op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 13 (0xd) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarga.s x + IL_0003: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method S::op_True + + .method public hidebysig specialname static + bool op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 13 (0xd) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarga.s x + IL_0003: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0008: stloc.0 + IL_0009: br.s IL_000b + + IL_000b: ldloc.0 + IL_000c: ret + } // end of method S::op_False + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 26 (0x1a) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarga.s x + IL_0003: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0008: ldarga.s y + IL_000a: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000f: and + IL_0010: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0015: stloc.0 + IL_0016: br.s IL_0018 + + IL_0018: ldloc.0 + IL_0019: ret + } // end of method S::op_BitwiseAnd + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 26 (0x1a) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarga.s x + IL_0003: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0008: ldarga.s y + IL_000a: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000f: or + IL_0010: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0015: stloc.0 + IL_0016: br.s IL_0018 + + IL_0018: ldloc.0 + IL_0019: ret + } // end of method S::op_BitwiseOr + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_LogicalNot(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 21 (0x15) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarga.s x + IL_0003: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0008: ldc.i4.0 + IL_0009: ceq + IL_000b: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0010: stloc.0 + IL_0011: br.s IL_0013 + + IL_0013: ldloc.0 + IL_0014: ret + } // end of method S::op_LogicalNot + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + Get(int32 i) cil managed + { + // Code size 15 (0xf) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: cgt + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_000a: stloc.0 + IL_000b: br.s IL_000d + + IL_000d: ldloc.0 + IL_000e: ret + } // end of method S::Get + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicAnd() cil managed + { + // Code size 31 (0x1f) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0007: dup + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000d: brtrue.s IL_001a + + IL_000f: ldc.i4.2 + IL_0010: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0015: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_001a: stloc.0 + IL_001b: br.s IL_001d + + IL_001d: ldloc.0 + IL_001e: ret + } // end of method S::LogicAnd + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicOr() cil managed + { + // Code size 31 (0x1f) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0007: dup + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000d: brtrue.s IL_001a + + IL_000f: ldc.i4.2 + IL_0010: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0015: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_001a: stloc.0 + IL_001b: br.s IL_001d + + IL_001d: ldloc.0 + IL_001e: ret + } // end of method S::LogicOr + + .method public hidebysig instance void + InConditionDetection() cil managed + { + // Code size 143 (0x8f) + .maxstack 2 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldstr "a" + IL_0006: call void [mscorlib]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.1 + IL_000d: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0012: dup + IL_0013: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0018: brtrue.s IL_0025 + + IL_001a: ldc.i4.2 + IL_001b: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0020: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0025: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_002a: ldc.i4.0 + IL_002b: ceq + IL_002d: stloc.0 + IL_002e: ldloc.0 + IL_002f: brtrue.s IL_0040 + + IL_0031: nop + IL_0032: ldstr "b" + IL_0037: call void [mscorlib]System.Console::WriteLine(string) + IL_003c: nop + IL_003d: nop + IL_003e: br.s IL_004d + + IL_0040: nop + IL_0041: ldstr "c" + IL_0046: call void [mscorlib]System.Console::WriteLine(string) + IL_004b: nop + IL_004c: nop + IL_004d: ldc.i4.1 + IL_004e: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0053: dup + IL_0054: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0059: brtrue.s IL_0066 + + IL_005b: ldc.i4.2 + IL_005c: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0061: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0066: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_006b: ldc.i4.0 + IL_006c: ceq + IL_006e: stloc.0 + IL_006f: ldloc.0 + IL_0070: brtrue.s IL_0081 + + IL_0072: nop + IL_0073: ldstr "d" + IL_0078: call void [mscorlib]System.Console::WriteLine(string) + IL_007d: nop + IL_007e: nop + IL_007f: br.s IL_008e + + IL_0081: nop + IL_0082: ldstr "e" + IL_0087: call void [mscorlib]System.Console::WriteLine(string) + IL_008c: nop + IL_008d: nop + IL_008e: ret + } // end of method S::InConditionDetection + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.il new file mode 100644 index 000000000..fc5150d56 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.il @@ -0,0 +1,485 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly CustomShortCircuitOperators.opt +{ + .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 + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CustomShortCircuitOperators.opt.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + extends [mscorlib]System.Object +{ + .method public hidebysig specialname static + bool op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } // end of method BaseClass::op_True + + .method public hidebysig specialname static + bool op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } // end of method BaseClass::op_False + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method BaseClass::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + extends ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass +{ + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method C::op_BitwiseAnd + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method C::op_BitwiseOr + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } // end of method C::op_LogicalNot + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + GetC(int32 a) cil managed + { + // Code size 6 (0x6) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: ret + } // end of method C::GetC + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicAnd() cil managed + { + // Code size 26 (0x1a) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0006: dup + IL_0007: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000c: brtrue.s IL_0019 + + IL_000e: ldc.i4.2 + IL_000f: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0014: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0019: ret + } // end of method C::LogicAnd + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicOr() cil managed + { + // Code size 26 (0x1a) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0006: dup + IL_0007: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000c: brtrue.s IL_0019 + + IL_000e: ldc.i4.2 + IL_000f: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0014: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0019: ret + } // end of method C::LogicOr + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + Complex() cil managed + { + // Code size 88 (0x58) + .maxstack 3 + IL_0000: ldc.i4.1 + IL_0001: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0006: dup + IL_0007: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000c: brtrue.s IL_0019 + + IL_000e: ldc.i4.2 + IL_000f: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0014: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0019: dup + IL_001a: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_001f: brtrue.s IL_002c + + IL_0021: ldc.i4.3 + IL_0022: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0027: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_002c: dup + IL_002d: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0032: brtrue.s IL_0057 + + IL_0034: ldc.i4.4 + IL_0035: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_003a: dup + IL_003b: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0040: brtrue.s IL_004d + + IL_0042: ldc.i4.5 + IL_0043: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0048: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_004d: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0052: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0057: ret + } // end of method C::Complex + + .method private hidebysig static void Main() cil managed + { + // Code size 67 (0x43) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_2, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_3) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: stloc.0 + IL_0006: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_000b: stloc.1 + IL_000c: ldloc.0 + IL_000d: dup + IL_000e: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0013: brtrue.s IL_001b + + IL_0015: ldloc.1 + IL_0016: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001b: stloc.2 + IL_001c: ldloc.0 + IL_001d: dup + IL_001e: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0023: brtrue.s IL_002b + + IL_0025: ldloc.1 + IL_0026: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_002b: stloc.3 + IL_002c: ldloc.2 + IL_002d: callvirt instance string [mscorlib]System.Object::ToString() + IL_0032: call void [mscorlib]System.Console::WriteLine(string) + IL_0037: ldloc.3 + IL_0038: callvirt instance string [mscorlib]System.Object::ToString() + IL_003d: call void [mscorlib]System.Console::WriteLine(string) + IL_0042: ret + } // end of method C::Main + + .method private hidebysig static void Test2() cil managed + { + // Code size 78 (0x4e) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: dup + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: brtrue.s IL_0015 + + IL_000f: ldloc.0 + IL_0010: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0015: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_001a: brfalse.s IL_0027 + + IL_001c: ldloc.0 + IL_001d: callvirt instance string [mscorlib]System.Object::ToString() + IL_0022: call void [mscorlib]System.Console::WriteLine(string) + IL_0027: ldloc.0 + IL_0028: dup + IL_0029: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_002e: brtrue.s IL_0036 + + IL_0030: ldloc.0 + IL_0031: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0036: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_003b: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0040: brfalse.s IL_004d + + IL_0042: ldloc.0 + IL_0043: callvirt instance string [mscorlib]System.Object::ToString() + IL_0048: call void [mscorlib]System.Console::WriteLine(string) + IL_004d: ret + } // end of method C::Test2 + + .method private hidebysig static void Test3() cil managed + { + // Code size 50 (0x32) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000c: brfalse.s IL_0019 + + IL_000e: ldloc.0 + IL_000f: callvirt instance string [mscorlib]System.Object::ToString() + IL_0014: call void [mscorlib]System.Console::WriteLine(string) + IL_0019: ldloc.0 + IL_001a: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001f: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0024: brfalse.s IL_0031 + + IL_0026: ldloc.0 + IL_0027: callvirt instance string [mscorlib]System.Object::ToString() + IL_002c: call void [mscorlib]System.Console::WriteLine(string) + IL_0031: ret + } // end of method C::Test3 + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::.ctor() + IL_0006: ret + } // end of method C::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + +.class private sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + extends [mscorlib]System.ValueType +{ + .field private initonly bool val + .method public hidebysig specialname rtspecialname + instance void .ctor(bool val) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ret + } // end of method S::.ctor + + .method public hidebysig specialname static + bool op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarga.s x + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ret + } // end of method S::op_True + + .method public hidebysig specialname static + bool op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarga.s x + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ret + } // end of method S::op_False + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarga.s x + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ldarga.s y + IL_0009: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000e: and + IL_000f: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0014: ret + } // end of method S::op_BitwiseAnd + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarga.s x + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ldarga.s y + IL_0009: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000e: or + IL_000f: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0014: ret + } // end of method S::op_BitwiseOr + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_LogicalNot(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 16 (0x10) + .maxstack 8 + IL_0000: ldarga.s x + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ldc.i4.0 + IL_0008: ceq + IL_000a: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_000f: ret + } // end of method S::op_LogicalNot + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + Get(int32 i) cil managed + { + // Code size 10 (0xa) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: cgt + IL_0004: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0009: ret + } // end of method S::Get + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicAnd() cil managed + { + // Code size 26 (0x1a) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0006: dup + IL_0007: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000c: brtrue.s IL_0019 + + IL_000e: ldc.i4.2 + IL_000f: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0014: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0019: ret + } // end of method S::LogicAnd + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicOr() cil managed + { + // Code size 26 (0x1a) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0006: dup + IL_0007: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000c: brtrue.s IL_0019 + + IL_000e: ldc.i4.2 + IL_000f: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0014: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0019: ret + } // end of method S::LogicOr + + .method public hidebysig instance void + InConditionDetection() cil managed + { + // Code size 118 (0x76) + .maxstack 2 + IL_0000: ldstr "a" + IL_0005: call void [mscorlib]System.Console::WriteLine(string) + IL_000a: ldc.i4.1 + IL_000b: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0010: dup + IL_0011: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0016: brtrue.s IL_0023 + + IL_0018: ldc.i4.2 + IL_0019: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_001e: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0023: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0028: brfalse.s IL_0036 + + IL_002a: ldstr "b" + IL_002f: call void [mscorlib]System.Console::WriteLine(string) + IL_0034: br.s IL_0040 + + IL_0036: ldstr "c" + IL_003b: call void [mscorlib]System.Console::WriteLine(string) + IL_0040: ldc.i4.1 + IL_0041: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0046: dup + IL_0047: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_004c: brtrue.s IL_0059 + + IL_004e: ldc.i4.2 + IL_004f: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0054: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0059: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_005e: brfalse.s IL_006b + + IL_0060: ldstr "d" + IL_0065: call void [mscorlib]System.Console::WriteLine(string) + IL_006a: ret + + IL_006b: ldstr "e" + IL_0070: call void [mscorlib]System.Console::WriteLine(string) + IL_0075: ret + } // end of method S::InConditionDetection + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.roslyn.il new file mode 100644 index 000000000..85ae3db95 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.opt.roslyn.il @@ -0,0 +1,563 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly CustomShortCircuitOperators +{ + .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 + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CustomShortCircuitOperators.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + extends [mscorlib]System.Object +{ + .method public hidebysig specialname static + bool op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } // end of method BaseClass::op_True + + .method public hidebysig specialname static + bool op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } // end of method BaseClass::op_False + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method BaseClass::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + extends ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass +{ + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method C::op_BitwiseAnd + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldnull + IL_0001: ret + } // end of method C::op_BitwiseOr + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x) cil managed + { + // Code size 2 (0x2) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } // end of method C::op_LogicalNot + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + GetC(int32 a) cil managed + { + // Code size 6 (0x6) + .maxstack 8 + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: ret + } // end of method C::GetC + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicAnd() cil managed + { + // Code size 30 (0x1e) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: ldc.i4.1 + IL_0001: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: brtrue.s IL_001c + + IL_000f: ldloc.0 + IL_0010: ldc.i4.2 + IL_0011: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0016: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001b: ret + + IL_001c: ldloc.0 + IL_001d: ret + } // end of method C::LogicAnd + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicOr() cil managed + { + // Code size 30 (0x1e) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: ldc.i4.1 + IL_0001: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: brtrue.s IL_001c + + IL_000f: ldloc.0 + IL_0010: ldc.i4.2 + IL_0011: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0016: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001b: ret + + IL_001c: ldloc.0 + IL_001d: ret + } // end of method C::LogicOr + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + Complex() cil managed + { + // Code size 107 (0x6b) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_2) + IL_0000: ldc.i4.1 + IL_0001: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0006: stloc.2 + IL_0007: ldloc.2 + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: brtrue.s IL_001d + + IL_000f: ldloc.2 + IL_0010: ldc.i4.2 + IL_0011: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0016: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001b: br.s IL_001e + + IL_001d: ldloc.2 + IL_001e: stloc.1 + IL_001f: ldloc.1 + IL_0020: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0025: brtrue.s IL_0035 + + IL_0027: ldloc.1 + IL_0028: ldc.i4.3 + IL_0029: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_002e: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0033: br.s IL_0036 + + IL_0035: ldloc.1 + IL_0036: stloc.0 + IL_0037: ldloc.0 + IL_0038: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_003d: brtrue.s IL_0069 + + IL_003f: ldloc.0 + IL_0040: ldc.i4.4 + IL_0041: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0046: stloc.1 + IL_0047: ldloc.1 + IL_0048: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_004d: brtrue.s IL_005d + + IL_004f: ldloc.1 + IL_0050: ldc.i4.5 + IL_0051: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0056: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_005b: br.s IL_005e + + IL_005d: ldloc.1 + IL_005e: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0063: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0068: ret + + IL_0069: ldloc.0 + IL_006a: ret + } // end of method C::Complex + + .method private hidebysig static void Main() cil managed + { + // Code size 73 (0x49) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_2) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_000a: stloc.0 + IL_000b: dup + IL_000c: stloc.2 + IL_000d: ldloc.2 + IL_000e: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0013: brtrue.s IL_001e + + IL_0015: ldloc.2 + IL_0016: ldloc.0 + IL_0017: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001c: br.s IL_001f + + IL_001e: ldloc.2 + IL_001f: stloc.1 + IL_0020: stloc.2 + IL_0021: ldloc.2 + IL_0022: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0027: brtrue.s IL_0032 + + IL_0029: ldloc.2 + IL_002a: ldloc.0 + IL_002b: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0030: br.s IL_0033 + + IL_0032: ldloc.2 + IL_0033: ldloc.1 + IL_0034: callvirt instance string [mscorlib]System.Object::ToString() + IL_0039: call void [mscorlib]System.Console::WriteLine(string) + IL_003e: callvirt instance string [mscorlib]System.Object::ToString() + IL_0043: call void [mscorlib]System.Console::WriteLine(string) + IL_0048: ret + } // end of method C::Main + + .method private hidebysig static void Test2() cil managed + { + // Code size 88 (0x58) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: stloc.1 + IL_0008: ldloc.1 + IL_0009: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000e: brtrue.s IL_0019 + + IL_0010: ldloc.1 + IL_0011: ldloc.0 + IL_0012: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0017: br.s IL_001a + + IL_0019: ldloc.1 + IL_001a: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_001f: brfalse.s IL_002c + + IL_0021: ldloc.0 + IL_0022: callvirt instance string [mscorlib]System.Object::ToString() + IL_0027: call void [mscorlib]System.Console::WriteLine(string) + IL_002c: ldloc.0 + IL_002d: stloc.1 + IL_002e: ldloc.1 + IL_002f: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0034: brtrue.s IL_003f + + IL_0036: ldloc.1 + IL_0037: ldloc.0 + IL_0038: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_003d: br.s IL_0040 + + IL_003f: ldloc.1 + IL_0040: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0045: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_004a: brfalse.s IL_0057 + + IL_004c: ldloc.0 + IL_004d: callvirt instance string [mscorlib]System.Object::ToString() + IL_0052: call void [mscorlib]System.Console::WriteLine(string) + IL_0057: ret + } // end of method C::Test2 + + .method private hidebysig static void Test3() cil managed + { + // Code size 50 (0x32) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000c: brfalse.s IL_0019 + + IL_000e: ldloc.0 + IL_000f: callvirt instance string [mscorlib]System.Object::ToString() + IL_0014: call void [mscorlib]System.Console::WriteLine(string) + IL_0019: ldloc.0 + IL_001a: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001f: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0024: brfalse.s IL_0031 + + IL_0026: ldloc.0 + IL_0027: callvirt instance string [mscorlib]System.Object::ToString() + IL_002c: call void [mscorlib]System.Console::WriteLine(string) + IL_0031: ret + } // end of method C::Test3 + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::.ctor() + IL_0006: ret + } // end of method C::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + +.class private sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + extends [mscorlib]System.ValueType +{ + .field private initonly bool val + .method public hidebysig specialname rtspecialname + instance void .ctor(bool val) cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ret + } // end of method S::.ctor + + .method public hidebysig specialname static + bool op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0006: ret + } // end of method S::op_True + + .method public hidebysig specialname static + bool op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0006: ret + } // end of method S::op_False + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0006: ldarg.1 + IL_0007: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000c: and + IL_000d: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0012: ret + } // end of method S::op_BitwiseAnd + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 19 (0x13) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0006: ldarg.1 + IL_0007: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000c: or + IL_000d: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0012: ret + } // end of method S::op_BitwiseOr + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_LogicalNot(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 15 (0xf) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0006: ldc.i4.0 + IL_0007: ceq + IL_0009: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_000e: ret + } // end of method S::op_LogicalNot + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + Get(int32 i) cil managed + { + // Code size 10 (0xa) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldc.i4.0 + IL_0002: cgt + IL_0004: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0009: ret + } // end of method S::Get + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicAnd() cil managed + { + // Code size 30 (0x1e) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: ldc.i4.1 + IL_0001: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000d: brtrue.s IL_001c + + IL_000f: ldloc.0 + IL_0010: ldc.i4.2 + IL_0011: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0016: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_001b: ret + + IL_001c: ldloc.0 + IL_001d: ret + } // end of method S::LogicAnd + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicOr() cil managed + { + // Code size 30 (0x1e) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: ldc.i4.1 + IL_0001: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000d: brtrue.s IL_001c + + IL_000f: ldloc.0 + IL_0010: ldc.i4.2 + IL_0011: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0016: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_001b: ret + + IL_001c: ldloc.0 + IL_001d: ret + } // end of method S::LogicOr + + .method public hidebysig instance void + InConditionDetection() cil managed + { + // Code size 128 (0x80) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: ldstr "a" + IL_0005: call void [mscorlib]System.Console::WriteLine(string) + IL_000a: ldc.i4.1 + IL_000b: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0010: stloc.0 + IL_0011: ldloc.0 + IL_0012: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0017: brtrue.s IL_0027 + + IL_0019: ldloc.0 + IL_001a: ldc.i4.2 + IL_001b: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0020: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0025: br.s IL_0028 + + IL_0027: ldloc.0 + IL_0028: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_002d: brfalse.s IL_003b + + IL_002f: ldstr "b" + IL_0034: call void [mscorlib]System.Console::WriteLine(string) + IL_0039: br.s IL_0045 + + IL_003b: ldstr "c" + IL_0040: call void [mscorlib]System.Console::WriteLine(string) + IL_0045: ldc.i4.1 + IL_0046: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_004b: stloc.0 + IL_004c: ldloc.0 + IL_004d: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0052: brtrue.s IL_0062 + + IL_0054: ldloc.0 + IL_0055: ldc.i4.2 + IL_0056: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_005b: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0060: br.s IL_0063 + + IL_0062: ldloc.0 + IL_0063: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0068: brfalse.s IL_0075 + + IL_006a: ldstr "d" + IL_006f: call void [mscorlib]System.Console::WriteLine(string) + IL_0074: ret + + IL_0075: ldstr "e" + IL_007a: call void [mscorlib]System.Console::WriteLine(string) + IL_007f: ret + } // end of method S::InConditionDetection + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.roslyn.il new file mode 100644 index 000000000..4d279600b --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.roslyn.il @@ -0,0 +1,723 @@ + + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly CustomShortCircuitOperators +{ + .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 + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module CustomShortCircuitOperators.dll +.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 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + extends [mscorlib]System.Object +{ + .method public hidebysig specialname static + bool op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method BaseClass::op_True + + .method public hidebysig specialname static + bool op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass x) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldc.i4.0 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method BaseClass::op_False + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method BaseClass::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass + +.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + extends ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass +{ + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method C::op_BitwiseAnd + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C y) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldnull + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method C::op_BitwiseOr + + .method public hidebysig specialname static + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C x) cil managed + { + // Code size 7 (0x7) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method C::op_LogicalNot + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + GetC(int32 a) cil managed + { + // Code size 11 (0xb) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + + IL_0009: ldloc.0 + IL_000a: ret + } // end of method C::GetC + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicAnd() cil managed + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000e: brtrue.s IL_001e + + IL_0010: ldloc.0 + IL_0011: ldc.i4.2 + IL_0012: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0017: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001c: br.s IL_001f + + IL_001e: ldloc.0 + IL_001f: stloc.1 + IL_0020: br.s IL_0022 + + IL_0022: ldloc.1 + IL_0023: ret + } // end of method C::LogicAnd + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + LogicOr() cil managed + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000e: brtrue.s IL_001e + + IL_0010: ldloc.0 + IL_0011: ldc.i4.2 + IL_0012: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0017: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001c: br.s IL_001f + + IL_001e: ldloc.0 + IL_001f: stloc.1 + IL_0020: br.s IL_0022 + + IL_0022: ldloc.1 + IL_0023: ret + } // end of method C::LogicOr + + .method public hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + Complex() cil managed + { + // Code size 113 (0x71) + .maxstack 3 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_2, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_3) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0007: stloc.2 + IL_0008: ldloc.2 + IL_0009: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000e: brtrue.s IL_001e + + IL_0010: ldloc.2 + IL_0011: ldc.i4.2 + IL_0012: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0017: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_001c: br.s IL_001f + + IL_001e: ldloc.2 + IL_001f: stloc.1 + IL_0020: ldloc.1 + IL_0021: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0026: brtrue.s IL_0036 + + IL_0028: ldloc.1 + IL_0029: ldc.i4.3 + IL_002a: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_002f: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0034: br.s IL_0037 + + IL_0036: ldloc.1 + IL_0037: stloc.0 + IL_0038: ldloc.0 + IL_0039: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_003e: brtrue.s IL_006b + + IL_0040: ldloc.0 + IL_0041: ldc.i4.4 + IL_0042: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0047: stloc.1 + IL_0048: ldloc.1 + IL_0049: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_004e: brtrue.s IL_005e + + IL_0050: ldloc.1 + IL_0051: ldc.i4.5 + IL_0052: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::GetC(int32) + IL_0057: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_005c: br.s IL_005f + + IL_005e: ldloc.1 + IL_005f: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0064: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0069: br.s IL_006c + + IL_006b: ldloc.0 + IL_006c: stloc.3 + IL_006d: br.s IL_006f + + IL_006f: ldloc.3 + IL_0070: ret + } // end of method C::Complex + + .method private hidebysig static void Main() cil managed + { + // Code size 88 (0x58) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_2, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_3, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_4) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_000c: stloc.1 + IL_000d: ldloc.0 + IL_000e: stloc.s V_4 + IL_0010: ldloc.s V_4 + IL_0012: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0017: brtrue.s IL_0023 + + IL_0019: ldloc.s V_4 + IL_001b: ldloc.1 + IL_001c: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0021: br.s IL_0025 + + IL_0023: ldloc.s V_4 + IL_0025: stloc.2 + IL_0026: ldloc.0 + IL_0027: stloc.s V_4 + IL_0029: ldloc.s V_4 + IL_002b: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0030: brtrue.s IL_003c + + IL_0032: ldloc.s V_4 + IL_0034: ldloc.1 + IL_0035: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseOr(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_003a: br.s IL_003e + + IL_003c: ldloc.s V_4 + IL_003e: stloc.3 + IL_003f: ldloc.2 + IL_0040: callvirt instance string [mscorlib]System.Object::ToString() + IL_0045: call void [mscorlib]System.Console::WriteLine(string) + IL_004a: nop + IL_004b: ldloc.3 + IL_004c: callvirt instance string [mscorlib]System.Object::ToString() + IL_0051: call void [mscorlib]System.Console::WriteLine(string) + IL_0056: nop + IL_0057: ret + } // end of method C::Main + + .method private hidebysig static void Test2() cil managed + { + // Code size 99 (0x63) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + bool V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_2, + bool V_3) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: stloc.2 + IL_0009: ldloc.2 + IL_000a: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000f: brtrue.s IL_001a + + IL_0011: ldloc.2 + IL_0012: ldloc.0 + IL_0013: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0018: br.s IL_001b + + IL_001a: ldloc.2 + IL_001b: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0020: stloc.1 + IL_0021: ldloc.1 + IL_0022: brfalse.s IL_0032 + + IL_0024: nop + IL_0025: ldloc.0 + IL_0026: callvirt instance string [mscorlib]System.Object::ToString() + IL_002b: call void [mscorlib]System.Console::WriteLine(string) + IL_0030: nop + IL_0031: nop + IL_0032: ldloc.0 + IL_0033: stloc.2 + IL_0034: ldloc.2 + IL_0035: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_False(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_003a: brtrue.s IL_0045 + + IL_003c: ldloc.2 + IL_003d: ldloc.0 + IL_003e: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_BitwiseAnd(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0043: br.s IL_0046 + + IL_0045: ldloc.2 + IL_0046: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_004b: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_0050: stloc.3 + IL_0051: ldloc.3 + IL_0052: brfalse.s IL_0062 + + IL_0054: nop + IL_0055: ldloc.0 + IL_0056: callvirt instance string [mscorlib]System.Object::ToString() + IL_005b: call void [mscorlib]System.Console::WriteLine(string) + IL_0060: nop + IL_0061: nop + IL_0062: ret + } // end of method C::Test2 + + .method private hidebysig static void Test3() cil managed + { + // Code size 61 (0x3d) + .maxstack 1 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C V_0, + bool V_1, + bool V_2) + IL_0000: nop + IL_0001: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::.ctor() + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_000d: stloc.1 + IL_000e: ldloc.1 + IL_000f: brfalse.s IL_001f + + IL_0011: nop + IL_0012: ldloc.0 + IL_0013: callvirt instance string [mscorlib]System.Object::ToString() + IL_0018: call void [mscorlib]System.Console::WriteLine(string) + IL_001d: nop + IL_001e: nop + IL_001f: ldloc.0 + IL_0020: call class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C::op_LogicalNot(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C) + IL_0025: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::op_True(class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass) + IL_002a: stloc.2 + IL_002b: ldloc.2 + IL_002c: brfalse.s IL_003c + + IL_002e: nop + IL_002f: ldloc.0 + IL_0030: callvirt instance string [mscorlib]System.Object::ToString() + IL_0035: call void [mscorlib]System.Console::WriteLine(string) + IL_003a: nop + IL_003b: nop + IL_003c: ret + } // end of method C::Test3 + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.BaseClass::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method C::.ctor + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.C + +.class private sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + extends [mscorlib]System.ValueType +{ + .field private initonly bool val + .method public hidebysig specialname rtspecialname + instance void .ctor(bool val) cil managed + { + // Code size 9 (0x9) + .maxstack 8 + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: stfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0008: ret + } // end of method S::.ctor + + .method public hidebysig specialname static + bool op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method S::op_True + + .method public hidebysig specialname static + bool op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 12 (0xc) + .maxstack 1 + .locals init (bool V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: stloc.0 + IL_0008: br.s IL_000a + + IL_000a: ldloc.0 + IL_000b: ret + } // end of method S::op_False + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 24 (0x18) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ldarg.1 + IL_0008: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000d: and + IL_000e: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0013: stloc.0 + IL_0014: br.s IL_0016 + + IL_0016: ldloc.0 + IL_0017: ret + } // end of method S::op_BitwiseAnd + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S y) cil managed + { + // Code size 24 (0x18) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ldarg.1 + IL_0008: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_000d: or + IL_000e: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_0013: stloc.0 + IL_0014: br.s IL_0016 + + IL_0016: ldloc.0 + IL_0017: ret + } // end of method S::op_BitwiseOr + + .method public hidebysig specialname static + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + op_LogicalNot(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S x) cil managed + { + // Code size 20 (0x14) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::val + IL_0007: ldc.i4.0 + IL_0008: ceq + IL_000a: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_000f: stloc.0 + IL_0010: br.s IL_0012 + + IL_0012: ldloc.0 + IL_0013: ret + } // end of method S::op_LogicalNot + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + Get(int32 i) cil managed + { + // Code size 15 (0xf) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0) + IL_0000: nop + IL_0001: ldarg.0 + IL_0002: ldc.i4.0 + IL_0003: cgt + IL_0005: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::.ctor(bool) + IL_000a: stloc.0 + IL_000b: br.s IL_000d + + IL_000d: ldloc.0 + IL_000e: ret + } // end of method S::Get + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicAnd() cil managed + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_1) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000e: brtrue.s IL_001e + + IL_0010: ldloc.0 + IL_0011: ldc.i4.2 + IL_0012: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0017: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_001c: br.s IL_001f + + IL_001e: ldloc.0 + IL_001f: stloc.1 + IL_0020: br.s IL_0022 + + IL_0022: ldloc.1 + IL_0023: ret + } // end of method S::LogicAnd + + .method public hidebysig static valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + LogicOr() cil managed + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_1) + IL_0000: nop + IL_0001: ldc.i4.1 + IL_0002: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0007: stloc.0 + IL_0008: ldloc.0 + IL_0009: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_000e: brtrue.s IL_001e + + IL_0010: ldloc.0 + IL_0011: ldc.i4.2 + IL_0012: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0017: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_001c: br.s IL_001f + + IL_001e: ldloc.0 + IL_001f: stloc.1 + IL_0020: br.s IL_0022 + + IL_0022: ldloc.1 + IL_0023: ret + } // end of method S::LogicOr + + .method public hidebysig instance void + InConditionDetection() cil managed + { + // Code size 147 (0x93) + .maxstack 2 + .locals init (bool V_0, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S V_1, + bool V_2) + IL_0000: nop + IL_0001: ldstr "a" + IL_0006: call void [mscorlib]System.Console::WriteLine(string) + IL_000b: nop + IL_000c: ldc.i4.1 + IL_000d: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0012: stloc.1 + IL_0013: ldloc.1 + IL_0014: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_False(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0019: brtrue.s IL_0029 + + IL_001b: ldloc.1 + IL_001c: ldc.i4.2 + IL_001d: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0022: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseAnd(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0027: br.s IL_002a + + IL_0029: ldloc.1 + IL_002a: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_002f: stloc.0 + IL_0030: ldloc.0 + IL_0031: brfalse.s IL_0042 + + IL_0033: nop + IL_0034: ldstr "b" + IL_0039: call void [mscorlib]System.Console::WriteLine(string) + IL_003e: nop + IL_003f: nop + IL_0040: br.s IL_004f + + IL_0042: nop + IL_0043: ldstr "c" + IL_0048: call void [mscorlib]System.Console::WriteLine(string) + IL_004d: nop + IL_004e: nop + IL_004f: ldc.i4.1 + IL_0050: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0055: stloc.1 + IL_0056: ldloc.1 + IL_0057: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_005c: brtrue.s IL_006c + + IL_005e: ldloc.1 + IL_005f: ldc.i4.2 + IL_0060: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::Get(int32) + IL_0065: call valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_BitwiseOr(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S, + valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_006a: br.s IL_006d + + IL_006c: ldloc.1 + IL_006d: call bool ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S::op_True(valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S) + IL_0072: stloc.2 + IL_0073: ldloc.2 + IL_0074: brfalse.s IL_0085 + + IL_0076: nop + IL_0077: ldstr "d" + IL_007c: call void [mscorlib]System.Console::WriteLine(string) + IL_0081: nop + IL_0082: nop + IL_0083: br.s IL_0092 + + IL_0085: nop + IL_0086: ldstr "e" + IL_008b: call void [mscorlib]System.Console::WriteLine(string) + IL_0090: nop + IL_0091: nop + IL_0092: ret + } // end of method S::InConditionDetection + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators.S + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index c52d56d45..385462e7f 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -145,7 +145,8 @@ namespace ICSharpCode.Decompiler.CSharp new TransformArrayInitializers(), new TransformCollectionAndObjectInitializers(), new TransformExpressionTrees(), - new NamedArgumentTransform() + new NamedArgumentTransform(), + new UserDefinedLogicTransform() ), } }, diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index 0b2bc3685..1268fd083 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -691,6 +691,21 @@ namespace ICSharpCode.Decompiler.CSharp or.AddCandidate(ctor); } } + } else if (method.IsOperator) { + IEnumerable operatorCandidates; + if (arguments.Count == 1) { + operatorCandidates = resolver.GetUserDefinedOperatorCandidates(arguments[0].Type, method.Name); + } else if (arguments.Count == 2) { + var hashSet = new HashSet(); + hashSet.UnionWith(resolver.GetUserDefinedOperatorCandidates(arguments[0].Type, method.Name)); + hashSet.UnionWith(resolver.GetUserDefinedOperatorCandidates(arguments[1].Type, method.Name)); + operatorCandidates = hashSet; + } else { + operatorCandidates = EmptyList.Instance; + } + foreach (var m in operatorCandidates) { + or.AddCandidate(m); + } } else if (target == null) { var result = resolver.ResolveSimpleName(method.Name, typeArguments, isInvocationTarget: true) as MethodGroupResolveResult; if (result == null) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index f83b8dcc1..778c4a33e 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -748,12 +748,12 @@ namespace ICSharpCode.Decompiler.CSharp left.ResolveResult, right.ResolveResult)); } - protected internal override TranslatedExpression VisitThreeValuedLogicAnd(ThreeValuedLogicAnd inst, TranslationContext context) + protected internal override TranslatedExpression VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst, TranslationContext context) { return HandleThreeValuedLogic(inst, BinaryOperatorType.BitwiseAnd, ExpressionType.And); } - protected internal override TranslatedExpression VisitThreeValuedLogicOr(ThreeValuedLogicOr inst, TranslationContext context) + protected internal override TranslatedExpression VisitThreeValuedBoolOr(ThreeValuedBoolOr inst, TranslationContext context) { return HandleThreeValuedLogic(inst, BinaryOperatorType.BitwiseOr, ExpressionType.Or); } @@ -780,6 +780,23 @@ namespace ICSharpCode.Decompiler.CSharp .WithILInstruction(inst); } + protected internal override TranslatedExpression VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst, TranslationContext context) + { + var left = Translate(inst.Left, inst.Method.Parameters[0].Type).ConvertTo(inst.Method.Parameters[0].Type, this); + var right = Translate(inst.Right, inst.Method.Parameters[1].Type).ConvertTo(inst.Method.Parameters[1].Type, this); + BinaryOperatorType op; + if (inst.Method.Name == "op_BitwiseAnd") { + op = BinaryOperatorType.ConditionalAnd; + } else if (inst.Method.Name == "op_BitwiseOr") { + op = BinaryOperatorType.ConditionalOr; + } else { + throw new InvalidOperationException("Invalid method name"); + } + return new BinaryOperatorExpression(left.Expression, op, right.Expression) + .WithRR(new InvocationResolveResult(null, inst.Method, new ResolveResult[] { left.ResolveResult, right.ResolveResult })) + .WithILInstruction(inst); + } + ExpressionWithResolveResult Assignment(TranslatedExpression left, TranslatedExpression right) { right = right.ConvertTo(left.Type, this, allowImplicitConversion: true); diff --git a/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs b/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs index a13a96b3d..d26e8d857 100644 --- a/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs +++ b/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs @@ -1149,7 +1149,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver #endregion #region Get user-defined operator candidates - IEnumerable GetUserDefinedOperatorCandidates(IType type, string operatorName) + public IEnumerable GetUserDefinedOperatorCandidates(IType type, string operatorName) { if (operatorName == null) return EmptyList.Instance; diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 9f0800f9f..9033f3bac 100644 --- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -267,6 +267,7 @@ + @@ -330,7 +331,7 @@ - + diff --git a/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs b/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs index 1fe7e6b40..25b34961c 100644 --- a/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs +++ b/ICSharpCode.Decompiler/IL/ILTypeExtensions.cs @@ -142,6 +142,8 @@ namespace ICSharpCode.Decompiler.IL return callVirt.Method.ReturnType; case CallIndirect calli: return calli.ReturnType; + case UserDefinedLogicOperator logicOp: + return logicOp.Method.ReturnType; case LdObj ldobj: return ldobj.Type; case StObj stobj: @@ -151,19 +153,19 @@ namespace ICSharpCode.Decompiler.IL case StLoc stloc: return stloc.Variable.Type; case LdLoca ldloca: - return new TypeSystem.ByReferenceType(ldloca.Variable.Type); + return new ByReferenceType(ldloca.Variable.Type); case LdFlda ldflda: - return new TypeSystem.ByReferenceType(ldflda.Field.Type); + return new ByReferenceType(ldflda.Field.Type); case LdsFlda ldsflda: - return new TypeSystem.ByReferenceType(ldsflda.Field.Type); + return new ByReferenceType(ldsflda.Field.Type); case LdElema ldelema: - if (ldelema.Array.InferType() is TypeSystem.ArrayType arrayType) { - var refType = new TypeSystem.ByReferenceType(arrayType.ElementType); + if (ldelema.Array.InferType() is ArrayType arrayType) { + var refType = new ByReferenceType(arrayType.ElementType); if (TypeUtils.IsCompatibleTypeForMemoryAccess(refType, ldelema.Type)) { return refType; } } - return new TypeSystem.ByReferenceType(ldelema.Type); + return new ByReferenceType(ldelema.Type); default: return SpecialType.UnknownType; } diff --git a/ICSharpCode.Decompiler/IL/InstructionFlags.cs b/ICSharpCode.Decompiler/IL/InstructionFlags.cs index bf0ddd517..f451c9ab2 100644 --- a/ICSharpCode.Decompiler/IL/InstructionFlags.cs +++ b/ICSharpCode.Decompiler/IL/InstructionFlags.cs @@ -70,7 +70,7 @@ namespace ICSharpCode.Decompiler.IL /// The instruction contains some kind of internal control flow. /// /// - /// If this flag is not set, all descendants of the instruction are fully evaluated (modulo MayThrow/MayBranch) + /// If this flag is not set, all descendants of the instruction are fully evaluated (modulo MayThrow/MayBranch/MayUnwrapNull) /// in left-to-right pre-order. /// /// Note that branch instructions don't have this flag set, because their control flow is not internal diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs index 29a87338d..6154ba2fe 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions.cs @@ -103,9 +103,9 @@ namespace ICSharpCode.Decompiler.IL /// Stores the value into an anonymous temporary variable, and returns the address of that variable. AddressOf, /// Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior. - ThreeValuedLogicAnd, + ThreeValuedBoolAnd, /// Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior. - ThreeValuedLogicOr, + ThreeValuedBoolOr, /// The input operand must be one of: /// 1. a nullable value type /// 2. a reference type @@ -187,6 +187,8 @@ namespace ICSharpCode.Decompiler.IL StringToInt, /// ILAst representation of Expression.Convert. ExpressionTreeCast, + /// Use of user-defined && or || operator. + UserDefinedLogicOperator, /// ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation). DynamicBinaryOperatorInstruction, /// ILAst representation of a unary operator inside a dynamic expression (maps to Binder.UnaryOperation). @@ -2607,27 +2609,27 @@ namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL { /// Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior. - public sealed partial class ThreeValuedLogicAnd : BinaryInstruction + public sealed partial class ThreeValuedBoolAnd : BinaryInstruction { - public ThreeValuedLogicAnd(ILInstruction left, ILInstruction right) : base(OpCode.ThreeValuedLogicAnd, left, right) + public ThreeValuedBoolAnd(ILInstruction left, ILInstruction right) : base(OpCode.ThreeValuedBoolAnd, left, right) { } public override StackType ResultType { get { return StackType.O; } } public override void AcceptVisitor(ILVisitor visitor) { - visitor.VisitThreeValuedLogicAnd(this); + visitor.VisitThreeValuedBoolAnd(this); } public override T AcceptVisitor(ILVisitor visitor) { - return visitor.VisitThreeValuedLogicAnd(this); + return visitor.VisitThreeValuedBoolAnd(this); } public override T AcceptVisitor(ILVisitor visitor, C context) { - return visitor.VisitThreeValuedLogicAnd(this, context); + return visitor.VisitThreeValuedBoolAnd(this, context); } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { - var o = other as ThreeValuedLogicAnd; + var o = other as ThreeValuedBoolAnd; return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match); } } @@ -2635,27 +2637,27 @@ namespace ICSharpCode.Decompiler.IL namespace ICSharpCode.Decompiler.IL { /// Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior. - public sealed partial class ThreeValuedLogicOr : BinaryInstruction + public sealed partial class ThreeValuedBoolOr : BinaryInstruction { - public ThreeValuedLogicOr(ILInstruction left, ILInstruction right) : base(OpCode.ThreeValuedLogicOr, left, right) + public ThreeValuedBoolOr(ILInstruction left, ILInstruction right) : base(OpCode.ThreeValuedBoolOr, left, right) { } public override StackType ResultType { get { return StackType.O; } } public override void AcceptVisitor(ILVisitor visitor) { - visitor.VisitThreeValuedLogicOr(this); + visitor.VisitThreeValuedBoolOr(this); } public override T AcceptVisitor(ILVisitor visitor) { - return visitor.VisitThreeValuedLogicOr(this); + return visitor.VisitThreeValuedBoolOr(this); } public override T AcceptVisitor(ILVisitor visitor, C context) { - return visitor.VisitThreeValuedLogicOr(this, context); + return visitor.VisitThreeValuedBoolOr(this, context); } protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) { - var o = other as ThreeValuedLogicOr; + var o = other as ThreeValuedBoolOr; return o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match); } } @@ -4840,6 +4842,116 @@ namespace ICSharpCode.Decompiler.IL } } namespace ICSharpCode.Decompiler.IL +{ + /// Use of user-defined && or || operator. + public sealed partial class UserDefinedLogicOperator : ILInstruction, IInstructionWithMethodOperand + { + public UserDefinedLogicOperator(IMethod method, ILInstruction left, ILInstruction right) : base(OpCode.UserDefinedLogicOperator) + { + this.method = method; + this.Left = left; + this.Right = right; + } + readonly IMethod method; + /// Returns the method operand. + public IMethod Method { get { return method; } } + public override StackType ResultType { get { return StackType.O; } } + public static readonly SlotInfo LeftSlot = new SlotInfo("Left", canInlineInto: true); + ILInstruction left; + public ILInstruction Left { + get { return this.left; } + set { + ValidateChild(value); + SetChildInstruction(ref this.left, value, 0); + } + } + public static readonly SlotInfo RightSlot = new SlotInfo("Right"); + ILInstruction right; + public ILInstruction Right { + get { return this.right; } + set { + ValidateChild(value); + SetChildInstruction(ref this.right, value, 1); + } + } + protected sealed override int GetChildCount() + { + return 2; + } + protected sealed override ILInstruction GetChild(int index) + { + switch (index) { + case 0: + return this.left; + case 1: + return this.right; + default: + throw new IndexOutOfRangeException(); + } + } + protected sealed override void SetChild(int index, ILInstruction value) + { + switch (index) { + case 0: + this.Left = value; + break; + case 1: + this.Right = value; + break; + default: + throw new IndexOutOfRangeException(); + } + } + protected sealed override SlotInfo GetChildSlot(int index) + { + switch (index) { + case 0: + return LeftSlot; + case 1: + return RightSlot; + default: + throw new IndexOutOfRangeException(); + } + } + public sealed override ILInstruction Clone() + { + var clone = (UserDefinedLogicOperator)ShallowClone(); + clone.Left = this.left.Clone(); + clone.Right = this.right.Clone(); + return clone; + } + public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + { + ILRange.WriteTo(output, options); + output.Write(OpCode); + output.Write(' '); + method.WriteTo(output); + output.Write('('); + this.left.WriteTo(output, options); + output.Write(", "); + this.right.WriteTo(output, options); + output.Write(')'); + } + public override void AcceptVisitor(ILVisitor visitor) + { + visitor.VisitUserDefinedLogicOperator(this); + } + public override T AcceptVisitor(ILVisitor visitor) + { + return visitor.VisitUserDefinedLogicOperator(this); + } + public override T AcceptVisitor(ILVisitor visitor, C context) + { + return visitor.VisitUserDefinedLogicOperator(this, context); + } + protected internal override bool PerformMatch(ILInstruction other, ref Patterns.Match match) + { + var o = other as UserDefinedLogicOperator; + return o != null && method.Equals(o.method) && this.left.PerformMatch(o.left, ref match) && this.right.PerformMatch(o.right, ref match); + } + } +} +namespace ICSharpCode.Decompiler.IL { /// ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation). public sealed partial class DynamicBinaryOperatorInstruction : DynamicInstruction @@ -6231,11 +6343,11 @@ namespace ICSharpCode.Decompiler.IL { Default(inst); } - protected internal virtual void VisitThreeValuedLogicAnd(ThreeValuedLogicAnd inst) + protected internal virtual void VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst) { Default(inst); } - protected internal virtual void VisitThreeValuedLogicOr(ThreeValuedLogicOr inst) + protected internal virtual void VisitThreeValuedBoolOr(ThreeValuedBoolOr inst) { Default(inst); } @@ -6383,6 +6495,10 @@ namespace ICSharpCode.Decompiler.IL { Default(inst); } + protected internal virtual void VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst) + { + Default(inst); + } protected internal virtual void VisitDynamicBinaryOperatorInstruction(DynamicBinaryOperatorInstruction inst) { Default(inst); @@ -6601,11 +6717,11 @@ namespace ICSharpCode.Decompiler.IL { return Default(inst); } - protected internal virtual T VisitThreeValuedLogicAnd(ThreeValuedLogicAnd inst) + protected internal virtual T VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst) { return Default(inst); } - protected internal virtual T VisitThreeValuedLogicOr(ThreeValuedLogicOr inst) + protected internal virtual T VisitThreeValuedBoolOr(ThreeValuedBoolOr inst) { return Default(inst); } @@ -6753,6 +6869,10 @@ namespace ICSharpCode.Decompiler.IL { return Default(inst); } + protected internal virtual T VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst) + { + return Default(inst); + } protected internal virtual T VisitDynamicBinaryOperatorInstruction(DynamicBinaryOperatorInstruction inst) { return Default(inst); @@ -6971,11 +7091,11 @@ namespace ICSharpCode.Decompiler.IL { return Default(inst, context); } - protected internal virtual T VisitThreeValuedLogicAnd(ThreeValuedLogicAnd inst, C context) + protected internal virtual T VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst, C context) { return Default(inst, context); } - protected internal virtual T VisitThreeValuedLogicOr(ThreeValuedLogicOr inst, C context) + protected internal virtual T VisitThreeValuedBoolOr(ThreeValuedBoolOr inst, C context) { return Default(inst, context); } @@ -7123,6 +7243,10 @@ namespace ICSharpCode.Decompiler.IL { return Default(inst, context); } + protected internal virtual T VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst, C context) + { + return Default(inst, context); + } protected internal virtual T VisitDynamicBinaryOperatorInstruction(DynamicBinaryOperatorInstruction inst, C context) { return Default(inst, context); @@ -7228,8 +7352,8 @@ namespace ICSharpCode.Decompiler.IL "ldloca", "stloc", "addressof", - "3vl.logic.and", - "3vl.logic.or", + "3vl.bool.and", + "3vl.bool.or", "nullable.unwrap", "nullable.rewrap", "ldstr", @@ -7266,6 +7390,7 @@ namespace ICSharpCode.Decompiler.IL "array.to.pointer", "string.to.int", "expression.tree.cast", + "user.logic.op", "dynamic.binary.operator", "dynamic.unary.operator", "dynamic.convert", @@ -7434,9 +7559,9 @@ namespace ICSharpCode.Decompiler.IL value = default(ILInstruction); return false; } - public bool MatchThreeValuedLogicAnd(out ILInstruction left, out ILInstruction right) + public bool MatchThreeValuedBoolAnd(out ILInstruction left, out ILInstruction right) { - var inst = this as ThreeValuedLogicAnd; + var inst = this as ThreeValuedBoolAnd; if (inst != null) { left = inst.Left; right = inst.Right; @@ -7446,9 +7571,9 @@ namespace ICSharpCode.Decompiler.IL right = default(ILInstruction); return false; } - public bool MatchThreeValuedLogicOr(out ILInstruction left, out ILInstruction right) + public bool MatchThreeValuedBoolOr(out ILInstruction left, out ILInstruction right) { - var inst = this as ThreeValuedLogicOr; + var inst = this as ThreeValuedBoolOr; if (inst != null) { left = inst.Left; right = inst.Right; @@ -7794,6 +7919,20 @@ namespace ICSharpCode.Decompiler.IL array = default(ILInstruction); return false; } + public bool MatchUserDefinedLogicOperator(out IMethod method, out ILInstruction left, out ILInstruction right) + { + var inst = this as UserDefinedLogicOperator; + if (inst != null) { + method = inst.Method; + left = inst.Left; + right = inst.Right; + return true; + } + method = default(IMethod); + left = default(ILInstruction); + right = default(ILInstruction); + return false; + } public bool MatchMakeRefAny(out ILInstruction argument, out IType type) { var inst = this as MakeRefAny; diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt index 8c5302f42..c0b8f51c2 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.tt +++ b/ICSharpCode.Decompiler/IL/Instructions.tt @@ -175,10 +175,10 @@ ResultType("variable.StackType")), new OpCode("addressof", "Stores the value into an anonymous temporary variable, and returns the address of that variable.", CustomClassName("AddressOf"), CustomArguments(("value", null)), ResultType("Ref")), - new OpCode("3vl.logic.and", "Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior.", - CustomClassName("ThreeValuedLogicAnd"), Binary, ResultType("O")), - new OpCode("3vl.logic.or", "Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior.", - CustomClassName("ThreeValuedLogicOr"), Binary, ResultType("O")), + new OpCode("3vl.bool.and", "Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior.", + CustomClassName("ThreeValuedBoolAnd"), Binary, ResultType("O")), + new OpCode("3vl.bool.or", "Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior.", + CustomClassName("ThreeValuedBoolOr"), Binary, ResultType("O")), new OpCode("nullable.unwrap", "The input operand must be one of:" + Environment.NewLine + " 1. a nullable value type" + Environment.NewLine + " 2. a reference type" + Environment.NewLine @@ -279,6 +279,16 @@ CustomClassName("ExpressionTreeCast"), Unary, HasTypeOperand, MayThrow, CustomConstructor, CustomWriteTo, ResultType("type.GetStackType()"), MatchCondition("this.IsChecked == o.IsChecked")), + new OpCode("user.logic.op", "Use of user-defined && or || operator.", + CustomClassName("UserDefinedLogicOperator"), + HasMethodOperand, ResultType("O"), + CustomChildren(new []{ + new ChildInfo("left") { CanInlineInto = true }, + new ChildInfo("right") { CanInlineInto = false } // only executed depending on value of left + }), + CustomComputeFlags // MayThrow, SideEffect, ControlFlow + ), + new OpCode("dynamic.binary.operator", "ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation).", CustomClassName("DynamicBinaryOperatorInstruction"), Dynamic, CustomArguments(("left", null), ("right", null)), CustomWriteTo), new OpCode("dynamic.unary.operator", "ILAst representation of a unary operator inside a dynamic expression (maps to Binder.UnaryOperation).", diff --git a/ICSharpCode.Decompiler/IL/Instructions/ThreeValuedLogicInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs similarity index 78% rename from ICSharpCode.Decompiler/IL/Instructions/ThreeValuedLogicInstructions.cs rename to ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs index 9d85403d7..b62c67216 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ThreeValuedLogicInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs @@ -23,7 +23,7 @@ namespace ICSharpCode.Decompiler.IL // Note: The comp instruction also supports three-valued logic via ComparisonLiftingKind.ThreeValuedLogic. // comp.i4.lifted[3VL](x == ldc.i4 0) is used to represent a lifted logic.not. - partial class ThreeValuedLogicAnd : ILiftableInstruction + partial class ThreeValuedBoolAnd : ILiftableInstruction { bool ILiftableInstruction.IsLifted => true; StackType ILiftableInstruction.UnderlyingResultType => StackType.I4; @@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler.IL } } - partial class ThreeValuedLogicOr : ILiftableInstruction + partial class ThreeValuedBoolOr : ILiftableInstruction { bool ILiftableInstruction.IsLifted => true; StackType ILiftableInstruction.UnderlyingResultType => StackType.I4; @@ -46,4 +46,20 @@ namespace ICSharpCode.Decompiler.IL Debug.Assert(Left.ResultType == StackType.I4 || Left.ResultType == StackType.O); } } + + partial class UserDefinedLogicOperator + { + protected override InstructionFlags ComputeFlags() + { + // left is always executed; right only sometimes + return DirectFlags | left.Flags + | SemanticHelper.CombineBranches(InstructionFlags.None, right.Flags); + } + + public override InstructionFlags DirectFlags { + get { + return InstructionFlags.MayThrow | InstructionFlags.SideEffect | InstructionFlags.ControlFlow; + } + } + } } diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index c63dd5b2e..31fb157af 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -371,7 +371,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms { type = NullableType.GetUnderlyingType(type); while (type is ModifiedType || type is PinnedType) { - type = ((TypeWithElementType)type).ElementType; + type = NullableType.GetUnderlyingType(((TypeWithElementType)type).ElementType); } string name; diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index 515d21a15..96f76a11e 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -333,6 +333,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (TransformDynamicAddAssignOrRemoveAssign(inst)) return; + if (inst.MatchIfInstructionPositiveCondition(out var condition, out var trueInst, out var falseInst)) { + ILInstruction transformed = UserDefinedLogicTransform.Transform(condition, trueInst, falseInst); + if (transformed != null) { + context.Step("User-defined short-circuiting logic operator (roslyn pattern)", condition); + transformed.AddILRange(inst.ILRange); + inst.ReplaceWith(transformed); + return; + } + } } /// diff --git a/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs b/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs index 3b535899e..b33cc0ba0 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs @@ -350,6 +350,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms break; case OpCode.NullableUnwrap: return true; // inline into ?. operator + case OpCode.UserDefinedLogicOperator: + return true; // inline into (left slot of) user-defined && or || operator case OpCode.DynamicGetMemberInstruction: case OpCode.DynamicGetIndexInstruction: case OpCode.LdObj: diff --git a/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs index 92ddf4dad..deb8f7da4 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs @@ -225,19 +225,19 @@ namespace ICSharpCode.Decompiler.IL.Transforms { // condition ? v : (bool?)false // => condition & v - context.Step("NullableLiftingTransform: 3vl.logic.and(bool, bool?)", ifInst); - return new ThreeValuedLogicAnd(condition, trueInst) { ILRange = ifInst.ILRange }; + context.Step("NullableLiftingTransform: 3vl.bool.and(bool, bool?)", ifInst); + return new ThreeValuedBoolAnd(condition, trueInst) { ILRange = ifInst.ILRange }; } if (falseInst.MatchLdLoc(out var v2)) { // condition ? v : v2 if (MatchThreeValuedLogicConditionPattern(condition, out var nullable1, out var nullable2)) { // (nullable1.GetValueOrDefault() || (!nullable2.GetValueOrDefault() && !nullable1.HasValue)) ? v : v2 if (v == nullable1 && v2 == nullable2) { - context.Step("NullableLiftingTransform: 3vl.logic.or(bool?, bool?)", ifInst); - return new ThreeValuedLogicOr(trueInst, falseInst) { ILRange = ifInst.ILRange }; + context.Step("NullableLiftingTransform: 3vl.bool.or(bool?, bool?)", ifInst); + return new ThreeValuedBoolOr(trueInst, falseInst) { ILRange = ifInst.ILRange }; } else if (v == nullable2 && v2 == nullable1) { - context.Step("NullableLiftingTransform: 3vl.logic.and(bool?, bool?)", ifInst); - return new ThreeValuedLogicAnd(falseInst, trueInst) { ILRange = ifInst.ILRange }; + context.Step("NullableLiftingTransform: 3vl.bool.and(bool?, bool?)", ifInst); + return new ThreeValuedBoolAnd(falseInst, trueInst) { ILRange = ifInst.ILRange }; } } } @@ -247,7 +247,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms // condition ? (bool?)true : v // => condition | v context.Step("NullableLiftingTransform: 3vl.logic.or(bool, bool?)", ifInst); - return new ThreeValuedLogicOr(condition, falseInst) { ILRange = ifInst.ILRange }; + return new ThreeValuedBoolOr(condition, falseInst) { ILRange = ifInst.ILRange }; } } return null; diff --git a/ICSharpCode.Decompiler/IL/Transforms/UserDefinedLogicTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/UserDefinedLogicTransform.cs new file mode 100644 index 000000000..43c882d10 --- /dev/null +++ b/ICSharpCode.Decompiler/IL/Transforms/UserDefinedLogicTransform.cs @@ -0,0 +1,150 @@ +// Copyright (c) 2018 Daniel Grunwald +// +// 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. + +using System; +using System.Collections.Generic; +using System.Text; + +namespace ICSharpCode.Decompiler.IL.Transforms +{ + class UserDefinedLogicTransform : IStatementTransform + { + void IStatementTransform.Run(Block block, int pos, StatementTransformContext context) + { + if (LegacyPattern(block, pos, context)) + return; + if (RoslynOptimized(block, pos, context)) + return; + } + + bool RoslynOptimized(Block block, int pos, StatementTransformContext context) + { + // Roslyn, optimized pattern in combination with return statement: + // if (logic.not(call op_False(ldloc lhsVar))) leave IL_0000 (call op_BitwiseAnd(ldloc lhsVar, rhsInst)) + // leave IL_0000(ldloc lhsVar) + // -> + // user.logic op_BitwiseAnd(ldloc lhsVar, rhsInst) + if (!block.Instructions[pos].MatchIfInstructionPositiveCondition(out var condition, out var trueInst, out var falseInst)) + return false; + if (trueInst.OpCode == OpCode.Nop) { + trueInst = block.Instructions[pos + 1]; + } else if (falseInst.OpCode == OpCode.Nop) { + falseInst = block.Instructions[pos + 1]; + } else { + return false; + } + if (trueInst.MatchReturn(out var trueValue) && falseInst.MatchReturn(out var falseValue)) { + var transformed = Transform(condition, trueValue, falseValue); + if (transformed != null) { + context.Step("User-defined short-circuiting logic operator (optimized return)", condition); + ((Leave)block.Instructions[pos + 1]).Value = transformed; + block.Instructions.RemoveAt(pos); + return true; + } + } + return false; + } + + bool LegacyPattern(Block block, int pos, StatementTransformContext context) + { + // Legacy csc pattern: + // stloc s(lhsInst) + // if (logic.not(call op_False(ldloc s))) Block { + // stloc s(call op_BitwiseAnd(ldloc s, rhsInst)) + // } + // -> + // stloc s(user.logic op_BitwiseAnd(lhsInst, rhsInst)) + if (!block.Instructions[pos].MatchStLoc(out var s, out var lhsInst)) + return false; + if (!(s.Kind == VariableKind.StackSlot)) + return false; + if (!(block.Instructions[pos + 1] is IfInstruction ifInst)) + return false; + if (!ifInst.Condition.MatchLogicNot(out var condition)) + return false; + if (!(MatchCondition(condition, out var s2, out string conditionMethodName) && s2 == s)) + return false; + if (ifInst.FalseInst.OpCode != OpCode.Nop) + return false; + var trueInst = Block.Unwrap(ifInst.TrueInst); + if (!trueInst.MatchStLoc(s, out var storeValue)) + return false; + if (storeValue is Call call) { + if (!MatchBitwiseCall(call, s, conditionMethodName)) + return false; + if (s.IsUsedWithin(call.Arguments[1])) + return false; + context.Step("User-defined short-circuiting logic operator (legacy pattern)", condition); + ((StLoc)block.Instructions[pos]).Value = new UserDefinedLogicOperator(call.Method, lhsInst, call.Arguments[1]) { + ILRange = call.ILRange + }; + block.Instructions.RemoveAt(pos + 1); + context.RequestRerun(); // the 'stloc s' may now be eligible for inlining + return true; + } + return false; + } + + static bool MatchCondition(ILInstruction condition, out ILVariable v, out string name) + { + v = null; + name = null; + if (!(condition is Call call && call.Method.IsOperator && call.Arguments.Count == 1 && !call.IsLifted)) + return false; + name = call.Method.Name; + if (!(name == "op_True" || name == "op_False")) + return false; + return call.Arguments[0].MatchLdLoc(out v); + } + + static bool MatchBitwiseCall(Call call, ILVariable v, string conditionMethodName) + { + if (!(call != null && call.Method.IsOperator && call.Arguments.Count == 2 && !call.IsLifted)) + return false; + if (!call.Arguments[0].MatchLdLoc(v)) + return false; + + return conditionMethodName == "op_False" && call.Method.Name == "op_BitwiseAnd" + || conditionMethodName == "op_True" && call.Method.Name == "op_BitwiseOr"; + } + + /// + /// if (call op_False(ldloc lhsVar)) ldloc lhsVar else call op_BitwiseAnd(ldloc lhsVar, rhsInst) + /// -> user.logic op_BitwiseAnd(ldloc lhsVar, rhsInst) + /// or + /// if (call op_True(ldloc lhsVar)) ldloc lhsVar else call op_BitwiseOr(ldloc lhsVar, rhsInst) + /// -> user.logic op_BitwiseOr(ldloc lhsVar, rhsInst) + /// + public static ILInstruction Transform(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst) + { + if (!MatchCondition(condition, out var lhsVar, out var conditionMethodName)) + return null; + if (!trueInst.MatchLdLoc(lhsVar)) + return null; + var call = falseInst as Call; + if (!MatchBitwiseCall(call, lhsVar, conditionMethodName)) + return null; + + var result = new UserDefinedLogicOperator(call.Method, call.Arguments[0], call.Arguments[1]); + result.AddILRange(condition.ILRange); + result.AddILRange(trueInst.ILRange); + result.AddILRange(call.ILRange); + return result; + } + } +}