Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix requireNonNull call with reusable selectors and fix default being removed from exhaustive switch statements #436

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent;
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement.EdgeDirection;

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

if (stlast.getExprents() != null && stlast.getExprents().isEmpty()) {
boolean needsExhaustive = swst.getCaseValues().stream()
.flatMap(List::stream)
.filter(exp -> exp instanceof FunctionExprent)
.map(exp -> (FunctionExprent) exp)
.filter(exp -> exp.getFuncType() == FunctionExprent.FunctionType.INSTANCEOF)
.findAny().isPresent();
if (stlast.getExprents() != null && stlast.getExprents().isEmpty() && !needsExhaustive) {
List<StatEdge> edges = stlast.getAllSuccessorEdges();
// If we don't have an edge from this statement or if the edge that we have isn't explicit, delete the default edge
if (edges.isEmpty() || !edges.get(0).explicit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,22 @@ private static boolean processStatement(SwitchStatement stat, Statement root) {
// Check for non null
if (basicHead != null && basicHead.size() >= 1 && realSelector instanceof VarExprent var && !nullCase) {
Exprent last = basicHead.get(basicHead.size() - 1);
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))) {
basicHead.remove(basicHead.size() - 1);
// Check for other assignment
if (basicHead.size() >= 1 && var.isStack() && !nullCase) {
last = basicHead.get(basicHead.size() - 1);
if (last instanceof AssignmentExprent assignment && assignment.getLeft() instanceof VarExprent assigned && var.equals(assigned)) {
if (!var.isVarReferenced(root, assigned)) {
realSelector = assignment.getRight();
AssignmentExprent stackAssignment = null;
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;")) {
VarExprent requireNonNullStackVar = null;
if (inv.getLstParameters().get(0) instanceof VarExprent varExprent) {
requireNonNullStackVar = varExprent;
}
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)) {
stackAssignment = assignment;
}
if (var.equals(inv.getLstParameters().get(0)) || (inv.getLstParameters().get(0).getExprentUse() & Exprent.MULTIPLE_USES) != 0 && inv.getLstParameters().get(0).equals(stackAssignment.getRight())) {
basicHead.remove(basicHead.size() - 1);
// Check for other assignment
if (basicHead.size() >= 1 && var.isStack() && !nullCase) {
last = basicHead.get(basicHead.size() - 1);
if (stackAssignment != null) {
realSelector = stackAssignment.getRight();
basicHead.remove(basicHead.size() - 1);
}
}
Expand Down
5 changes: 3 additions & 2 deletions testData/results/pkg/TestSwitchPatternMatching15.dec
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class TestSwitchPatternMatching15 {
case Number nx:// 15
System.out.println("Number: " + nx);// 16
break;// 17
default:
}
}// 21
}
Expand Down Expand Up @@ -133,7 +134,7 @@ class 'pkg/TestSwitchPatternMatching15' {
95 18
96 18
97 19
9d 21
9d 22
}
}

Expand All @@ -151,6 +152,6 @@ Lines mapping:
15 <-> 18
16 <-> 19
17 <-> 20
21 <-> 22
21 <-> 23
Not mapped:
19
Loading