diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
index c8e8d2721..34a3c4406 100644
--- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
+++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
@@ -92,6 +92,7 @@
+
diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
index c5687aa85..fdfc29d62 100644
--- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
@@ -493,6 +493,12 @@ namespace ICSharpCode.Decompiler.Tests
RunForLibrary(cscOptions: cscOptions);
}
+ [Test]
+ public void DeconstructionTests([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
+ {
+ RunForLibrary(cscOptions: cscOptions);
+ }
+
void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings);
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs
new file mode 100644
index 000000000..8d834ef7b
--- /dev/null
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs
@@ -0,0 +1,101 @@
+// Copyright (c) 2020 Siegfried Pammer
+//
+// 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.Runtime.InteropServices;
+
+namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
+{
+ internal class DeconstructionTests
+ {
+ private class CustomDeconstructionAndConversion
+ {
+ [StructLayout(LayoutKind.Sequential, Size = 1)]
+ public struct MyInt
+ {
+ public static implicit operator int(MyInt x)
+ {
+ return 0;
+ }
+
+ public static implicit operator MyInt(int x)
+ {
+ return default(MyInt);
+ }
+ }
+
+ public int IntField;
+
+ public int? NullableIntField;
+
+ public MyInt MyIntField;
+
+ public MyInt? NullableMyIntField;
+
+ public int Int {
+ get;
+ set;
+ }
+
+ public int? NInt {
+ get;
+ set;
+ }
+
+ public MyInt My {
+ get;
+ set;
+ }
+
+ public MyInt? NMy {
+ get;
+ set;
+ }
+
+ public void Deconstruct(out MyInt? x, out MyInt y)
+ {
+ x = null;
+ y = default(MyInt);
+ }
+
+ public CustomDeconstructionAndConversion GetValue()
+ {
+ return null;
+ }
+
+ public CustomDeconstructionAndConversion Get(int i)
+ {
+ return null;
+ }
+
+ private MyInt? GetNullableMyInt()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Test7()
+ {
+ MyInt? myInt3;
+ MyInt x;
+ (myInt3, x) = GetValue();
+ Console.WriteLine(myInt3);
+ Console.WriteLine(x);
+ }
+ }
+ }
+}
diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs
index e1b158b0a..36bd2534a 100644
--- a/ICSharpCode.Decompiler/DecompilerSettings.cs
+++ b/ICSharpCode.Decompiler/DecompilerSettings.cs
@@ -93,6 +93,7 @@ namespace ICSharpCode.Decompiler
tupleConversions = false;
discards = false;
localFunctions = false;
+ deconstruction = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp7_2) {
introduceReadonlyAndInModifiers = false;
@@ -1106,6 +1107,23 @@ namespace ICSharpCode.Decompiler
}
}
+ bool deconstruction = true;
+
+ ///
+ /// Gets/Sets whether C# 7.0 deconstruction should be detected.
+ ///
+ [Category("C# 7.0 / VS 2017")]
+ [Description("DecompilerSettings.Deconstruction")]
+ public bool Deconstruction {
+ get { return deconstruction; }
+ set {
+ if (deconstruction != value) {
+ deconstruction = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
bool staticLocalFunctions = true;
///
@@ -1126,7 +1144,7 @@ namespace ICSharpCode.Decompiler
bool ranges = true;
///
- /// Gets/Sets whether C# 8.0 static local functions should be transformed.
+ /// Gets/Sets whether C# 8.0 index and range syntax should be used.
///
[Category("C# 8.0 / VS 2019")]
[Description("DecompilerSettings.Ranges")]
diff --git a/ICSharpCode.Decompiler/IL/Transforms/DeconstructionTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/DeconstructionTransform.cs
index b3322f31e..3a33a5b02 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/DeconstructionTransform.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/DeconstructionTransform.cs
@@ -18,12 +18,6 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Text;
-
-using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.IL.Transforms
@@ -62,8 +56,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
* */
void IStatementTransform.Run(Block block, int pos, StatementTransformContext context)
{
- //if (!context.Settings.Deconstruction)
- // return;
+ if (!context.Settings.Deconstruction)
+ return;
try {
this.context = context;
diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs
index 84a05cf4c..6ede5d22a 100644
--- a/ILSpy/Properties/Resources.Designer.cs
+++ b/ILSpy/Properties/Resources.Designer.cs
@@ -765,6 +765,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to Detect deconstruction assignments.
+ ///
+ public static string DecompilerSettings_Deconstruction {
+ get {
+ return ResourceManager.GetString("DecompilerSettings.Deconstruction", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Detect awaited using and foreach statements.
///
diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx
index 62a8ffa83..6a979b29d 100644
--- a/ILSpy/Properties/Resources.resx
+++ b/ILSpy/Properties/Resources.resx
@@ -879,4 +879,7 @@ Do you want to continue?
Base Types
+
+ Detect deconstruction assignments
+
\ No newline at end of file