in src/org/jetbrains/java/decompiler/modules/decompiler/SequenceHelper.java [26:146]
private static void condenseSequencesRec(Statement stat) {
if (stat.type == StatementType.SEQUENCE) {
List<Statement> lst = new ArrayList<>(stat.getStats());
boolean unfolded = false;
// unfold blocks
for (int i = 0; i < lst.size(); i++) {
Statement st = lst.get(i);
if (st.type == StatementType.SEQUENCE) {
removeEmptyStatements((SequenceStatement)st);
if (i == lst.size() - 1 || isSequenceDisbandable(st, lst.get(i + 1))) {
// move predecessors
Statement first = st.getFirst();
for (StatEdge edge : st.getAllPredecessorEdges()) {
st.removePredecessor(edge);
edge.getSource().changeEdgeNode(EdgeDirection.FORWARD, edge, first);
first.addPredecessor(edge);
}
// move successors
Statement last = st.getStats().getLast();
if (last.getAllSuccessorEdges().isEmpty() && i < lst.size() - 1) {
last.addSuccessor(new StatEdge(EdgeType.REGULAR, last, lst.get(i + 1)));
}
else {
for (StatEdge edge : last.getAllSuccessorEdges()) {
if (i == lst.size() - 1) {
if (edge.closure == st) {
stat.addLabeledEdge(edge);
}
}
else {
edge.getSource().changeEdgeType(EdgeDirection.FORWARD, edge, EdgeType.REGULAR);
edge.closure.getLabelEdges().remove(edge);
edge.closure = null;
}
}
}
for (StatEdge edge : st.getAllSuccessorEdges()) {
st.removeSuccessor(edge);
}
for (StatEdge edge : new HashSet<>(st.getLabelEdges())) {
if (edge.getSource() != last) {
last.addLabeledEdge(edge);
}
}
lst.remove(i);
lst.addAll(i, st.getStats());
i--;
unfolded = true;
}
}
}
if (unfolded) {
SequenceStatement sequence = new SequenceStatement(lst);
sequence.setAllParent();
stat.getParent().replaceStatement(stat, sequence);
stat = sequence;
}
}
// sequence consisting of one statement -> disband
if (stat.type == StatementType.SEQUENCE) {
removeEmptyStatements((SequenceStatement)stat);
if (stat.getStats().size() == 1) {
Statement st = stat.getFirst();
boolean ok = st.getAllSuccessorEdges().isEmpty();
if (!ok) {
StatEdge edge = st.getAllSuccessorEdges().get(0);
ok = stat.getAllSuccessorEdges().isEmpty();
if (!ok) {
StatEdge statedge = stat.getAllSuccessorEdges().get(0);
ok = (edge.getDestination() == statedge.getDestination());
if (ok) {
st.removeSuccessor(edge);
}
}
}
if (ok) {
stat.getParent().replaceStatement(stat, st);
stat = st;
}
}
}
// replace flat statements with synthetic basic blocks
outer:
while (true) {
for (Statement st : stat.getStats()) {
if ((st.getStats().isEmpty() || st.getExprents() != null) && st.type != StatementType.BASIC_BLOCK) {
destroyAndFlattenStatement(st);
continue outer;
}
}
break;
}
// recursion
for (int i = 0; i < stat.getStats().size(); i++) {
condenseSequencesRec(stat.getStats().get(i));
}
}