From bdd2941a03670b8677b70262755556f61896e378 Mon Sep 17 00:00:00 2001 From: coehlrich Date: Sun, 5 May 2024 15:00:12 +1200 Subject: [PATCH] Fix default case not always being last --- .../SwitchPatternMatchProcessor.java | 20 ++ .../java/decompiler/SingleClassesTest.java | 1 + .../pkg/TestSwitchPatternMatching19.dec | 151 ++++++++------- .../pkg/TestSwitchPatternMatching21.dec | 174 +++++++++--------- .../pkg/TestSwitchPatternMatchingJ21.dec | 68 +++++++ .../pkg/TestSwitchPatternMatchingJ21.java | 10 + 6 files changed, 261 insertions(+), 163 deletions(-) create mode 100644 testData/results/pkg/TestSwitchPatternMatchingJ21.dec create mode 100644 testData/src/java21/pkg/TestSwitchPatternMatchingJ21.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java index 3f526e824..daa4a5320 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java @@ -186,6 +186,26 @@ private static boolean processStatement(SwitchStatement stat, Statement root) { } } + for (int i = 0; i < stat.getCaseValues().size(); i++) { + if (stat.getCaseValues().get(i).contains(null)) { + // Default case statements are required to be last + stat.getCaseValues().add(stat.getCaseValues().remove(i)); + stat.getCaseStatements().add(stat.getCaseStatements().remove(i)); + stat.getCaseEdges().add(stat.getCaseEdges().remove(i)); + if (i < stat.getCaseGuards().size()) { + if (stat.getCaseGuards().get(i) != null) { + while (stat.getCaseGuards().size() < stat.getCaseStatements().size()) { + stat.getCaseGuards().add(null); + } + stat.getCaseGuards().add(stat.getCaseGuards().remove(i)); + } else { + stat.getCaseGuards().remove(i); + } + } + break; + } + } + // go through bootstrap arguments to ensure types are correct & add enum/integer/string constants for (int i = 0; i < value.getBootstrapArguments().size(); i++) { PooledConstant bsa = value.getBootstrapArguments().get(i); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index da4bb8d68..c80934709 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -704,6 +704,7 @@ private void registerDefault() { register(JAVA_21, "TestInnerClasses3J21"); register(JAVA_8, "TestInnerClassesJ8"); register(JAVA_8, "TestSwitchInTry"); + register(JAVA_21, "TestSwitchPatternMatchingJ21"); } private void registerEntireClassPath() { diff --git a/testData/results/pkg/TestSwitchPatternMatching19.dec b/testData/results/pkg/TestSwitchPatternMatching19.dec index 6661b91b7..76a5a64f1 100644 --- a/testData/results/pkg/TestSwitchPatternMatching19.dec +++ b/testData/results/pkg/TestSwitchPatternMatching19.dec @@ -5,10 +5,6 @@ public class TestSwitchPatternMatching19 { static void test(TestSwitchPatternMatching19.XXX s) { var1; switch (s) {// 5 - case null: - default: - System.out.println("f");// 11 - break; case X1: System.out.println("x1");// 6 break; @@ -22,6 +18,10 @@ public class TestSwitchPatternMatching19 { System.out.println("d"); break; case TestSwitchPatternMatching19.XXX var11 when false: + break; + case null: + default: + System.out.println("f");// 11 } }// 13 @@ -114,73 +114,72 @@ class 'pkg/TestSwitchPatternMatching19' { 2d 6 2e 6 2f 6 - 30 12 - 31 12 - 32 12 - 33 12 - 34 12 - 35 12 - 36 12 - 37 12 - 38 13 - 3b 14 - 3d 14 - 3e 14 - 3f 14 - 40 14 - 41 14 - 42 14 - 43 14 - 49 15 - 4a 15 - 4b 15 - 4c 15 - 4d 15 - 4e 15 - 4f 15 - 50 15 - 51 16 - 54 17 - 57 17 - 58 17 - 59 17 - 5a 17 - 5b 17 - 64 18 - 65 18 - 66 18 - 67 18 - 68 18 - 69 18 - 6a 18 - 6b 18 - 6c 19 - 6f 20 - 72 20 - 73 20 - 74 20 - 75 20 - 76 20 - 77 20 - 78 20 - 7e 21 - 7f 21 - 80 21 - 81 21 - 82 21 - 83 21 - 84 21 - 85 21 - 86 22 - 94 9 - 95 9 - 96 9 - 97 9 - 98 9 - 99 9 - 9a 9 - 9b 9 - 9c 10 + 30 8 + 31 8 + 32 8 + 33 8 + 34 8 + 35 8 + 36 8 + 37 8 + 38 9 + 3b 10 + 3d 10 + 3e 10 + 3f 10 + 40 10 + 41 10 + 42 10 + 43 10 + 49 11 + 4a 11 + 4b 11 + 4c 11 + 4d 11 + 4e 11 + 4f 11 + 50 11 + 51 12 + 54 13 + 57 13 + 58 13 + 59 13 + 5a 13 + 5b 13 + 64 14 + 65 14 + 66 14 + 67 14 + 68 14 + 69 14 + 6a 14 + 6b 14 + 6c 15 + 6f 16 + 72 16 + 73 16 + 74 16 + 75 16 + 76 16 + 77 16 + 78 16 + 7e 17 + 7f 17 + 80 17 + 81 17 + 82 17 + 83 17 + 84 17 + 85 17 + 86 18 + 94 23 + 95 23 + 96 23 + 97 23 + 98 23 + 99 23 + 9a 23 + 9b 23 9f 25 } @@ -262,11 +261,11 @@ class 'pkg/TestSwitchPatternMatching19' { Lines mapping: 5 <-> 7 -6 <-> 13 -7 <-> 15 -8 <-> 18 -9 <-> 21 -11 <-> 10 +6 <-> 9 +7 <-> 11 +8 <-> 14 +9 <-> 17 +11 <-> 24 13 <-> 26 16 <-> 29 17 <-> 35 diff --git a/testData/results/pkg/TestSwitchPatternMatching21.dec b/testData/results/pkg/TestSwitchPatternMatching21.dec index e94a79326..2e99a40bd 100644 --- a/testData/results/pkg/TestSwitchPatternMatching21.dec +++ b/testData/results/pkg/TestSwitchPatternMatching21.dec @@ -30,10 +30,6 @@ public class TestSwitchPatternMatching21 { public void test2(String it) { switch (it) {// 19 - case null: - default: - System.out.println(it + "?");// 26 27 - break; case "": System.out.println("nothing");// 20 break; @@ -45,6 +41,10 @@ public class TestSwitchPatternMatching21 { break; case String var8 when Math.random() > 0.0: System.out.println(it + "!!");// 24 25 + break; + case null: + default: + System.out.println(it + "?");// 26 27 } }// 29 @@ -236,81 +236,81 @@ class 'pkg/TestSwitchPatternMatching21' { 29 31 2a 31 2b 31 - 2c 37 - 2d 37 - 2e 37 - 2f 37 - 30 37 - 31 37 - 32 37 - 33 37 - 34 38 - 37 40 - 38 40 - 39 40 - 3a 40 - 3b 40 - 3c 40 - 3d 40 - 3e 40 - 3f 41 - 42 43 - 45 42 - 46 42 - 47 42 - 48 42 - 49 42 - 52 43 - 53 43 - 54 43 - 55 43 - 56 43 - 57 43 - 58 43 - 59 43 - 5a 43 - 5b 43 - 5c 43 - 5d 43 - 5e 43 - 5f 44 - 62 46 - 65 45 - 66 45 - 67 45 - 68 45 - 69 45 - 6a 45 - 6b 45 - 6c 45 - 72 46 - 73 46 - 74 46 - 75 46 - 76 46 - 77 46 - 78 46 - 79 46 - 7a 46 - 7b 46 - 7c 46 - 7d 46 - 7e 46 - 82 34 - 85 34 - 86 34 - 87 34 - 88 34 - 89 34 - 8a 34 - 8b 34 - 8c 34 - 8d 34 - 8e 34 - 8f 34 - 90 34 - 91 34 - 92 35 + 2c 33 + 2d 33 + 2e 33 + 2f 33 + 30 33 + 31 33 + 32 33 + 33 33 + 34 34 + 37 36 + 38 36 + 39 36 + 3a 36 + 3b 36 + 3c 36 + 3d 36 + 3e 36 + 3f 37 + 42 39 + 45 38 + 46 38 + 47 38 + 48 38 + 49 38 + 52 39 + 53 39 + 54 39 + 55 39 + 56 39 + 57 39 + 58 39 + 59 39 + 5a 39 + 5b 39 + 5c 39 + 5d 39 + 5e 39 + 5f 40 + 62 42 + 65 41 + 66 41 + 67 41 + 68 41 + 69 41 + 6a 41 + 6b 41 + 6c 41 + 72 42 + 73 42 + 74 42 + 75 42 + 76 42 + 77 42 + 78 42 + 79 42 + 7a 42 + 7b 42 + 7c 42 + 7d 42 + 7e 42 + 7f 43 + 82 46 + 85 46 + 86 46 + 87 46 + 88 46 + 89 46 + 8a 46 + 8b 46 + 8c 46 + 8d 46 + 8e 46 + 8f 46 + 90 46 + 91 46 95 48 } @@ -409,14 +409,14 @@ Lines mapping: 14 <-> 27 16 <-> 29 19 <-> 32 -20 <-> 38 -21 <-> 41 -22 <-> 44 -23 <-> 44 -24 <-> 47 -25 <-> 47 -26 <-> 35 -27 <-> 35 +20 <-> 34 +21 <-> 37 +22 <-> 40 +23 <-> 40 +24 <-> 43 +25 <-> 43 +26 <-> 47 +27 <-> 47 29 <-> 49 32 <-> 52 33 <-> 55 diff --git a/testData/results/pkg/TestSwitchPatternMatchingJ21.dec b/testData/results/pkg/TestSwitchPatternMatchingJ21.dec new file mode 100644 index 000000000..f578579d4 --- /dev/null +++ b/testData/results/pkg/TestSwitchPatternMatchingJ21.dec @@ -0,0 +1,68 @@ +package pkg; + +public class TestSwitchPatternMatchingJ21 { + public void test1(Object o) { + System.out.println(switch (o) {// 5 + case Integer i -> Integer.toString(i);// 6 + case null, default -> "null";// 7 + }); + }// 9 +} + +class 'pkg/TestSwitchPatternMatchingJ21' { + method 'test1 (Ljava/lang/Object;)V' { + 0 4 + 1 4 + 2 4 + 3 4 + 7 4 + e 4 + f 4 + 10 4 + 11 4 + 12 4 + 13 4 + 14 4 + 15 4 + 16 4 + 17 4 + 18 4 + 19 4 + 1a 4 + 1b 4 + 1c 4 + 1d 4 + 1e 4 + 1f 4 + 20 4 + 21 4 + 22 4 + 23 4 + 24 4 + 25 4 + 26 4 + 27 4 + 2c 5 + 2d 5 + 2e 5 + 2f 5 + 30 5 + 31 5 + 32 5 + 33 5 + 34 5 + 35 5 + 39 6 + 3a 6 + 3b 4 + 3c 4 + 3d 4 + 3e 8 + } +} + +Lines mapping: +5 <-> 5 +6 <-> 6 +7 <-> 7 +9 <-> 9 diff --git a/testData/src/java21/pkg/TestSwitchPatternMatchingJ21.java b/testData/src/java21/pkg/TestSwitchPatternMatchingJ21.java new file mode 100644 index 000000000..db6546abc --- /dev/null +++ b/testData/src/java21/pkg/TestSwitchPatternMatchingJ21.java @@ -0,0 +1,10 @@ +package pkg; + +public class TestSwitchPatternMatchingJ21 { + public void test1(Object o) { + System.out.println(switch (o) { + case Integer i -> Integer.toString(i); + case null, default -> "null"; + }); + } +}