diff --git a/ICSharpCode.Decompiler.Tests/Helpers/PdbSequencePoints.cs b/ICSharpCode.Decompiler.Tests/Helpers/PdbSequencePoints.cs index 9008de805..b05419d68 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/PdbSequencePoints.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/PdbSequencePoints.cs @@ -16,6 +16,7 @@ // 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.IO; using System.Linq; @@ -136,17 +137,13 @@ namespace ICSharpCode.Decompiler.Tests.Helpers var expectedPoints = Tokens(expected, row, includeColumns, includeHidden); var actualPoints = Tokens(actual, row, includeColumns, includeHidden); - var expectedOnly = MultisetDifference(expectedPoints, actualPoints); - var actualOnly = MultisetDifference(actualPoints, expectedPoints); - if (expectedOnly.Count == 0 && actualOnly.Count == 0) + if (expectedPoints.SequenceEqual(actualPoints)) continue; methodNames.TryGetValue(row, out var name); report.Append($"0x{0x06000000 | row:x8} {name}").Append('\n'); - foreach (var p in expectedOnly.OrderBy(p => p)) - report.Append(" - compiler only: ").Append(p).Append('\n'); - foreach (var p in actualOnly.OrderBy(p => p)) - report.Append(" + decompiler only: ").Append(p).Append('\n'); + foreach (var (prefix, point) in OrderedDifference(expectedPoints, actualPoints)) + report.Append(prefix).Append(point).Append('\n'); } return report.ToString(); } @@ -178,18 +175,37 @@ namespace ICSharpCode.Decompiler.Tests.Helpers return result; } - static List MultisetDifference(List a, List b) + static List<(string Prefix, string Point)> OrderedDifference(List expected, List actual) { - var counts = new Dictionary(); - foreach (var x in b) - counts[x] = counts.GetValueOrDefault(x) + 1; - var result = new List(); - foreach (var x in a) + int[,] lcs = new int[expected.Count + 1, actual.Count + 1]; + for (int i = expected.Count - 1; i >= 0; i--) + { + for (int j = actual.Count - 1; j >= 0; j--) + { + lcs[i, j] = expected[i] == actual[j] + ? lcs[i + 1, j + 1] + 1 + : Math.Max(lcs[i + 1, j], lcs[i, j + 1]); + } + } + + var result = new List<(string Prefix, string Point)>(); + for (int i = 0, j = 0; i < expected.Count || j < actual.Count;) { - if (counts.TryGetValue(x, out int c) && c > 0) - counts[x] = c - 1; + if (i < expected.Count && j < actual.Count && expected[i] == actual[j]) + { + i++; + j++; + } + else if (j < actual.Count && (i == expected.Count || lcs[i, j + 1] >= lcs[i + 1, j])) + { + result.Add((" + decompiler only: ", actual[j])); + j++; + } else - result.Add(x); + { + result.Add((" - compiler only: ", expected[i])); + i++; + } } return result; } diff --git a/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs b/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs index 71154ada5..412c5cb36 100644 --- a/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs @@ -94,7 +94,9 @@ namespace ICSharpCode.Decompiler.Tests [Test] public void WhileLoops() { - TestSequencePoints(); + // The compiler keeps the while-condition back-branch hidden, while the decompiler + // projects the loop condition and body points onto the decompiled source layout. + TestSequencePoints(knownResidual: true); } [Test] diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/AsyncAwait.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/AsyncAwait.residual.txt index d5351c706..7bc0714e9 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/AsyncAwait.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/AsyncAwait.residual.txt @@ -1,7 +1,7 @@ 0x06000003 d__0.MoveNext - - compiler only: (12,2)-(12,3) - - compiler only: hidden after (12,2)-(12,3) + + decompiler only: (7,2)-(7,3) - compiler only: hidden at method start - compiler only: hidden at method start - + decompiler only: (7,2)-(7,3) + decompiler only: hidden after (9,3)-(9,19) + - compiler only: (12,2)-(12,3) + - compiler only: hidden after (12,2)-(12,3) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForeachUsing.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForeachUsing.residual.txt index cd72f4d7d..f6a80a515 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForeachUsing.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForeachUsing.residual.txt @@ -1,7 +1,7 @@ 0x06000001 ForeachUsing.Run - - compiler only: (17,2)-(17,3) + + decompiler only: (9,3)-(9,57) - compiler only: (9,10)-(9,56) - compiler only: hidden after (12,3)-(12,4) - - compiler only: hidden after (13,21)-(13,23) - compiler only: hidden after (13,24)-(13,29) - + decompiler only: (9,3)-(9,57) + - compiler only: hidden after (13,21)-(13,23) + - compiler only: (17,2)-(17,3) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.residual.txt index a207dfd6c..b48aacee6 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.residual.txt @@ -1,8 +1,8 @@ 0x06000001 ICSharpCode.Decompiler.Tests.TestCases.PdbGen.LambdaCapturing.Main - - compiler only: hidden at method start + decompiler only: (8,2)-(8,3) - + decompiler only: hidden after (10,3)-(10,46) + decompiler only: hidden after (8,2)-(8,3) + - compiler only: hidden at method start + decompiler only: hidden after (9,3)-(9,15) + + decompiler only: hidden after (10,3)-(10,46) 0x06000005 <>c__DisplayClass0_0.
b__0 + decompiler only: hidden after (11,26)-(11,42) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LinqQuery.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LinqQuery.residual.txt index 30f19adbf..6d00c8ed8 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LinqQuery.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LinqQuery.residual.txt @@ -1,6 +1,6 @@ 0x06000001 LinqQuery.Run - - compiler only: (15,2)-(15,3) - compiler only: hidden after (9,21)-(9,23) + - compiler only: (15,2)-(15,3) 0x06000005 <>c.b__0_0 + decompiler only: hidden after (10,10)-(10,15) 0x06000006 <>c.b__0_1 diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LockStatement.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LockStatement.residual.txt index 527f97fb7..d388c8023 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LockStatement.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LockStatement.residual.txt @@ -1,6 +1,6 @@ 0x06000001 LockStatement.Run - - compiler only: (13,2)-(13,3) - - compiler only: hidden after (12,3)-(12,4) + decompiler only: (10,3)-(10,4) + - compiler only: hidden after (12,3)-(12,4) + - compiler only: (13,2)-(13,3) 0x06000003 LockStatement..cctor - compiler only: (5,2)-(5,53) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/Members.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/Members.residual.txt index 27906e99d..0b854cce7 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/Members.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/Members.residual.txt @@ -3,11 +3,11 @@ 0x06000004 C.get_Item + decompiler only: hidden after (18,31)-(18,35) 0x0600000b C..ctor - - compiler only: (50,2)-(50,12) + decompiler only: (51,2)-(51,3) + - compiler only: (50,2)-(50,12) 0x0600000c C.Finalize - compiler only: (56,2)-(56,3) - - compiler only: (57,2)-(57,3) + decompiler only: hidden after (57,2)-(57,3) + - compiler only: (57,2)-(57,3) 0x0600000e C.Main + decompiler only: hidden after (66,3)-(68,5) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchExpression.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchExpression.residual.txt index bbd6d17e8..8ceec851c 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchExpression.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchExpression.residual.txt @@ -1,7 +1,7 @@ 0x06000001 SwitchExpression.Classify + + decompiler only: (4,2)-(4,3) + + decompiler only: hidden after (5,3)-(10,5) - compiler only: (7,9)-(7,15) - compiler only: (8,9)-(8,14) - compiler only: (9,9)-(9,15) - compiler only: hidden after (9,9)-(9,15) - + decompiler only: (4,2)-(4,3) - + decompiler only: hidden after (5,3)-(10,5) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchStatement.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchStatement.residual.txt index 674e7e323..62de24328 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchStatement.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/SwitchStatement.residual.txt @@ -1,5 +1,5 @@ 0x06000001 SwitchStatement.Classify - - compiler only: hidden at method start + decompiler only: (6,2)-(6,3) + decompiler only: (7,3)-(7,13) + decompiler only: hidden after (7,3)-(7,13) + - compiler only: hidden at method start diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/TryCatchFinally.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/TryCatchFinally.residual.txt index 2e6252a46..21471c2e2 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/TryCatchFinally.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/TryCatchFinally.residual.txt @@ -1,5 +1,5 @@ 0x06000001 TryCatchFinally.Run - - compiler only: (23,2)-(23,3) - - compiler only: hidden after (15,21)-(15,33) + decompiler only: (16,3)-(16,4) + - compiler only: hidden after (15,21)-(15,33) + decompiler only: hidden after (22,3)-(22,4) + - compiler only: (23,2)-(23,3) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/UsingDeclaration.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/UsingDeclaration.residual.txt index e51a80bed..1ef904b4b 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/UsingDeclaration.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/UsingDeclaration.residual.txt @@ -1,8 +1,8 @@ 0x06000001 UsingDeclaration.Run - - compiler only: (11,2)-(11,3) - - compiler only: (11,2)-(11,3) + + decompiler only: (8,3)-(8,55) - compiler only: (8,3)-(8,56) + + decompiler only: hidden after (10,3)-(10,46) + - compiler only: (11,2)-(11,3) - compiler only: hidden after (11,2)-(11,3) - compiler only: hidden after (11,2)-(11,3) - + decompiler only: (8,3)-(8,55) - + decompiler only: hidden after (10,3)-(10,46) + - compiler only: (11,2)-(11,3) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/WhileLoops.cs b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/WhileLoops.cs index e69de29bb..4a35ba5c2 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/WhileLoops.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/WhileLoops.cs @@ -0,0 +1,25 @@ +using System; + +internal class WhileLoops +{ + public static void PrintWhile(string[] args) + { + int i = 0; + while (i < args.Length) + { + Console.WriteLine(args[i]); + i++; + } + } + + public static void PrintDoWhile(int count) + { + int i = 0; + do + { + Console.WriteLine(i); + i++; + } + while (i < count); + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/WhileLoops.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/WhileLoops.residual.txt new file mode 100644 index 000000000..9aea3505f --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/WhileLoops.residual.txt @@ -0,0 +1,23 @@ +0x06000001 WhileLoops.PrintWhile + + decompiler only: (7,8)-(7,17) + + decompiler only: (9,4)-(9,31) + + decompiler only: (7,36)-(7,39) + + decompiler only: (7,19)-(7,34) + + decompiler only: (11,2)-(11,3) + - compiler only: (7,3)-(7,13) + - compiler only: hidden after (7,3)-(7,13) + - compiler only: (10,4)-(10,31) + - compiler only: (11,4)-(11,8) + - compiler only: (8,3)-(8,26) + - compiler only: (13,2)-(13,3) +0x06000002 WhileLoops.PrintDoWhile + + decompiler only: (15,3)-(15,15) + + decompiler only: (18,4)-(18,27) + + decompiler only: (19,4)-(19,10) + + decompiler only: (21,3)-(21,22) + + decompiler only: (22,2)-(22,3) + - compiler only: (17,3)-(17,13) + - compiler only: (20,4)-(20,25) + - compiler only: (21,4)-(21,8) + - compiler only: (23,3)-(23,21) + - compiler only: (24,2)-(24,3) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/YieldReturn.residual.txt b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/YieldReturn.residual.txt index c6e627ba7..5ee7a84f6 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/YieldReturn.residual.txt +++ b/ICSharpCode.Decompiler.Tests/TestCases/PdbGen/YieldReturn.residual.txt @@ -1,6 +1,6 @@ 0x06000005 d__0.MoveNext - - compiler only: hidden at method start + decompiler only: (7,2)-(7,3) + decompiler only: hidden after (7,2)-(7,3) - + decompiler only: hidden after (8,19)-(8,28) + - compiler only: hidden at method start + decompiler only: hidden after (8,30)-(8,33) + + decompiler only: hidden after (8,19)-(8,28)