[java-decompiler] dead code
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2015 JetBrains s.r.o.
|
* Copyright 2000-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -21,7 +21,6 @@ import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
|
|||||||
import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent;
|
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.Exprent;
|
||||||
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
|
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
|
||||||
import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -29,32 +28,23 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ExitHelper {
|
public class ExitHelper {
|
||||||
|
|
||||||
|
|
||||||
public static boolean condenseExits(RootStatement root) {
|
public static boolean condenseExits(RootStatement root) {
|
||||||
|
|
||||||
int changed = integrateExits(root);
|
int changed = integrateExits(root);
|
||||||
|
|
||||||
if (changed > 0) {
|
if (changed > 0) {
|
||||||
|
|
||||||
cleanUpUnreachableBlocks(root);
|
cleanUpUnreachableBlocks(root);
|
||||||
|
|
||||||
SequenceHelper.condenseSequences(root);
|
SequenceHelper.condenseSequences(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (changed > 0);
|
return (changed > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void cleanUpUnreachableBlocks(Statement stat) {
|
private static void cleanUpUnreachableBlocks(Statement stat) {
|
||||||
|
|
||||||
boolean found;
|
boolean found;
|
||||||
do {
|
do {
|
||||||
|
|
||||||
found = false;
|
found = false;
|
||||||
|
|
||||||
for (int i = 0; i < stat.getStats().size(); i++) {
|
for (int i = 0; i < stat.getStats().size(); i++) {
|
||||||
|
|
||||||
Statement st = stat.getStats().get(i);
|
Statement st = stat.getStats().get(i);
|
||||||
|
|
||||||
cleanUpUnreachableBlocks(st);
|
cleanUpUnreachableBlocks(st);
|
||||||
@@ -83,16 +73,12 @@ public class ExitHelper {
|
|||||||
while (found);
|
while (found);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static int integrateExits(Statement stat) {
|
private static int integrateExits(Statement stat) {
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
Statement dest = null;
|
Statement dest;
|
||||||
|
|
||||||
if (stat.getExprents() == null) {
|
if (stat.getExprents() == null) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
|
|
||||||
for (Statement st : stat.getStats()) {
|
for (Statement st : stat.getStats()) {
|
||||||
@@ -108,7 +94,6 @@ public class ExitHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (stat.type) {
|
switch (stat.type) {
|
||||||
case Statement.TYPE_IF:
|
case Statement.TYPE_IF:
|
||||||
IfStatement ifst = (IfStatement)stat;
|
IfStatement ifst = (IfStatement)stat;
|
||||||
@@ -168,15 +153,12 @@ public class ExitHelper {
|
|||||||
// LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>());
|
// LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>());
|
||||||
// do it by hand
|
// do it by hand
|
||||||
for (StatEdge prededge : block.getPredecessorEdges(StatEdge.TYPE_CONTINUE)) {
|
for (StatEdge prededge : block.getPredecessorEdges(StatEdge.TYPE_CONTINUE)) {
|
||||||
|
|
||||||
block.removePredecessor(prededge);
|
block.removePredecessor(prededge);
|
||||||
prededge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, prededge, stat);
|
prededge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, prededge, stat);
|
||||||
stat.addPredecessor(prededge);
|
stat.addPredecessor(prededge);
|
||||||
|
|
||||||
stat.addLabeledEdge(prededge);
|
stat.addLabeledEdge(prededge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
stat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, stat, bstat));
|
stat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, stat, bstat));
|
||||||
|
|
||||||
for (StatEdge edge : dest.getAllPredecessorEdges()) {
|
for (StatEdge edge : dest.getAllPredecessorEdges()) {
|
||||||
@@ -202,11 +184,9 @@ public class ExitHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Statement isExitEdge(StatEdge edge) {
|
private static Statement isExitEdge(StatEdge edge) {
|
||||||
|
|
||||||
Statement dest = edge.getDestination();
|
Statement dest = edge.getDestination();
|
||||||
|
|
||||||
if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASICBLOCK
|
if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASICBLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge))) {
|
||||||
&& edge.explicit && (edge.labeled || isOnlyEdge(edge))) {
|
|
||||||
List<Exprent> data = dest.getExprents();
|
List<Exprent> data = dest.getExprents();
|
||||||
|
|
||||||
if (data != null && data.size() == 1) {
|
if (data != null && data.size() == 1) {
|
||||||
@@ -220,7 +200,6 @@ public class ExitHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isOnlyEdge(StatEdge edge) {
|
private static boolean isOnlyEdge(StatEdge edge) {
|
||||||
|
|
||||||
Statement stat = edge.getDestination();
|
Statement stat = edge.getDestination();
|
||||||
|
|
||||||
for (StatEdge ed : stat.getAllPredecessorEdges()) {
|
for (StatEdge ed : stat.getAllPredecessorEdges()) {
|
||||||
@@ -244,7 +223,6 @@ public class ExitHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean removeRedundantReturns(RootStatement root) {
|
public static boolean removeRedundantReturns(RootStatement root) {
|
||||||
|
|
||||||
boolean res = false;
|
boolean res = false;
|
||||||
|
|
||||||
DummyExitStatement dummyExit = root.getDummyExit();
|
DummyExitStatement dummyExit = root.getDummyExit();
|
||||||
@@ -270,79 +248,4 @@ public class ExitHelper {
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean handleReturnFromInitializer(RootStatement root) {
|
|
||||||
|
|
||||||
boolean res = false;
|
|
||||||
|
|
||||||
Statement exit = root.getDummyExit();
|
|
||||||
Statement top = root.getFirst();
|
|
||||||
Statement newret = null;
|
|
||||||
|
|
||||||
boolean sharedcreated = false;
|
|
||||||
|
|
||||||
for (StatEdge edge : exit.getAllPredecessorEdges()) {
|
|
||||||
if (edge.explicit) {
|
|
||||||
|
|
||||||
if (!sharedcreated) {
|
|
||||||
newret = addSharedInitializerReturn(root);
|
|
||||||
sharedcreated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Statement source = edge.getSource();
|
|
||||||
List<Exprent> lstExpr = source.getExprents();
|
|
||||||
if (lstExpr != null && !lstExpr.isEmpty()) {
|
|
||||||
Exprent expr = lstExpr.get(lstExpr.size() - 1);
|
|
||||||
if (expr.type == Exprent.EXPRENT_EXIT) {
|
|
||||||
ExitExprent ex = (ExitExprent)expr;
|
|
||||||
if (ex.getExitType() == ExitExprent.EXIT_RETURN && ex.getValue() == null) {
|
|
||||||
lstExpr.remove(lstExpr.size() - 1);
|
|
||||||
|
|
||||||
source.removeSuccessor(edge);
|
|
||||||
source.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, source, newret, top));
|
|
||||||
|
|
||||||
res = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Statement addSharedInitializerReturn(RootStatement root) {
|
|
||||||
|
|
||||||
Statement exit = root.getDummyExit();
|
|
||||||
Statement top = root.getFirst();
|
|
||||||
|
|
||||||
// build a new statement with the single instruction 'return'
|
|
||||||
BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(
|
|
||||||
DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER)));
|
|
||||||
|
|
||||||
ExitExprent retexpr = new ExitExprent(ExitExprent.EXIT_RETURN, null,
|
|
||||||
((MethodDescriptor)DecompilerContext
|
|
||||||
.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret, null);
|
|
||||||
// a changeable list needed
|
|
||||||
bstat.setExprents(new ArrayList<Exprent>(Arrays.asList(new Exprent[]{retexpr})));
|
|
||||||
|
|
||||||
// build sequence to replace the former top statement
|
|
||||||
SequenceStatement seq = new SequenceStatement(Arrays.asList(top, bstat));
|
|
||||||
top.setParent(seq);
|
|
||||||
bstat.setParent(seq);
|
|
||||||
seq.setParent(root);
|
|
||||||
|
|
||||||
root.getStats().removeWithKey(top.id);
|
|
||||||
root.getStats().addWithKeyAndIndex(0, seq, seq.id);
|
|
||||||
root.setFirst(seq);
|
|
||||||
|
|
||||||
for (StatEdge succedge : top.getAllSuccessorEdges()) {
|
|
||||||
top.removeSuccessor(succedge);
|
|
||||||
}
|
|
||||||
|
|
||||||
top.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, top, bstat));
|
|
||||||
bstat.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, bstat, exit, seq));
|
|
||||||
|
|
||||||
return bstat;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user