From c5de72147b405f6e8cbaef4fe0e4b67684717414 Mon Sep 17 00:00:00 2001 From: coehlrich Date: Thu, 18 Dec 2025 18:37:41 +1300 Subject: [PATCH 1/3] Fix primitives in patterns when the if statement has `false` --- .../decompiler/IfPatternMatchProcessor.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java index a51dceed57..5a79808143 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java @@ -474,17 +474,26 @@ record PatternStore(StructRecordComponent component, StructClass cl, VarType typ ok = true; } } - } else if (ifSt.getHeadexprent().getCondition() instanceof ConstExprent constExp && constExp.hasBooleanValue() && (int) constExp.getValue() == 1) { - BasicBlockStatement headStat = ifSt.getIfstat().getBasichead(); - List headExprents = headStat.getExprents(); - if (headExprents.size() >= 1 - && headExprents.get(0) instanceof AssignmentExprent assignment + } else if (ifSt.getHeadexprent().getCondition() instanceof ConstExprent constExp && constExp.hasBooleanValue()) { + BasicBlockStatement stat = null; + List exprents = null; + if ((int) constExp.getValue() == 1) { + stat = ifSt.getIfstat().getBasichead(); + exprents = stat.getExprents(); + } else if (stIdx + 1 < branch.getStats().size()) { + stat = branch.getStats().get(stIdx + 1).getBasichead(); + exprents = stat.getExprents(); + inverted = true; + } + + if (exprents.size() >= 1 + && exprents.get(0) instanceof AssignmentExprent assignment && assignment.getLeft() instanceof VarExprent store && assignment.getRight() instanceof VarExprent) { found = true; vars.put(c, store); ok = true; - List toRemove = remove.computeIfAbsent(headStat, block -> new ArrayList<>()); + List toRemove = remove.computeIfAbsent(stat, block -> new ArrayList<>()); toRemove.add(assignment); } } From 0dd690399aa015283c0536b77b23482524a2083d Mon Sep 17 00:00:00 2001 From: coehlrich Date: Thu, 18 Dec 2025 20:20:56 +1300 Subject: [PATCH 2/3] Add null check --- .../decompiler/modules/decompiler/IfPatternMatchProcessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java index 5a79808143..b2e5c1ca9e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/IfPatternMatchProcessor.java @@ -486,7 +486,8 @@ record PatternStore(StructRecordComponent component, StructClass cl, VarType typ inverted = true; } - if (exprents.size() >= 1 + if (stat != null + && exprents.size() >= 1 && exprents.get(0) instanceof AssignmentExprent assignment && assignment.getLeft() instanceof VarExprent store && assignment.getRight() instanceof VarExprent) { From 8313c331c5211b756a5b00390fcd6f410c9807d8 Mon Sep 17 00:00:00 2001 From: coehlrich Date: Fri, 19 Dec 2025 13:21:39 +1300 Subject: [PATCH 3/3] Add test --- .../pkg/TestSwitchPatternMatchingJ25.dec | 677 ++++++++++-------- .../pkg/TestSwitchPatternMatchingJ25.java | 10 + 2 files changed, 387 insertions(+), 300 deletions(-) diff --git a/testData/results/pkg/TestSwitchPatternMatchingJ25.dec b/testData/results/pkg/TestSwitchPatternMatchingJ25.dec index 361a5c9432..6ec639d261 100644 --- a/testData/results/pkg/TestSwitchPatternMatchingJ25.dec +++ b/testData/results/pkg/TestSwitchPatternMatchingJ25.dec @@ -1,5 +1,6 @@ package pkg; +import java.util.Objects; import java.util.function.Supplier; public class TestSwitchPatternMatchingJ25 { @@ -55,328 +56,404 @@ public class TestSwitchPatternMatchingJ25 { }; } + public String test6(Object o) { + Objects.requireNonNull(o); + Object var2 = o; + + while (true) { + return switch (var2) {// 61 + case TestSwitchPatternMatchingJ25.Test6a(int i) -> Integer.toString(i);// 62 + case TestSwitchPatternMatchingJ25.Test6b(int ix) -> Integer.toString(ix);// 63 + default -> throw new RuntimeException();// 64 + }; + } + } + record Test5(Object o) { } + + record Test6a(int i) { + } + + record Test6b(int i) { + } } class 'pkg/TestSwitchPatternMatchingJ25' { method 'test1 (Ljava/lang/Object;)V' { - 0 8 - 1 8 - 2 8 - 3 8 - e 8 - f 8 - 10 8 - 11 8 - 12 8 - 13 8 - 14 8 - 15 8 - 16 8 - 17 8 - 18 8 - 19 8 - 1a 8 - 1b 8 - 1c 8 - 1d 8 - 1e 8 - 1f 8 - 20 8 - 21 8 - 22 8 - 23 8 - 24 8 - 25 8 - 26 8 - 27 8 - 2c 9 - 2d 9 - 2e 9 - 2f 9 - 30 9 - 31 9 - 32 9 - 33 9 - 34 9 - 35 9 - 39 10 - 3a 10 - 3b 8 - 3c 8 - 3d 8 - 3e 12 + 0 9 + 1 9 + 2 9 + 3 9 + e 9 + f 9 + 10 9 + 11 9 + 12 9 + 13 9 + 14 9 + 15 9 + 16 9 + 17 9 + 18 9 + 19 9 + 1a 9 + 1b 9 + 1c 9 + 1d 9 + 1e 9 + 1f 9 + 20 9 + 21 9 + 22 9 + 23 9 + 24 9 + 25 9 + 26 9 + 27 9 + 2c 10 + 2d 10 + 2e 10 + 2f 10 + 30 10 + 31 10 + 32 10 + 33 10 + 34 10 + 35 10 + 39 11 + 3a 11 + 3b 9 + 3c 9 + 3d 9 + 3e 13 } method 'test2 (Ljava/lang/Object;)Ljava/lang/String;' { - 0 15 - 10 15 - 11 15 - 12 15 - 13 15 - 14 15 - 15 15 - 16 15 - 17 15 - 18 15 - 19 15 - 1a 15 - 1b 15 - 1c 15 - 1d 15 - 1e 15 - 1f 15 - 20 15 - 21 15 - 22 15 - 23 15 - 24 15 - 25 15 - 26 15 - 27 15 - 28 15 - 29 15 - 2a 15 - 2b 15 - 30 16 - 31 16 - 32 16 - 33 16 - 34 16 - 35 16 - 36 16 - 37 16 - 38 16 - 39 16 - 41 17 - 42 17 - 43 17 - 44 17 - 48 18 - 49 18 - 4a 15 + 0 16 + 10 16 + 11 16 + 12 16 + 13 16 + 14 16 + 15 16 + 16 16 + 17 16 + 18 16 + 19 16 + 1a 16 + 1b 16 + 1c 16 + 1d 16 + 1e 16 + 1f 16 + 20 16 + 21 16 + 22 16 + 23 16 + 24 16 + 25 16 + 26 16 + 27 16 + 28 16 + 29 16 + 2a 16 + 2b 16 + 30 17 + 31 17 + 32 17 + 33 17 + 34 17 + 35 17 + 36 17 + 37 17 + 38 17 + 39 17 + 41 18 + 42 18 + 43 18 + 44 18 + 48 19 + 49 19 + 4a 16 } method 'test3 (Ljava/util/function/Supplier;)Ljava/lang/String;' { - 0 23 - 1 23 - 2 23 - 3 23 - 4 23 - 5 23 - 15 23 - 16 23 - 17 23 - 18 23 - 19 23 - 1a 23 - 1b 23 - 1c 23 - 1d 23 - 1e 23 - 1f 23 - 20 23 - 21 23 - 22 23 - 23 23 - 24 23 - 25 23 - 26 23 - 27 23 - 28 23 - 29 23 - 2a 23 - 2b 23 - 2c 23 - 2d 23 - 2e 23 - 2f 23 - 34 24 - 35 24 - 36 24 - 37 24 - 38 24 - 39 24 - 3a 24 - 3b 24 - 3c 24 - 3d 24 - 45 25 - 46 25 - 47 25 - 48 25 - 4c 26 - 4d 26 - 4e 23 + 0 24 + 1 24 + 2 24 + 3 24 + 4 24 + 5 24 + 15 24 + 16 24 + 17 24 + 18 24 + 19 24 + 1a 24 + 1b 24 + 1c 24 + 1d 24 + 1e 24 + 1f 24 + 20 24 + 21 24 + 22 24 + 23 24 + 24 24 + 25 24 + 26 24 + 27 24 + 28 24 + 29 24 + 2a 24 + 2b 24 + 2c 24 + 2d 24 + 2e 24 + 2f 24 + 34 25 + 35 25 + 36 25 + 37 25 + 38 25 + 39 25 + 3a 25 + 3b 25 + 3c 25 + 3d 25 + 45 26 + 46 26 + 47 26 + 48 26 + 4c 27 + 4d 27 + 4e 24 } method 'test4 ()Ljava/lang/String;' { - 0 31 - 1 31 - 2 31 - 3 31 - 13 31 - 14 31 - 15 31 - 16 31 - 17 31 - 18 31 - 19 31 - 1a 31 - 1b 31 - 1c 31 - 1d 31 - 1e 31 - 1f 31 - 20 31 - 21 31 - 22 31 - 23 31 - 24 31 - 25 31 - 26 31 - 27 31 - 28 31 - 29 31 - 2a 31 - 2b 31 - 30 32 - 31 32 - 32 32 - 33 32 - 34 32 - 35 32 - 36 32 - 37 32 - 3f 33 - 40 33 - 41 33 - 42 33 - 46 34 - 47 31 + 0 32 + 1 32 + 2 32 + 3 32 + 13 32 + 14 32 + 15 32 + 16 32 + 17 32 + 18 32 + 19 32 + 1a 32 + 1b 32 + 1c 32 + 1d 32 + 1e 32 + 1f 32 + 20 32 + 21 32 + 22 32 + 23 32 + 24 32 + 25 32 + 26 32 + 27 32 + 28 32 + 29 32 + 2a 32 + 2b 32 + 30 33 + 31 33 + 32 33 + 33 33 + 34 33 + 35 33 + 36 33 + 37 33 + 3f 34 + 40 34 + 41 34 + 42 34 + 46 35 + 47 32 } method 'test4 (Ljava/lang/Object;)V' { - 0 39 - 10 39 - 11 39 - 12 39 - 13 39 - 14 39 - 15 39 - 16 39 - 17 39 - 18 39 - 19 39 - 1a 39 - 1b 39 - 1c 39 - 1d 39 - 1e 39 - 1f 39 - 20 39 - 21 39 - 22 39 - 23 39 - 24 39 - 25 39 - 26 39 - 27 39 - 28 39 - 29 39 - 2a 39 - 2b 39 - 30 40 - 31 40 - 32 41 - 33 41 - 34 41 - 35 41 - 36 41 - 37 41 - 38 41 - 39 41 - 3a 41 - 3b 41 - 3c 41 - 3d 41 - 3e 41 - 3f 41 - 40 42 - 47 43 - 48 43 - 49 44 - 4a 44 - 4b 44 - 4c 44 - 4d 44 - 4e 44 - 4f 44 - 50 44 - 51 45 - 54 48 + 0 40 + 10 40 + 11 40 + 12 40 + 13 40 + 14 40 + 15 40 + 16 40 + 17 40 + 18 40 + 19 40 + 1a 40 + 1b 40 + 1c 40 + 1d 40 + 1e 40 + 1f 40 + 20 40 + 21 40 + 22 40 + 23 40 + 24 40 + 25 40 + 26 40 + 27 40 + 28 40 + 29 40 + 2a 40 + 2b 40 + 30 41 + 31 41 + 32 42 + 33 42 + 34 42 + 35 42 + 36 42 + 37 42 + 38 42 + 39 42 + 3a 42 + 3b 42 + 3c 42 + 3d 42 + 3e 42 + 3f 42 + 40 43 + 47 44 + 48 44 + 49 45 + 4a 45 + 4b 45 + 4c 45 + 4d 45 + 4e 45 + 4f 45 + 50 45 + 51 46 + 54 49 } method 'test5 (Ljava/lang/Object;)Ljava/lang/String;' { - 0 51 - 10 51 - 11 51 - 12 51 - 13 51 - 14 51 - 15 51 - 16 51 - 17 51 - 18 51 - 19 51 - 1a 51 - 1b 51 - 1c 51 - 1d 51 - 1e 51 - 1f 51 - 20 51 - 21 51 - 22 51 - 23 51 - 54 52 - 55 52 - 56 52 - 57 52 - 5e 52 - 5f 52 - 60 52 - 66 53 - 6a 51 + 0 52 + 10 52 + 11 52 + 12 52 + 13 52 + 14 52 + 15 52 + 16 52 + 17 52 + 18 52 + 19 52 + 1a 52 + 1b 52 + 1c 52 + 1d 52 + 1e 52 + 1f 52 + 20 52 + 21 52 + 22 52 + 23 52 + 54 53 + 55 53 + 56 53 + 57 53 + 5e 53 + 5f 53 + 60 53 + 66 54 + 6a 52 + } + + method 'test6 (Ljava/lang/Object;)Ljava/lang/String;' { + 0 59 + 2 59 + 3 59 + 4 59 + 6 60 + 9 63 + 10 63 + 11 63 + 12 63 + 13 63 + 14 63 + 15 63 + 16 63 + 17 63 + 18 63 + 19 63 + 1a 63 + 1b 63 + 1c 63 + 1d 63 + 1e 63 + 1f 63 + 20 63 + 21 63 + 22 63 + 23 63 + 24 63 + 25 63 + 26 63 + 27 63 + 28 63 + 29 63 + 2a 63 + 2b 63 + 43 64 + 44 64 + 45 64 + 46 64 + 4d 64 + 4e 64 + 4f 64 + 6c 65 + 6d 65 + 6e 65 + 6f 65 + 76 65 + 77 65 + 78 65 + 85 66 + 86 63 } } Lines mapping: -7 <-> 9 -8 <-> 10 -9 <-> 11 -11 <-> 13 -14 <-> 16 -15 <-> 17 -16 <-> 18 -17 <-> 19 -22 <-> 24 -23 <-> 25 -24 <-> 26 -25 <-> 27 -31 <-> 32 -32 <-> 33 -33 <-> 34 -34 <-> 35 -39 <-> 40 -40 <-> 41 -41 <-> 42 -42 <-> 43 -43 <-> 44 -44 <-> 45 -45 <-> 46 -48 <-> 49 -52 <-> 52 -53 <-> 53 -54 <-> 54 +7 <-> 10 +8 <-> 11 +9 <-> 12 +11 <-> 14 +14 <-> 17 +15 <-> 18 +16 <-> 19 +17 <-> 20 +22 <-> 25 +23 <-> 26 +24 <-> 27 +25 <-> 28 +31 <-> 33 +32 <-> 34 +33 <-> 35 +34 <-> 36 +39 <-> 41 +40 <-> 42 +41 <-> 43 +42 <-> 44 +43 <-> 45 +44 <-> 46 +45 <-> 47 +48 <-> 50 +52 <-> 53 +53 <-> 54 +54 <-> 55 +61 <-> 64 +62 <-> 65 +63 <-> 66 +64 <-> 67 diff --git a/testData/src/java25/pkg/TestSwitchPatternMatchingJ25.java b/testData/src/java25/pkg/TestSwitchPatternMatchingJ25.java index 363ea470ae..143527f0be 100644 --- a/testData/src/java25/pkg/TestSwitchPatternMatchingJ25.java +++ b/testData/src/java25/pkg/TestSwitchPatternMatchingJ25.java @@ -54,4 +54,14 @@ public String test5(Object o) { default -> null; }; } + + record Test6a(int i) {} + record Test6b(int i) {} + public String test6(Object o) { + return switch (o) { + case Test6a(int i) -> Integer.toString(i); + case Test6b(int i) -> Integer.toString(i); + default -> throw new RuntimeException(); + }; + } }