Skip to content

Commit 3da350a

Browse files
authored
Fix requireNonNull call appearing when the selector is reusable and fix (#436)
default being removed from switch statements that are required to be exhaustive
1 parent fd167c7 commit 3da350a

File tree

5 files changed

+346
-167
lines changed

5 files changed

+346
-167
lines changed

src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent;
55
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
6+
import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent;
67
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
78
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.EdgeDirection;
89

@@ -470,7 +471,13 @@ public static boolean hideDefaultSwitchEdges(Statement stat) {
470471
if (last >= 0) { // empty switch possible
471472
Statement stlast = swst.getCaseStatements().get(last);
472473

473-
if (stlast.getExprents() != null && stlast.getExprents().isEmpty()) {
474+
boolean needsExhaustive = swst.getCaseValues().stream()
475+
.flatMap(List::stream)
476+
.filter(exp -> exp instanceof FunctionExprent)
477+
.map(exp -> (FunctionExprent) exp)
478+
.filter(exp -> exp.getFuncType() == FunctionExprent.FunctionType.INSTANCEOF)
479+
.findAny().isPresent();
480+
if (stlast.getExprents() != null && stlast.getExprents().isEmpty() && !needsExhaustive) {
474481
List<StatEdge> edges = stlast.getAllSuccessorEdges();
475482
// If we don't have an edge from this statement or if the edge that we have isn't explicit, delete the default edge
476483
if (edges.isEmpty() || !edges.get(0).explicit) {

src/org/jetbrains/java/decompiler/modules/decompiler/SwitchPatternMatchProcessor.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -317,14 +317,22 @@ private static boolean processStatement(SwitchStatement stat, Statement root) {
317317
// Check for non null
318318
if (basicHead != null && basicHead.size() >= 1 && realSelector instanceof VarExprent var && !nullCase) {
319319
Exprent last = basicHead.get(basicHead.size() - 1);
320-
if (last instanceof InvocationExprent inv && inv.isStatic() && inv.getClassname().equals("java/util/Objects") && inv.getName().equals("requireNonNull") && inv.getStringDescriptor().equals("(Ljava/lang/Object;)Ljava/lang/Object;") && var.equals(inv.getLstParameters().get(0))) {
321-
basicHead.remove(basicHead.size() - 1);
322-
// Check for other assignment
323-
if (basicHead.size() >= 1 && var.isStack() && !nullCase) {
324-
last = basicHead.get(basicHead.size() - 1);
325-
if (last instanceof AssignmentExprent assignment && assignment.getLeft() instanceof VarExprent assigned && var.equals(assigned)) {
326-
if (!var.isVarReferenced(root, assigned)) {
327-
realSelector = assignment.getRight();
320+
AssignmentExprent stackAssignment = null;
321+
if (last instanceof InvocationExprent inv && inv.isStatic() && inv.getClassname().equals("java/util/Objects") && inv.getName().equals("requireNonNull") && inv.getStringDescriptor().equals("(Ljava/lang/Object;)Ljava/lang/Object;")) {
322+
VarExprent requireNonNullStackVar = null;
323+
if (inv.getLstParameters().get(0) instanceof VarExprent varExprent) {
324+
requireNonNullStackVar = varExprent;
325+
}
326+
if (basicHead.size() >= 2 && var.isStack() && !nullCase && basicHead.get(basicHead.size() - 2) instanceof AssignmentExprent assignment && assignment.getLeft() instanceof VarExprent assigned && var.equals(assigned) && !var.isVarReferenced(root, assigned, requireNonNullStackVar)) {
327+
stackAssignment = assignment;
328+
}
329+
if (var.equals(inv.getLstParameters().get(0)) || (inv.getLstParameters().get(0).getExprentUse() & Exprent.MULTIPLE_USES) != 0 && inv.getLstParameters().get(0).equals(stackAssignment.getRight())) {
330+
basicHead.remove(basicHead.size() - 1);
331+
// Check for other assignment
332+
if (basicHead.size() >= 1 && var.isStack() && !nullCase) {
333+
last = basicHead.get(basicHead.size() - 1);
334+
if (stackAssignment != null) {
335+
realSelector = stackAssignment.getRight();
328336
basicHead.remove(basicHead.size() - 1);
329337
}
330338
}

testData/results/pkg/TestSwitchPatternMatching15.dec

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class TestSwitchPatternMatching15 {
1818
case Number nx:// 15
1919
System.out.println("Number: " + nx);// 16
2020
break;// 17
21+
default:
2122
}
2223
}// 21
2324
}
@@ -133,7 +134,7 @@ class 'pkg/TestSwitchPatternMatching15' {
133134
95 18
134135
96 18
135136
97 19
136-
9d 21
137+
9d 22
137138
}
138139
}
139140

@@ -151,6 +152,6 @@ Lines mapping:
151152
15 <-> 18
152153
16 <-> 19
153154
17 <-> 20
154-
21 <-> 22
155+
21 <-> 23
155156
Not mapped:
156157
19

0 commit comments

Comments
 (0)