[java decompiler] - StatEdge type refactoring

GitOrigin-RevId: 62f2b69c2e9487f0b7d05b7f462d80d0809d997c
This commit is contained in:
Ilyas Selimov
2022-01-19 12:12:13 +07:00
committed by intellij-monorepo-bot
parent ff5d33a8c6
commit 87844ec3ff
28 changed files with 458 additions and 333 deletions

View File

@@ -10,6 +10,7 @@ import org.jetbrains.java.decompiler.main.rels.ClassWrapper;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
import org.jetbrains.java.decompiler.modules.decompiler.SecondaryFunctionsHelper;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
import org.jetbrains.java.decompiler.struct.StructField;
@@ -217,7 +218,7 @@ public final class AssertProcessor {
sequence.setAllParent();
for (int i = 0; i < sequence.getStats().size() - 1; i++) {
sequence.getStats().get(i).addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR,
sequence.getStats().get(i).addSuccessor(new StatEdge(EdgeType.REGULAR,
sequence.getStats().get(i), sequence.getStats().get(i + 1)));
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
@@ -20,7 +21,7 @@ public final class DecHelper {
Set<Statement> intersection = null;
for (Statement stat : lst) {
Set<Statement> setNew = stat.getNeighboursSet(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD);
Set<Statement> setNew = stat.getNeighboursSet(EdgeType.EXCEPTION, Statement.DIRECTION_FORWARD);
if (intersection == null) {
intersection = setNew;
@@ -39,7 +40,7 @@ public final class DecHelper {
}
for (Statement stat : handlers) {
if (!all.contains(stat) || !all.containsAll(stat.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD))) {
if (!all.contains(stat) || !all.containsAll(stat.getNeighbours(EdgeType.EXCEPTION, Statement.DIRECTION_BACKWARD))) {
return false;
}
}
@@ -47,7 +48,7 @@ public final class DecHelper {
// check for other handlers (excluding head)
for (int i = 1; i < lst.size(); i++) {
Statement stat = lst.get(i);
if (!stat.getPredecessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty() && !handlers.contains(stat)) {
if (!stat.getPredecessorEdges(EdgeType.EXCEPTION).isEmpty() && !handlers.contains(stat)) {
return false;
}
}
@@ -59,7 +60,7 @@ public final class DecHelper {
Statement post = null;
Set<Statement> setDest = head.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD);
Set<Statement> setDest = head.getNeighboursSet(EdgeType.REGULAR, Statement.DIRECTION_FORWARD);
if (setDest.contains(head)) {
return false;
@@ -86,7 +87,7 @@ public final class DecHelper {
}
// preds
Set<Statement> setPred = stat.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
Set<Statement> setPred = stat.getNeighboursSet(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD);
setPred.remove(head);
if (setPred.contains(stat)) {
return false;
@@ -105,7 +106,7 @@ public final class DecHelper {
else if (setPred.size() == 1) {
Statement pred = setPred.iterator().next();
while (lst.contains(pred)) {
Set<Statement> setPredTemp = pred.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
Set<Statement> setPredTemp = pred.getNeighboursSet(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD);
setPredTemp.remove(head);
if (!setPredTemp.isEmpty()) { // at most 1 predecessor
@@ -121,9 +122,9 @@ public final class DecHelper {
}
// succs
List<StatEdge> lstEdges = stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL);
List<StatEdge> lstEdges = stat.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (lstEdges.size() > 1) {
Set<Statement> setSucc = stat.getNeighboursSet(Statement.STATEDGE_DIRECT_ALL, Statement.DIRECTION_FORWARD);
Set<Statement> setSucc = stat.getNeighboursSet(EdgeType.DIRECT_ALL, Statement.DIRECTION_FORWARD);
setSucc.retainAll(setDest);
if (setSucc.size() > 0) {
@@ -143,7 +144,7 @@ public final class DecHelper {
else if (lstEdges.size() == 1) {
StatEdge edge = lstEdges.get(0);
if (edge.getType() == StatEdge.TYPE_REGULAR) {
if (edge.getType() == EdgeType.REGULAR) {
Statement statd = edge.getDestination();
if (head == statd) {
return false;
@@ -153,7 +154,7 @@ public final class DecHelper {
return false;
}
else {
Set<Statement> set = statd.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
Set<Statement> set = statd.getNeighboursSet(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD);
if (set.size() > 1) {
post = statd;
repeat = true;
@@ -184,8 +185,8 @@ public final class DecHelper {
}
public static Set<Statement> getUniquePredExceptions(Statement head) {
Set<Statement> setHandlers = new HashSet<>(head.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD));
setHandlers.removeIf(statement -> statement.getPredecessorEdges(StatEdge.TYPE_EXCEPTION).size() > 1);
Set<Statement> setHandlers = new HashSet<>(head.getNeighbours(EdgeType.EXCEPTION, Statement.DIRECTION_FORWARD));
setHandlers.removeIf(statement -> statement.getPredecessorEdges(EdgeType.EXCEPTION).size() > 1);
return setHandlers;
}

View File

@@ -6,6 +6,7 @@ import org.jetbrains.java.decompiler.code.cfg.ControlFlowGraph;
import org.jetbrains.java.decompiler.code.cfg.ExceptionRangeCFG;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.decompose.FastExtendedPostdominanceHelper;
import org.jetbrains.java.decompiler.modules.decompiler.deobfuscator.IrreducibleCFGDeobfuscator;
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
@@ -39,7 +40,7 @@ public final class DomHelper {
}
else { // one straightforward basic block
RootStatement root = new RootStatement(firstst, dummyexit);
firstst.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, firstst, dummyexit, root));
firstst.addSuccessor(new StatEdge(EdgeType.BREAK, firstst, dummyexit, root));
return root;
}
@@ -50,24 +51,24 @@ public final class DomHelper {
for (BasicBlock succ : block.getSuccessors()) {
Statement stsucc = stats.getWithKey(succ.id);
int type;
EdgeType type;
if (stsucc == firstst) {
type = StatEdge.TYPE_CONTINUE;
type = EdgeType.CONTINUE;
}
else if (graph.getFinallyExits().contains(block)) {
type = StatEdge.TYPE_FINALLYEXIT;
type = EdgeType.FINALLY_EXIT;
stsucc = dummyexit;
}
else if (succ.id == graph.getLast().id) {
type = StatEdge.TYPE_BREAK;
type = EdgeType.BREAK;
stsucc = dummyexit;
}
else {
type = StatEdge.TYPE_REGULAR;
type = EdgeType.REGULAR;
}
stat.addSuccessor(new StatEdge(type, stat, (type == StatEdge.TYPE_CONTINUE) ? general : stsucc,
(type == StatEdge.TYPE_REGULAR) ? null : general));
stat.addSuccessor(new StatEdge(type, stat, (type == EdgeType.CONTINUE) ? general : stsucc,
(type == EdgeType.REGULAR) ? null : general));
}
// exceptions edges
@@ -130,7 +131,7 @@ public final class DomHelper {
FastFixedSet<Statement> doms = lists.get(stat);
FastFixedSet<Statement> domsSuccs = factory.spawnEmptySet();
List<Statement> lstSuccs = stat.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD);
List<Statement> lstSuccs = stat.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_FORWARD);
for (int j = 0; j < lstSuccs.size(); j++) {
Statement succ = lstSuccs.get(j);
FastFixedSet<Statement> succlst = lists.get(succ);
@@ -151,7 +152,7 @@ public final class DomHelper {
lists.put(stat, domsSuccs);
List<Statement> lstPreds = stat.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
List<Statement> lstPreds = stat.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD);
for (Statement pred : lstPreds) {
setFlagNodes.add(pred);
}
@@ -256,9 +257,9 @@ public final class DomHelper {
if (ca.getFirst().isContainsMonitorExit() && ca.getHandler().isContainsMonitorExit()) {
// remove the head block from sequence
current.removeSuccessor(current.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0));
current.removeSuccessor(current.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0));
for (StatEdge edge : current.getPredecessorEdges(Statement.STATEDGE_DIRECT_ALL)) {
for (StatEdge edge : current.getPredecessorEdges(EdgeType.DIRECT_ALL)) {
current.removePredecessor(edge);
edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, nextDirect);
nextDirect.addPredecessor(edge);
@@ -275,7 +276,7 @@ public final class DomHelper {
sync.addLabeledEdge(edge);
}
current.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, current, ca.getFirst()));
current.addSuccessor(new StatEdge(EdgeType.REGULAR, current, ca.getFirst()));
ca.getParent().replaceStatement(ca, sync);
found = true;
@@ -480,7 +481,7 @@ public final class DomHelper {
boolean addhd = (setNodes.size() == 0); // first handler == head
if (!addhd) {
List<Statement> hdsupp = handler.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD);
List<Statement> hdsupp = handler.getNeighbours(EdgeType.EXCEPTION, Statement.DIRECTION_BACKWARD);
addhd = (setNodes.containsAll(hdsupp) && (setNodes.size() > hdsupp.size()
|| setNodes.size() == 1)); // strict subset
}
@@ -496,14 +497,14 @@ public final class DomHelper {
setNodes.add(st);
if (st != head) {
// record predeccessors except for the head
setPreds.addAll(st.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD));
setPreds.addAll(st.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD));
}
// put successors on the stack
lstStack.addAll(st.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD));
lstStack.addAll(st.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_FORWARD));
// exception edges
setHandlers.addAll(st.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD));
setHandlers.addAll(st.getNeighbours(EdgeType.EXCEPTION, Statement.DIRECTION_FORWARD));
}
}
@@ -521,13 +522,13 @@ public final class DomHelper {
// check exception handlers
setHandlers.clear();
for (Statement st : setNodes) {
setHandlers.addAll(st.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD));
setHandlers.addAll(st.getNeighbours(EdgeType.EXCEPTION, Statement.DIRECTION_FORWARD));
}
setHandlers.removeAll(setNodes);
boolean excok = true;
for (Statement handler : setHandlers) {
if (!handler.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD).containsAll(setNodes)) {
if (!handler.getNeighbours(EdgeType.EXCEPTION, Statement.DIRECTION_BACKWARD).containsAll(setNodes)) {
excok = false;
break;
}
@@ -540,7 +541,7 @@ public final class DomHelper {
setPreds.removeAll(setNodes);
if (setPreds.size() == 0) {
if ((setNodes.size() > 1 ||
head.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD).contains(head))
head.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD).contains(head))
&& setNodes.size() < stats.size()) {
if (checkSynchronizedCompleteness(setNodes)) {
res = new GeneralStatement(head, setNodes, same ? null : post);
@@ -561,8 +562,8 @@ public final class DomHelper {
// check exit nodes
for (Statement stat : setNodes) {
if (stat.isMonitorEnter()) {
List<StatEdge> lstSuccs = stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL);
if (lstSuccs.size() != 1 || lstSuccs.get(0).getType() != StatEdge.TYPE_REGULAR) {
List<StatEdge> lstSuccs = stat.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (lstSuccs.size() != 1 || lstSuccs.get(0).getType() != EdgeType.REGULAR) {
return false;
}

View File

@@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.code.cfg.BasicBlock;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
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.stats.*;
@@ -44,7 +45,7 @@ public final class ExitHelper {
if (last.getExprents() == null || !last.getExprents().isEmpty()) {
if (!secondlast.hasBasicSuccEdge()) {
Set<Statement> set = last.getNeighboursSet(Statement.STATEDGE_DIRECT_ALL, Statement.DIRECTION_BACKWARD);
Set<Statement> set = last.getNeighboursSet(EdgeType.DIRECT_ALL, Statement.DIRECTION_BACKWARD);
set.remove(secondlast);
if (set.isEmpty()) {
@@ -92,7 +93,7 @@ public final class ExitHelper {
bstat.setExprents(DecHelper.copyExprentList(dest.getExprents()));
ifst.getFirst().removeSuccessor(ifedge);
StatEdge newedge = new StatEdge(StatEdge.TYPE_REGULAR, ifst.getFirst(), bstat);
StatEdge newedge = new StatEdge(EdgeType.REGULAR, ifst.getFirst(), bstat);
ifst.getFirst().addSuccessor(newedge);
ifst.setIfEdge(newedge);
ifst.setIfstat(bstat);
@@ -100,7 +101,7 @@ public final class ExitHelper {
bstat.setParent(ifst);
StatEdge oldexitedge = dest.getAllSuccessorEdges().get(0);
StatEdge newexitedge = new StatEdge(StatEdge.TYPE_BREAK, bstat, oldexitedge.getDestination());
StatEdge newexitedge = new StatEdge(EdgeType.BREAK, bstat, oldexitedge.getDestination());
bstat.addSuccessor(newexitedge);
oldexitedge.closure.addLabeledEdge(newexitedge);
ret = 1;
@@ -111,7 +112,7 @@ public final class ExitHelper {
if (stat.getAllSuccessorEdges().size() == 1 &&
stat.getAllSuccessorEdges().get(0).getType() == StatEdge.TYPE_BREAK &&
stat.getAllSuccessorEdges().get(0).getType() == EdgeType.BREAK &&
stat.getLabelEdges().isEmpty()) {
Statement parent = stat.getParent();
if (stat != parent.getFirst() || (parent.type != Statement.TYPE_IF &&
@@ -127,7 +128,7 @@ public final class ExitHelper {
bstat.setExprents(DecHelper.copyExprentList(dest.getExprents()));
StatEdge oldexitedge = dest.getAllSuccessorEdges().get(0);
StatEdge newexitedge = new StatEdge(StatEdge.TYPE_BREAK, bstat, oldexitedge.getDestination());
StatEdge newexitedge = new StatEdge(EdgeType.BREAK, bstat, oldexitedge.getDestination());
bstat.addSuccessor(newexitedge);
oldexitedge.closure.addLabeledEdge(newexitedge);
@@ -138,14 +139,14 @@ public final class ExitHelper {
// LabelHelper.lowContinueLabels not applicable because of forward continue edges
// LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>());
// do it by hand
for (StatEdge prededge : block.getPredecessorEdges(StatEdge.TYPE_CONTINUE)) {
for (StatEdge prededge : block.getPredecessorEdges(EdgeType.CONTINUE)) {
block.removePredecessor(prededge);
prededge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, prededge, stat);
stat.addPredecessor(prededge);
stat.addLabeledEdge(prededge);
}
stat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, stat, bstat));
stat.addSuccessor(new StatEdge(EdgeType.REGULAR, stat, bstat));
for (StatEdge edge : dest.getAllPredecessorEdges()) {
if (!edge.explicit && stat.containsStatementStrict(edge.getSource()) &&
@@ -172,7 +173,7 @@ public final class ExitHelper {
private static Statement isExitEdge(StatEdge edge) {
Statement dest = edge.getDestination();
if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASIC_BLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge))) {
if (edge.getType() == EdgeType.BREAK && dest.type == Statement.TYPE_BASIC_BLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge))) {
List<Exprent> data = dest.getExprents();
if (data != null && data.size() == 1) {
@@ -190,7 +191,7 @@ public final class ExitHelper {
for (StatEdge ed : stat.getAllPredecessorEdges()) {
if (ed != edge) {
if (ed.getType() == StatEdge.TYPE_REGULAR) {
if (ed.getType() == EdgeType.REGULAR) {
Statement source = ed.getSource();
if (source.type == Statement.TYPE_BASIC_BLOCK || (source.type == Statement.TYPE_IF &&

View File

@@ -7,6 +7,7 @@ import org.jetbrains.java.decompiler.code.InstructionSequence;
import org.jetbrains.java.decompiler.code.cfg.BasicBlock;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode;
@@ -803,20 +804,19 @@ public class ExprProcessor implements CodeConstants {
public static TextBuffer jmpWrapper(Statement stat, int indent, boolean semicolon, BytecodeMappingTracer tracer) {
TextBuffer buf = stat.toJava(indent, tracer);
List<StatEdge> lstSuccs = stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = stat.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (lstSuccs.size() == 1) {
StatEdge edge = lstSuccs.get(0);
if (edge.getType() != StatEdge.TYPE_REGULAR && edge.explicit && edge.getDestination().type != Statement.TYPE_DUMMY_EXIT) {
if (edge.getType() != EdgeType.REGULAR && edge.explicit && edge.getDestination().type != Statement.TYPE_DUMMY_EXIT) {
buf.appendIndent(indent);
switch (edge.getType()) {
case StatEdge.TYPE_BREAK:
addDeletedGotoInstructionMapping(stat, tracer);
buf.append("break");
break;
case StatEdge.TYPE_CONTINUE:
addDeletedGotoInstructionMapping(stat, tracer);
buf.append("continue");
if (EdgeType.BREAK.equals(edge.getType())) {
addDeletedGotoInstructionMapping(stat, tracer);
buf.append("break");
}
else if (EdgeType.CONTINUE.equals(edge.getType())) {
addDeletedGotoInstructionMapping(stat, tracer);
buf.append("continue");
}
if (edge.labeled) {

View File

@@ -12,6 +12,7 @@ import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.modules.code.DeadCodeHelper;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
@@ -248,8 +249,8 @@ public class FinallyProcessor {
// find finally exits
if (blockStatement != null && blockStatement.getBlock() != null) {
Statement handler = fstat.getHandler();
for (StatEdge edge : blockStatement.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL)) {
if (edge.getType() != StatEdge.TYPE_REGULAR && handler.containsStatement(blockStatement)
for (StatEdge edge : blockStatement.getSuccessorEdges(EdgeType.DIRECT_ALL)) {
if (edge.getType() != EdgeType.REGULAR && handler.containsStatement(blockStatement)
&& !handler.containsStatement(edge.getDestination())) {
Boolean existingFlag = mapLast.get(blockStatement.getBlock());
// note: the dummy node is also processed!

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
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.exps.IfExprent;
@@ -148,7 +149,7 @@ public final class IfHelper {
else {
ifchild.getFirst().removeSuccessor(ifchild.getIfEdge());
StatEdge ifedge = new StatEdge(StatEdge.TYPE_REGULAR, ifparent.getFirst(), ifinner);
StatEdge ifedge = new StatEdge(EdgeType.REGULAR, ifparent.getFirst(), ifinner);
ifparent.getFirst().addSuccessor(ifedge);
ifparent.setIfEdge(ifedge);
ifparent.setIfstat(ifinner);
@@ -312,7 +313,7 @@ public final class IfHelper {
second.addSuccessor(new StatEdge(ifedge.getType(), second, ifedge.getDestination(), ifedge.closure));
StatEdge newifedge = new StatEdge(StatEdge.TYPE_REGULAR, firstif.getFirst(), second);
StatEdge newifedge = new StatEdge(EdgeType.REGULAR, firstif.getFirst(), second);
firstif.getFirst().addSuccessor(newifedge);
firstif.setIfstat(second);
@@ -372,7 +373,7 @@ public final class IfHelper {
Statement elsechild = edge.getDestination();
IfNode elsenode = new IfNode(elsechild);
if (stsingle || edge.getType() != StatEdge.TYPE_REGULAR) {
if (stsingle || edge.getType() != EdgeType.REGULAR) {
res.addChild(elsenode, 1);
}
else {
@@ -414,19 +415,19 @@ public final class IfHelper {
if (ifstat.getIfstat() == null) {
noifstat = true;
ifdirect = ifstat.getIfEdge().getType() == StatEdge.TYPE_FINALLYEXIT ||
ifdirect = ifstat.getIfEdge().getType() == EdgeType.FINALLY_EXIT ||
MergeHelper.isDirectPath(from, ifstat.getIfEdge().getDestination());
}
else {
List<StatEdge> lstSuccs = ifstat.getIfstat().getAllSuccessorEdges();
ifdirect = !lstSuccs.isEmpty() && lstSuccs.get(0).getType() == StatEdge.TYPE_FINALLYEXIT ||
ifdirect = !lstSuccs.isEmpty() && lstSuccs.get(0).getType() == EdgeType.FINALLY_EXIT ||
hasDirectEndEdge(ifstat.getIfstat(), from);
}
Statement last = parent.type == Statement.TYPE_SEQUENCE ? parent.getStats().getLast() : ifstat;
noelsestat = (last == ifstat);
elsedirect = !last.getAllSuccessorEdges().isEmpty() && last.getAllSuccessorEdges().get(0).getType() == StatEdge.TYPE_FINALLYEXIT ||
elsedirect = !last.getAllSuccessorEdges().isEmpty() && last.getAllSuccessorEdges().get(0).getType() == EdgeType.FINALLY_EXIT ||
hasDirectEndEdge(last, from);
if (!noelsestat && existsPath(ifstat, ifstat.getAllSuccessorEdges().get(0).getDestination())) {
@@ -482,7 +483,7 @@ public final class IfHelper {
sequence.getStats().removeWithKey(st.id);
}
StatEdge elseedge = new StatEdge(StatEdge.TYPE_REGULAR, ifstat.getFirst(), stelse);
StatEdge elseedge = new StatEdge(EdgeType.REGULAR, ifstat.getFirst(), stelse);
ifstat.getFirst().addSuccessor(elseedge);
ifstat.setElsestat(stelse);
ifstat.setElseEdge(elseedge);
@@ -537,7 +538,7 @@ public final class IfHelper {
ifstat.getParent().replaceStatement(ifstat, newseq);
newseq.setAllParent();
ifstat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, ifstat, ifbranch));
ifstat.addSuccessor(new StatEdge(EdgeType.REGULAR, ifstat, ifbranch));
}
}
else {
@@ -583,13 +584,13 @@ public final class IfHelper {
ifstat.getFirst().removeSuccessor(ifstat.getIfEdge());
ifstat.getStats().removeWithKey(ifbranch.id);
ifstat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, ifstat, ifbranch));
ifstat.addSuccessor(new StatEdge(EdgeType.REGULAR, ifstat, ifbranch));
sequence.getStats().addWithKey(ifbranch, ifbranch.id);
ifbranch.setParent(sequence);
}
StatEdge newifedge = new StatEdge(StatEdge.TYPE_REGULAR, ifstat.getFirst(), stelse);
StatEdge newifedge = new StatEdge(EdgeType.REGULAR, ifstat.getFirst(), stelse);
ifstat.getFirst().addSuccessor(newifedge);
ifstat.setIfstat(stelse);
ifstat.setIfEdge(newifedge);

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
import java.util.ArrayList;
@@ -49,7 +50,7 @@ public final class InlineSingleBlockHelper {
Statement pre = seq.getStats().get(index - 1);
pre.removeSuccessor(pre.getAllSuccessorEdges().get(0)); // single regular edge
StatEdge edge = first.getPredecessorEdges(StatEdge.TYPE_BREAK).get(0);
StatEdge edge = first.getPredecessorEdges(EdgeType.BREAK).get(0);
Statement source = edge.getSource();
Statement parent = source.getParent();
source.removeSuccessor(edge);
@@ -65,7 +66,7 @@ public final class InlineSingleBlockHelper {
SequenceStatement block = new SequenceStatement(lst);
block.setAllParent();
StatEdge newedge = new StatEdge(StatEdge.TYPE_REGULAR, source, block);
StatEdge newedge = new StatEdge(EdgeType.REGULAR, source, block);
source.addSuccessor(newedge);
ifparent.setIfEdge(newedge);
ifparent.setIfstat(block);
@@ -84,7 +85,7 @@ public final class InlineSingleBlockHelper {
// LabelHelper.lowContinueLabels not applicable because of forward continue edges
// LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>());
// do it by hand
for (StatEdge prededge : block.getPredecessorEdges(StatEdge.TYPE_CONTINUE)) {
for (StatEdge prededge : block.getPredecessorEdges(EdgeType.CONTINUE)) {
block.removePredecessor(prededge);
prededge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, prededge, source);
@@ -98,7 +99,7 @@ public final class InlineSingleBlockHelper {
((SwitchStatement)parent).sortEdgesAndNodes();
}
source.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, source, first));
source.addSuccessor(new StatEdge(EdgeType.REGULAR, source, first));
}
}
@@ -112,7 +113,7 @@ public final class InlineSingleBlockHelper {
}
List<StatEdge> lst = first.getPredecessorEdges(StatEdge.TYPE_BREAK);
List<StatEdge> lst = first.getPredecessorEdges(EdgeType.BREAK);
if (lst.size() == 1) {
StatEdge edge = lst.get(0);
@@ -166,7 +167,7 @@ public final class InlineSingleBlockHelper {
private static boolean noExitLabels(Statement block, Statement sequence) {
for (StatEdge edge : block.getAllSuccessorEdges()) {
if (edge.getType() != StatEdge.TYPE_REGULAR && edge.getDestination().type != Statement.TYPE_DUMMY_EXIT) {
if (edge.getType() != EdgeType.REGULAR && edge.getDestination().type != Statement.TYPE_DUMMY_EXIT) {
if (!sequence.containsStatementStrict(edge.getDestination())) {
return false;
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
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.DoStatement.LoopType;
@@ -39,32 +40,31 @@ public final class LabelHelper {
private static void liftClosures(Statement stat) {
for (StatEdge edge : stat.getAllSuccessorEdges()) {
switch (edge.getType()) {
case StatEdge.TYPE_CONTINUE:
if (edge.getDestination() != edge.closure) {
edge.getDestination().addLabeledEdge(edge);
if (EdgeType.CONTINUE.equals(edge.getType())) {
if (edge.getDestination() != edge.closure) {
edge.getDestination().addLabeledEdge(edge);
}
}
else if (EdgeType.BREAK.equals(edge.getType())) {
Statement dest = edge.getDestination();
if (dest.type != Statement.TYPE_DUMMY_EXIT) {
Statement parent = dest.getParent();
List<Statement> lst = new ArrayList<>();
if (parent.type == Statement.TYPE_SEQUENCE) {
lst.addAll(parent.getStats());
}
else if (parent.type == Statement.TYPE_SWITCH) {
lst.addAll(((SwitchStatement)parent).getCaseStatements());
}
break;
case StatEdge.TYPE_BREAK:
Statement dest = edge.getDestination();
if (dest.type != Statement.TYPE_DUMMY_EXIT) {
Statement parent = dest.getParent();
List<Statement> lst = new ArrayList<>();
if (parent.type == Statement.TYPE_SEQUENCE) {
lst.addAll(parent.getStats());
}
else if (parent.type == Statement.TYPE_SWITCH) {
lst.addAll(((SwitchStatement)parent).getCaseStatements());
}
for (int i = 0; i < lst.size(); i++) {
if (lst.get(i) == dest) {
lst.get(i - 1).addLabeledEdge(edge);
break;
}
for (int i = 0; i < lst.size(); i++) {
if (lst.get(i) == dest) {
lst.get(i - 1).addLabeledEdge(edge);
break;
}
}
}
}
}
@@ -80,7 +80,7 @@ public final class LabelHelper {
}
if (!stat.hasBasicSuccEdge()) {
for (StatEdge edge : stat.getSuccessorEdges(StatEdge.TYPE_CONTINUE | StatEdge.TYPE_BREAK)) {
for (StatEdge edge : stat.getSuccessorEdges(EdgeType.CONTINUE.unite(EdgeType.BREAK))) {
stat.removeSuccessor(edge);
}
}
@@ -97,7 +97,7 @@ public final class LabelHelper {
}
if (ok) {
edges.addAll(stat.getPredecessorEdges(StatEdge.TYPE_CONTINUE));
edges.addAll(stat.getPredecessorEdges(EdgeType.CONTINUE));
}
if (ok && stat.type == Statement.TYPE_DO) {
@@ -127,7 +127,7 @@ public final class LabelHelper {
for (StatEdge edge : new ArrayList<>(stat.getLabelEdges())) {
if (edge.getType() == StatEdge.TYPE_BREAK) { // FIXME: ?
if (edge.getType() == EdgeType.BREAK) { // FIXME: ?
for (Statement st : stat.getStats()) {
if (st.containsStatementStrict(edge.getSource())) {
if (MergeHelper.isDirectPath(st, edge.getDestination())) {
@@ -159,7 +159,7 @@ public final class LabelHelper {
Statement exit = root.getDummyExit();
for (StatEdge edge : exit.getAllPredecessorEdges()) {
List<Exprent> lst = edge.getSource().getExprents();
if (edge.getType() == StatEdge.TYPE_FINALLYEXIT || (lst != null && !lst.isEmpty() &&
if (edge.getType() == EdgeType.FINALLY_EXIT || (lst != null && !lst.isEmpty() &&
lst.get(lst.size() - 1).type == Exprent.EXPRENT_EXIT)) {
edge.labeled = false;
}
@@ -425,8 +425,8 @@ public final class LabelHelper {
boolean shieldType = (stat.type == Statement.TYPE_DO || stat.type == Statement.TYPE_SWITCH);
if (shieldType) {
for (StatEdge edge : stat.getLabelEdges()) {
if (edge.explicit && ((edge.getType() == StatEdge.TYPE_BREAK && sets.breaks.contains(edge.getSource())) ||
(edge.getType() == StatEdge.TYPE_CONTINUE && sets.continues.contains(edge.getSource())))) {
if (edge.explicit && ((edge.getType() == EdgeType.BREAK && sets.breaks.contains(edge.getSource())) ||
(edge.getType() == EdgeType.CONTINUE && sets.continues.contains(edge.getSource())))) {
edge.labeled = false;
}
}
@@ -450,7 +450,7 @@ public final class LabelHelper {
if (stat.type == Statement.TYPE_DO) {
List<StatEdge> lst = stat.getPredecessorEdges(StatEdge.TYPE_CONTINUE);
List<StatEdge> lst = stat.getPredecessorEdges(EdgeType.CONTINUE);
for (StatEdge edge : lst) {
@@ -459,7 +459,7 @@ public final class LabelHelper {
if (minclosure != edge.closure &&
!InlineSingleBlockHelper.isBreakEdgeLabeled(edge.getSource(), minclosure)) {
edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, StatEdge.TYPE_BREAK);
edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, EdgeType.BREAK);
edge.labeled = false;
minclosure.addLabeledEdge(edge);
}

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement;
import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement.LoopType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.IfStatement;
@@ -65,7 +66,7 @@ public final class LoopExtractHelper {
}
for (StatEdge edge : stat.getLabelEdges()) {
if (edge.getType() != StatEdge.TYPE_CONTINUE && edge.getDestination().type != Statement.TYPE_DUMMY_EXIT) {
if (edge.getType() != EdgeType.CONTINUE && edge.getDestination().type != Statement.TYPE_DUMMY_EXIT) {
return false;
}
}
@@ -87,9 +88,9 @@ public final class LoopExtractHelper {
Statement ifstat = lastif.getIfstat();
StatEdge elseedge = lastif.getAllSuccessorEdges().get(0);
if (elseedge.getType() == StatEdge.TYPE_CONTINUE && elseedge.closure == stat) {
if (elseedge.getType() == EdgeType.CONTINUE && elseedge.closure == stat) {
Set<Statement> set = stat.getNeighboursSet(StatEdge.TYPE_CONTINUE, Statement.DIRECTION_BACKWARD);
Set<Statement> set = stat.getNeighboursSet(EdgeType.CONTINUE, Statement.DIRECTION_BACKWARD);
set.remove(last);
if (set.isEmpty()) { // no direct continues in a do{}while loop
@@ -157,7 +158,7 @@ public final class LoopExtractHelper {
StatEdge ifedge = ifstat.getIfEdge();
ifstat.setIfstat(null);
ifedge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, ifedge, StatEdge.TYPE_BREAK);
ifedge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, ifedge, EdgeType.BREAK);
ifedge.closure = loop;
ifstat.getStats().removeWithKey(target.id);
@@ -167,15 +168,15 @@ public final class LoopExtractHelper {
loop.getParent().replaceStatement(loop, block);
block.setAllParent();
loop.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, loop, target));
loop.addSuccessor(new StatEdge(EdgeType.REGULAR, loop, target));
for (StatEdge edge : new ArrayList<>(block.getLabelEdges())) {
if (edge.getType() == StatEdge.TYPE_CONTINUE || edge == ifedge) {
if (edge.getType() == EdgeType.CONTINUE || edge == ifedge) {
loop.addLabeledEdge(edge);
}
}
for (StatEdge edge : block.getPredecessorEdges(StatEdge.TYPE_CONTINUE)) {
for (StatEdge edge : block.getPredecessorEdges(EdgeType.CONTINUE)) {
if (loop.containsStatementStrict(edge.getSource())) {
block.removePredecessor(edge);
edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, loop);

View File

@@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.code.cfg.BasicBlock;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.IfExprent;
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
@@ -72,12 +73,12 @@ public final class MergeHelper {
StatEdge ifedge = lastif.getIfEdge();
StatEdge elseedge = lastif.getAllSuccessorEdges().get(0);
if ((ifedge.getType() == StatEdge.TYPE_BREAK && elseedge.getType() == StatEdge.TYPE_CONTINUE && elseedge.closure == stat
if ((ifedge.getType() == EdgeType.BREAK && elseedge.getType() == EdgeType.CONTINUE && elseedge.closure == stat
&& isDirectPath(stat, ifedge.getDestination())) ||
(ifedge.getType() == StatEdge.TYPE_CONTINUE && elseedge.getType() == StatEdge.TYPE_BREAK && ifedge.closure == stat
(ifedge.getType() == EdgeType.CONTINUE && elseedge.getType() == EdgeType.BREAK && ifedge.closure == stat
&& isDirectPath(stat, elseedge.getDestination()))) {
Set<Statement> set = stat.getNeighboursSet(StatEdge.TYPE_CONTINUE, Statement.DIRECTION_BACKWARD);
Set<Statement> set = stat.getNeighboursSet(EdgeType.CONTINUE, Statement.DIRECTION_BACKWARD);
set.remove(last);
if (!set.isEmpty()) {
@@ -87,7 +88,7 @@ public final class MergeHelper {
stat.setLoopType(LoopType.DO_WHILE);
IfExprent ifexpr = (IfExprent)lastif.getHeadexprent().copy();
if (ifedge.getType() == StatEdge.TYPE_BREAK) {
if (ifedge.getType() == EdgeType.BREAK) {
ifexpr.negateIf();
}
stat.setConditionExprent(ifexpr.getCondition());
@@ -101,13 +102,13 @@ public final class MergeHelper {
else {
lastif.setExprents(lastif.getFirst().getExprents());
StatEdge newedge = new StatEdge(StatEdge.TYPE_CONTINUE, lastif, stat);
StatEdge newedge = new StatEdge(EdgeType.CONTINUE, lastif, stat);
lastif.addSuccessor(newedge);
stat.addLabeledEdge(newedge);
}
if (stat.getAllSuccessorEdges().isEmpty()) {
StatEdge edge = elseedge.getType() == StatEdge.TYPE_CONTINUE ? ifedge : elseedge;
StatEdge edge = elseedge.getType() == EdgeType.CONTINUE ? ifedge : elseedge;
edge.setSource(stat);
if (edge.closure == stat) {
@@ -213,7 +214,7 @@ public final class MergeHelper {
first.getParent().replaceStatement(first, firstif.getIfstat());
// lift closures
for (StatEdge prededge : elseedge.getDestination().getPredecessorEdges(StatEdge.TYPE_BREAK)) {
for (StatEdge prededge : elseedge.getDestination().getPredecessorEdges(EdgeType.BREAK)) {
if (stat.containsStatementStrict(prededge.closure)) {
stat.addLabeledEdge(prededge);
}
@@ -233,7 +234,7 @@ public final class MergeHelper {
public static boolean isDirectPath(Statement stat, Statement endstat) {
Set<Statement> setStat = stat.getNeighboursSet(Statement.STATEDGE_DIRECT_ALL, Statement.DIRECTION_FORWARD);
Set<Statement> setStat = stat.getNeighboursSet(EdgeType.DIRECT_ALL, Statement.DIRECTION_FORWARD);
if (setStat.isEmpty()) {
Statement parent = stat.getParent();
if (parent == null) {
@@ -308,7 +309,7 @@ public final class MergeHelper {
current = parent;
}
else {
preData = current.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD).get(0);
preData = current.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD).get(0);
preData = getLastDirectData(preData);
if (preData != null && !preData.getExprents().isEmpty()) {
initDoExprent = preData.getExprents().get(preData.getExprents().size() - 1);
@@ -325,7 +326,7 @@ public final class MergeHelper {
}
if (hasinit || issingle) { // FIXME: issingle sufficient?
Set<Statement> set = stat.getNeighboursSet(StatEdge.TYPE_CONTINUE, Statement.DIRECTION_BACKWARD);
Set<Statement> set = stat.getNeighboursSet(EdgeType.CONTINUE, Statement.DIRECTION_BACKWARD);
set.remove(lastData);
if (!set.isEmpty()) {
@@ -358,7 +359,7 @@ public final class MergeHelper {
}
else {
for (StatEdge edge : stat.getAllPredecessorEdges()) {
edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, StatEdge.TYPE_CONTINUE);
edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, EdgeType.CONTINUE);
stat.removePredecessor(edge);
edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, dostat);

View File

@@ -4,6 +4,7 @@ package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.java.decompiler.code.cfg.BasicBlock;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement;
import org.jetbrains.java.decompiler.modules.decompiler.stats.SequenceStatement;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
@@ -47,7 +48,7 @@ public final class SequenceHelper {
// move successors
Statement last = st.getStats().getLast();
if (last.getAllSuccessorEdges().isEmpty() && i < lst.size() - 1) {
last.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, last, lst.get(i + 1)));
last.addSuccessor(new StatEdge(EdgeType.REGULAR, last, lst.get(i + 1)));
}
else {
for (StatEdge edge : last.getAllSuccessorEdges()) {
@@ -57,7 +58,7 @@ public final class SequenceHelper {
}
}
else {
edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, StatEdge.TYPE_REGULAR);
edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, EdgeType.REGULAR);
edge.closure.getLabelEdges().remove(edge);
edge.closure = null;
}
@@ -152,7 +153,7 @@ public final class SequenceHelper {
}
}
for (StatEdge edge : next.getPredecessorEdges(StatEdge.TYPE_BREAK)) {
for (StatEdge edge : next.getPredecessorEdges(EdgeType.BREAK)) {
if (last != edge.getSource() && !last.containsStatementStrict(edge.getSource())) {
return false;
}
@@ -178,7 +179,7 @@ public final class SequenceHelper {
if (st.getExprents() != null && st.getExprents().isEmpty()) {
if (st.getAllSuccessorEdges().isEmpty()) {
List<StatEdge> lstBreaks = st.getPredecessorEdges(StatEdge.TYPE_BREAK);
List<StatEdge> lstBreaks = st.getPredecessorEdges(EdgeType.BREAK);
if (lstBreaks.isEmpty()) {
for (StatEdge edge : st.getAllPredecessorEdges()) {
@@ -189,11 +190,11 @@ public final class SequenceHelper {
}
else {
StatEdge sucedge = st.getAllSuccessorEdges().get(0);
if (sucedge.getType() != StatEdge.TYPE_FINALLYEXIT) {
if (sucedge.getType() != EdgeType.FINALLY_EXIT) {
st.removeSuccessor(sucedge);
for (StatEdge edge : st.getAllPredecessorEdges()) {
if (sucedge.getType() != StatEdge.TYPE_REGULAR) {
if (sucedge.getType() != EdgeType.REGULAR) {
edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, sucedge.getType());
}

View File

@@ -6,6 +6,7 @@ import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.main.rels.ClassWrapper;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.SSAConstructorSparseEx;
import org.jetbrains.java.decompiler.modules.decompiler.stats.IfStatement;
@@ -724,7 +725,7 @@ public class SimplifyExprentsHelper {
StatEdge retEdge = ifStatement.getAllSuccessorEdges().get(0);
Statement closure = retEdge.closure == statement ? statement.getParent() : retEdge.closure;
statement.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, statement, retEdge.getDestination(), closure));
statement.addSuccessor(new StatEdge(EdgeType.BREAK, statement, retEdge.getDestination(), closure));
SequenceHelper.destroyAndFlattenStatement(statement);

View File

@@ -1,70 +1,49 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
import java.util.ArrayList;
import java.util.List;
public class StatEdge {
public static final int TYPE_REGULAR = 1;
public static final int TYPE_EXCEPTION = 2;
public static final int TYPE_BREAK = 4;
public static final int TYPE_CONTINUE = 8;
public static final int TYPE_FINALLYEXIT = 32;
public static final int[] TYPES = new int[]{
TYPE_REGULAR,
TYPE_EXCEPTION,
TYPE_BREAK,
TYPE_CONTINUE,
TYPE_FINALLYEXIT
};
private int type;
private @NotNull EdgeType type;
private Statement source;
private Statement destination;
private List<String> exceptions;
public Statement closure;
public boolean labeled = true;
public boolean explicit = true;
public StatEdge(int type, Statement source, Statement destination, Statement closure) {
public StatEdge(@NotNull EdgeType type, Statement source, Statement destination, Statement closure) {
this(type, source, destination);
this.closure = closure;
}
public StatEdge(int type, Statement source, Statement destination) {
public StatEdge(@NotNull EdgeType type, Statement source, Statement destination) {
this.type = type;
this.source = source;
this.destination = destination;
}
public StatEdge(Statement source, Statement destination, List<String> exceptions) {
this(TYPE_EXCEPTION, source, destination);
this(EdgeType.EXCEPTION, source, destination);
if (exceptions != null) {
this.exceptions = new ArrayList<>(exceptions);
}
}
public int getType() {
public @NotNull EdgeType getType() {
return type;
}
public void setType(int type) {
public void setType(@NotNull EdgeType type) {
this.type = type;
}
public Statement getSource() {
return source;
}
public void setSource(Statement source) {
this.source = source;
}
@@ -72,7 +51,6 @@ public class StatEdge {
public Statement getDestination() {
return destination;
}
public void setDestination(Statement destination) {
this.destination = destination;
}
@@ -81,7 +59,130 @@ public class StatEdge {
return this.exceptions;
}
// public void setException(String exception) {
// this.exception = exception;
// }
/**
* Type of the edges between statements.
* @see Statement
*/
public interface EdgeType {
EdgeType REGULAR = new EdgeType() {
@Override
public int mask() {
return 1;
}
@Override
public String toString() {
return "REGULAR";
}
};
EdgeType EXCEPTION = new EdgeType() {
@Override
public int mask() {
return 2;
}
@Override
public String toString() {
return "EXCEPTION";
}
};
EdgeType BREAK = new EdgeType() {
@Override
public int mask() {
return 4;
}
@Override
public String toString() {
return "BREAK";
}
};
EdgeType CONTINUE = new EdgeType() {
@Override
public int mask() {
return 8;
}
@Override
public String toString() {
return "CONTINUE";
}
};
EdgeType FINALLY_EXIT = new EdgeType() {
@Override
public int mask() {
return 32;
}
@Override
public String toString() {
return "FINALLY_EXIT";
}
};
EdgeType ALL = new EdgeType() {
@Override
public int mask() {
return 0x80000000;
}
@Override
public @NotNull EdgeType unite(@NotNull EdgeType other) {
return this;
}
@Override
public String toString() {
return "ALL";
}
};
EdgeType DIRECT_ALL = new EdgeType() {
@Override
public int mask() {
return 0x40000000;
}
@Override
public @NotNull EdgeType unite(@NotNull EdgeType other) {
return this;
}
@Override
public String toString() {
return "DIRECT_ALL";
}
};
EdgeType NULL = new EdgeType() {
@Override
public int mask() {
return -1;
}
@Override
public @NotNull EdgeType unite(@NotNull EdgeType other) {
throw new UnsupportedOperationException("Union operation is not supported for NULL edge type");
}
};
int mask();
default @NotNull EdgeType unite(@NotNull EdgeType other) {
return new EdgeType() {
@Override
public int mask() {
return EdgeType.this.mask() | other.mask();
}
};
}
static EdgeType[] types() {
return new EdgeType[] {REGULAR, EXCEPTION, BREAK, CONTINUE, FINALLY_EXIT};
}
}
}

View File

@@ -2,6 +2,7 @@
package org.jetbrains.java.decompiler.modules.decompiler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
import org.jetbrains.java.decompiler.util.ListStack;
@@ -26,7 +27,7 @@ public class StrongConnectivityHelper {
public StrongConnectivityHelper(@NotNull Statement startStatement) {
visitTree(startStatement.getFirst());
for (Statement statement : startStatement.getStats()) {
if (!setProcessed.contains(statement) && statement.getPredecessorEdges(Statement.STATEDGE_DIRECT_ALL).isEmpty()) {
if (!setProcessed.contains(statement) && statement.getPredecessorEdges(EdgeType.DIRECT_ALL).isEmpty()) {
visitTree(statement);
}
}
@@ -56,7 +57,7 @@ public class StrongConnectivityHelper {
indices.put(statement, nextIndex);
lowIndices.put(statement, nextIndex);
nextIndex++;
List<Statement> successors = statement.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD); // TODO: set?
List<Statement> successors = statement.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_FORWARD); // TODO: set?
successors.removeAll(setProcessed);
for (Statement successor : successors) {
int successorIndex;
@@ -85,7 +86,7 @@ public class StrongConnectivityHelper {
public static boolean isExitComponent(@NotNull List<? extends Statement> component) {
Set<Statement> statements = new HashSet<>();
for (Statement statement : component) {
statements.addAll(statement.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD));
statements.addAll(statement.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_FORWARD));
}
for (Statement statement : component) {
statements.remove(statement);

View File

@@ -8,6 +8,7 @@ import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
import org.jetbrains.java.decompiler.struct.gen.VarType;
@@ -479,10 +480,10 @@ public final class SwitchHelper {
}
private static void removeOuterBreakEdge(@NotNull IfStatement ifStatement) {
List<StatEdge> ifStatementBreakEdges = ifStatement.getSuccessorEdges(StatEdge.TYPE_BREAK);
List<StatEdge> ifStatementBreakEdges = ifStatement.getSuccessorEdges(EdgeType.BREAK);
if (ifStatementBreakEdges.size() != 1) return;
Statement lastStatement = ifStatement.getStats().get(ifStatement.getStats().size() - 1);
List<StatEdge> lastStatementBreakEdges = lastStatement.getSuccessorEdges(StatEdge.TYPE_BREAK);
List<StatEdge> lastStatementBreakEdges = lastStatement.getSuccessorEdges(EdgeType.BREAK);
if (lastStatementBreakEdges.size() != 1) return;
StatEdge firstIfStatementBreakEdge = ifStatementBreakEdges.get(0);
StatEdge lastStatementBreakEdge = lastStatementBreakEdges.get(0);

View File

@@ -1,7 +1,7 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.decompiler.decompose;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
import org.jetbrains.java.decompiler.util.VBStyleCollection;
@@ -75,7 +75,7 @@ public class DominatorTreeExceptionFilter {
private void buildExceptionRanges() {
for (Statement stat : statement.getStats()) {
List<Statement> lstPreds = stat.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD);
List<Statement> lstPreds = stat.getNeighbours(EdgeType.EXCEPTION, Statement.DIRECTION_BACKWARD);
if (!lstPreds.isEmpty()) {
Set<Integer> set = new HashSet<>();

View File

@@ -2,6 +2,7 @@
package org.jetbrains.java.decompiler.modules.decompiler.decompose;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
import org.jetbrains.java.decompiler.util.FastFixedSetFactory;
import org.jetbrains.java.decompiler.util.FastFixedSetFactory.FastFixedSet;
@@ -96,7 +97,7 @@ public class FastExtendedPostdominanceHelper {
continue;
}
for (StatEdge edge : stat.getSuccessorEdges(StatEdge.TYPE_REGULAR)) {
for (StatEdge edge : stat.getSuccessorEdges(EdgeType.REGULAR)) {
Statement edge_destination = edge.getDestination();
@@ -133,7 +134,7 @@ public class FastExtendedPostdominanceHelper {
private void removeErroneousNodes() {
mapSupportPoints = new HashMap<>();
calcReachabilitySuppPoints(StatEdge.TYPE_REGULAR);
calcReachabilitySuppPoints(EdgeType.REGULAR);
iterateReachability((node, mapSets) -> {
Integer nodeid = node.id;
@@ -141,7 +142,7 @@ public class FastExtendedPostdominanceHelper {
FastFixedSet<Integer> setReachability = mapSets.get(nodeid);
List<FastFixedSet<Integer>> lstPredSets = new ArrayList<>();
for (StatEdge prededge : node.getPredecessorEdges(StatEdge.TYPE_REGULAR)) {
for (StatEdge prededge : node.getPredecessorEdges(EdgeType.REGULAR)) {
FastFixedSet<Integer> setPred = mapSets.get(prededge.getSource().id);
if (setPred == null) {
setPred = mapSupportPoints.get(prededge.getSource().id);
@@ -183,7 +184,7 @@ public class FastExtendedPostdominanceHelper {
}
return false;
}, StatEdge.TYPE_REGULAR);
}, EdgeType.REGULAR);
// exception handlers cannot be postdominator nodes
// TODO: replace with a standard set?
@@ -191,8 +192,8 @@ public class FastExtendedPostdominanceHelper {
boolean handlerfound = false;
for (Statement stat : statement.getStats()) {
if (stat.getPredecessorEdges(Statement.STATEDGE_DIRECT_ALL).isEmpty() &&
!stat.getPredecessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty()) { // exception handler
if (stat.getPredecessorEdges(EdgeType.DIRECT_ALL).isEmpty() &&
!stat.getPredecessorEdges(EdgeType.EXCEPTION).isEmpty()) { // exception handler
setHandlers.add(stat.id);
handlerfound = true;
}
@@ -206,7 +207,7 @@ public class FastExtendedPostdominanceHelper {
}
private void calcDefaultReachableSets() {
int edgetype = StatEdge.TYPE_REGULAR | StatEdge.TYPE_EXCEPTION;
EdgeType edgetype = EdgeType.REGULAR.unite(EdgeType.EXCEPTION);
calcReachabilitySuppPoints(edgetype);
@@ -226,11 +227,11 @@ public class FastExtendedPostdominanceHelper {
}, edgetype);
}
private void calcReachabilitySuppPoints(final int edgetype) {
private void calcReachabilitySuppPoints(final EdgeType edgetype) {
iterateReachability((node, mapSets) -> {
// consider to be a support point
for (StatEdge sucedge : node.getAllSuccessorEdges()) {
if ((sucedge.getType() & edgetype) != 0) {
if ((sucedge.getType().mask() & edgetype.mask()) != 0) {
if (mapSets.containsKey(sucedge.getDestination().id)) {
FastFixedSet<Integer> setReachability = mapSets.get(node.id);
@@ -246,7 +247,7 @@ public class FastExtendedPostdominanceHelper {
}, edgetype);
}
private void iterateReachability(IReachabilityAction action, int edgetype) {
private void iterateReachability(IReachabilityAction action, EdgeType edgetype) {
while (true) {
boolean iterate = false;
@@ -258,7 +259,7 @@ public class FastExtendedPostdominanceHelper {
set.add(stat.id);
for (StatEdge prededge : stat.getAllPredecessorEdges()) {
if ((prededge.getType() & edgetype) != 0) {
if ((prededge.getType().mask() & edgetype.mask()) != 0) {
Statement pred = prededge.getSource();
FastFixedSet<Integer> setPred = mapSets.get(pred.id);
@@ -280,13 +281,13 @@ public class FastExtendedPostdominanceHelper {
// remove reachability information of fully processed nodes (saves memory)
for (StatEdge prededge : stat.getAllPredecessorEdges()) {
if ((prededge.getType() & edgetype) != 0) {
if ((prededge.getType().mask() & edgetype.mask()) != 0) {
Statement pred = prededge.getSource();
if (mapSets.containsKey(pred.id)) {
boolean remstat = true;
for (StatEdge sucedge : pred.getAllSuccessorEdges()) {
if ((sucedge.getType() & edgetype) != 0) {
if ((sucedge.getType().mask() & edgetype.mask()) != 0) {
if (!mapSets.containsKey(sucedge.getDestination().id)) {
remstat = false;
break;

View File

@@ -2,6 +2,7 @@
package org.jetbrains.java.decompiler.modules.decompiler.deobfuscator;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.BasicBlockStatement;
import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
@@ -29,7 +30,7 @@ public final class IrreducibleCFGDeobfuscator {
// checking exceptions and creating nodes
for (Statement stat : statement.getStats()) {
if (!stat.getSuccessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty()) {
if (!stat.getSuccessorEdges(EdgeType.EXCEPTION).isEmpty()) {
return false;
}
@@ -40,7 +41,7 @@ public final class IrreducibleCFGDeobfuscator {
for (Statement stat : statement.getStats()) {
Node node = mapNodes.get(stat.id);
for (Statement succ : stat.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD)) {
for (Statement succ : stat.getNeighbours(EdgeType.REGULAR, Statement.DIRECTION_FORWARD)) {
Node nodeSucc = mapNodes.get(succ.id);
node.succs.add(nodeSucc);
@@ -101,10 +102,10 @@ public final class IrreducibleCFGDeobfuscator {
for (Statement stat : statement.getStats()) {
Set<Statement> setPreds = stat.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
Set<Statement> setPreds = stat.getNeighboursSet(EdgeType.REGULAR, Statement.DIRECTION_BACKWARD);
if (setPreds.size() > 1) {
int succCount = stat.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD).size();
int succCount = stat.getNeighboursSet(EdgeType.REGULAR, Statement.DIRECTION_FORWARD).size();
if (succCount <= succsCandidateForSplitting) {
int size = getStatementSize(stat) * (setPreds.size() - 1);
@@ -128,7 +129,7 @@ public final class IrreducibleCFGDeobfuscator {
return false;
}
StatEdge enteredge = splitnode.getPredecessorEdges(StatEdge.TYPE_REGULAR).iterator().next();
StatEdge enteredge = splitnode.getPredecessorEdges(EdgeType.REGULAR).iterator().next();
// copy the smallest statement
Statement splitcopy = copyStatement(splitnode, null, new HashMap<>());
@@ -139,7 +140,7 @@ public final class IrreducibleCFGDeobfuscator {
statement.getStats().addWithKey(splitcopy, splitcopy.id);
// switch input edges
for (StatEdge prededge : splitnode.getPredecessorEdges(Statement.STATEDGE_DIRECT_ALL)) {
for (StatEdge prededge : splitnode.getPredecessorEdges(EdgeType.DIRECT_ALL)) {
if (prededge.getSource() == enteredge.getSource() ||
prededge.closure == enteredge.getSource()) {
splitnode.removePredecessor(prededge);
@@ -149,7 +150,7 @@ public final class IrreducibleCFGDeobfuscator {
}
// connect successors
for (StatEdge succ : splitnode.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL)) {
for (StatEdge succ : splitnode.getSuccessorEdges(EdgeType.DIRECT_ALL)) {
splitcopy.addSuccessor(new StatEdge(succ.getType(), splitcopy, succ.getDestination(), succ.closure));
}
@@ -191,7 +192,7 @@ public final class IrreducibleCFGDeobfuscator {
Statement stold = from.getStats().get(i);
Statement stnew = to.getStats().get(i);
for (StatEdge edgeold : stold.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL)) {
for (StatEdge edgeold : stold.getSuccessorEdges(EdgeType.DIRECT_ALL)) {
// type cannot be TYPE_EXCEPTION (checked in isIrreducibleTriangle)
StatEdge edgenew = new StatEdge(edgeold.getType(), stnew,
mapAltToCopies.containsKey(edgeold.getDestination())

View File

@@ -2,6 +2,7 @@
package org.jetbrains.java.decompiler.modules.decompiler.sforms;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode.DirectNodeType;
import org.jetbrains.java.decompiler.modules.decompiler.stats.*;
@@ -102,7 +103,7 @@ public class FlattenStatementsHelper {
graph.nodes.putWithKey(node, node.id);
mapDestinationNodes.put(stat.id, new String[]{node.id, null});
lstSuccEdges.addAll(stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL));
lstSuccEdges.addAll(stat.getSuccessorEdges(EdgeType.DIRECT_ALL));
sourcenode = node;
List<Exprent> tailExprentList = statEntry.tailExprents;
@@ -113,7 +114,7 @@ public class FlattenStatementsHelper {
graph.nodes.putWithKey(tail, tail.id);
mapDestinationNodes.put(-stat.id, new String[]{tail.id, null});
listEdges.add(new Edge(node.id, -stat.id, StatEdge.TYPE_REGULAR));
listEdges.add(new Edge(node.id, -stat.id, EdgeType.REGULAR));
sourcenode = tail;
}
@@ -134,7 +135,7 @@ public class FlattenStatementsHelper {
LinkedList<StatementStackEntry> lst = new LinkedList<>();
for (Statement st : stat.getStats()) {
listEdges.add(new Edge(firstnd.id, st.id, StatEdge.TYPE_REGULAR));
listEdges.add(new Edge(firstnd.id, st.id, EdgeType.REGULAR));
LinkedList<StackEntry> stack = stackFinally;
if (stat.type == Statement.TYPE_CATCH_ALL && ((CatchAllStatement)stat).isFinally()) {
@@ -144,7 +145,7 @@ public class FlattenStatementsHelper {
stack.add(new StackEntry((CatchAllStatement)stat, Boolean.FALSE));
}
else { // handler
stack.add(new StackEntry((CatchAllStatement)stat, Boolean.TRUE, StatEdge.TYPE_BREAK,
stack.add(new StackEntry((CatchAllStatement)stat, Boolean.TRUE, EdgeType.BREAK,
root.getDummyExit(), st, st, firstnd, firstnd, true));
}
}
@@ -172,7 +173,7 @@ public class FlattenStatementsHelper {
break;
}
lstSuccEdges.add(stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0)); // exactly one edge
lstSuccEdges.add(stat.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0)); // exactly one edge
switch (loopType) {
case WHILE:
@@ -181,7 +182,7 @@ public class FlattenStatementsHelper {
node.exprents = dostat.getConditionExprentList();
graph.nodes.putWithKey(node, node.id);
listEdges.add(new Edge(node.id, stat.getFirst().id, StatEdge.TYPE_REGULAR));
listEdges.add(new Edge(node.id, stat.getFirst().id, EdgeType.REGULAR));
if (loopType == LoopType.WHILE) {
mapDestinationNodes.put(stat.id, new String[]{node.id, node.id});
@@ -191,13 +192,13 @@ public class FlattenStatementsHelper {
boolean found = false;
for (Edge edge : listEdges) {
if (edge.statid.equals(stat.id) && edge.edgetype == StatEdge.TYPE_CONTINUE) {
if (edge.statid.equals(stat.id) && edge.edgetype == EdgeType.CONTINUE) {
found = true;
break;
}
}
if (!found) {
listEdges.add(new Edge(nd.id, stat.id, StatEdge.TYPE_CONTINUE));
listEdges.add(new Edge(nd.id, stat.id, EdgeType.CONTINUE));
}
}
sourcenode = node;
@@ -220,19 +221,19 @@ public class FlattenStatementsHelper {
mapDestinationNodes.put(stat.id, new String[]{nodeinit.id, nodeinc.id});
mapDestinationNodes.put(-stat.id, new String[]{nodecond.id, null});
listEdges.add(new Edge(nodecond.id, stat.getFirst().id, StatEdge.TYPE_REGULAR));
listEdges.add(new Edge(nodeinit.id, -stat.id, StatEdge.TYPE_REGULAR));
listEdges.add(new Edge(nodeinc.id, -stat.id, StatEdge.TYPE_REGULAR));
listEdges.add(new Edge(nodecond.id, stat.getFirst().id, EdgeType.REGULAR));
listEdges.add(new Edge(nodeinit.id, -stat.id, EdgeType.REGULAR));
listEdges.add(new Edge(nodeinc.id, -stat.id, EdgeType.REGULAR));
boolean found = false;
for (Edge edge : listEdges) {
if (edge.statid.equals(stat.id) && edge.edgetype == StatEdge.TYPE_CONTINUE) {
if (edge.statid.equals(stat.id) && edge.edgetype == EdgeType.CONTINUE) {
found = true;
break;
}
}
if (!found) {
listEdges.add(new Edge(nd.id, stat.id, StatEdge.TYPE_CONTINUE));
listEdges.add(new Edge(nd.id, stat.id, EdgeType.CONTINUE));
}
sourcenode = nodecond;
@@ -276,7 +277,7 @@ public class FlattenStatementsHelper {
mapDestinationNodes.put(stat.id, new String[]{node.id, null});
if (stat.type == Statement.TYPE_IF && ((IfStatement)stat).iftype == IfStatement.IFTYPE_IF) {
lstSuccEdges.add(stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0)); // exactly one edge
lstSuccEdges.add(stat.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0)); // exactly one edge
sourcenode = tailexprlst.get(0) == null ? node : graph.nodes.getWithKey(node.id + "_tail");
}
}
@@ -296,7 +297,7 @@ public class FlattenStatementsHelper {
LinkedList<StackEntry> stack = new LinkedList<>(stackFinally);
int edgetype = edge.getType();
EdgeType edgetype = edge.getType();
Statement destination = edge.getDestination();
DirectNode finallyShortRangeSource = sourcenode;
@@ -326,7 +327,7 @@ public class FlattenStatementsHelper {
CatchAllStatement catchall = entry.catchstatement;
if (entry.state) { // finally handler statement
if (edgetype == StatEdge.TYPE_FINALLYEXIT) {
if (edgetype == EdgeType.FINALLY_EXIT) {
stack.removeLast();
destination = entry.destination;
@@ -355,7 +356,7 @@ public class FlattenStatementsHelper {
}
else { // finally protected try statement
if (!catchall.containsStatementStrict(destination)) {
saveEdge(sourcenode, catchall.getHandler(), StatEdge.TYPE_REGULAR, isFinallyExit ? finallyShortRangeSource : null,
saveEdge(sourcenode, catchall.getHandler(), EdgeType.REGULAR, isFinallyExit ? finallyShortRangeSource : null,
finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath);
stack.removeLast();
@@ -388,19 +389,19 @@ public class FlattenStatementsHelper {
private void saveEdge(DirectNode sourcenode,
Statement destination,
int edgetype,
EdgeType edgetype,
DirectNode finallyShortRangeSource,
DirectNode finallyLongRangeSource,
Statement finallyShortRangeEntry,
Statement finallyLongRangeEntry,
boolean isFinallyMonitorExceptionPath) {
if (edgetype != StatEdge.TYPE_FINALLYEXIT) {
if (edgetype != EdgeType.FINALLY_EXIT) {
listEdges.add(new Edge(sourcenode.id, destination.id, edgetype));
}
if (finallyShortRangeSource != null) {
boolean isContinueEdge = (edgetype == StatEdge.TYPE_CONTINUE);
boolean isContinueEdge = (edgetype == EdgeType.CONTINUE);
mapShortRangeFinallyPathIds.computeIfAbsent(sourcenode.id, k -> new ArrayList<>()).add(new String[]{
finallyShortRangeSource.id,
@@ -426,7 +427,7 @@ public class FlattenStatementsHelper {
DirectNode source = graph.nodes.getWithKey(sourceid);
DirectNode dest = graph.nodes.getWithKey(mapDestinationNodes.get(statid)[edge.edgetype == StatEdge.TYPE_CONTINUE ? 1 : 0]);
DirectNode dest = graph.nodes.getWithKey(mapDestinationNodes.get(statid)[edge.edgetype == EdgeType.CONTINUE ? 1 : 0]);
if (!source.successors.contains(dest)) {
source.successors.add(dest);
@@ -510,7 +511,7 @@ public class FlattenStatementsHelper {
public final CatchAllStatement catchstatement;
public final boolean state;
public final int edgetype;
public final EdgeType edgetype;
public final boolean isFinallyExceptionPath;
public final Statement destination;
@@ -520,14 +521,14 @@ public class FlattenStatementsHelper {
public final DirectNode finallyLongRangeSource;
StackEntry(CatchAllStatement catchstatement,
boolean state,
int edgetype,
Statement destination,
Statement finallyShortRangeEntry,
Statement finallyLongRangeEntry,
DirectNode finallyShortRangeSource,
DirectNode finallyLongRangeSource,
boolean isFinallyExceptionPath) {
boolean state,
EdgeType edgetype,
Statement destination,
Statement finallyShortRangeEntry,
Statement finallyLongRangeEntry,
DirectNode finallyShortRangeSource,
DirectNode finallyLongRangeSource,
boolean isFinallyExceptionPath) {
this.catchstatement = catchstatement;
this.state = state;
@@ -542,16 +543,16 @@ public class FlattenStatementsHelper {
}
StackEntry(CatchAllStatement catchstatement, boolean state) {
this(catchstatement, state, -1, null, null, null, null, null, false);
this(catchstatement, state, EdgeType.NULL, null, null, null, null, null, false);
}
}
private static class Edge {
public final String sourceid;
public final Integer statid;
public final int edgetype;
public final EdgeType edgetype;
Edge(String sourceid, Integer statid, int edgetype) {
Edge(String sourceid, Integer statid, EdgeType edgetype) {
this.sourceid = sourceid;
this.statid = statid;
this.edgetype = edgetype;

View File

@@ -8,6 +8,7 @@ import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.TextBuffer;
@@ -45,10 +46,10 @@ public final class CatchAllStatement extends Statement {
this.handler = handler;
stats.addWithKey(handler, handler.id);
List<StatEdge> lstSuccs = head.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = head.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (!lstSuccs.isEmpty()) {
StatEdge edge = lstSuccs.get(0);
if (edge.getType() == StatEdge.TYPE_REGULAR) {
if (edge.getType() == EdgeType.REGULAR) {
post = edge.getDestination();
}
}
@@ -73,12 +74,12 @@ public final class CatchAllStatement extends Statement {
return null;
}
for (StatEdge edge : head.getSuccessorEdges(StatEdge.TYPE_EXCEPTION)) {
for (StatEdge edge : head.getSuccessorEdges(EdgeType.EXCEPTION)) {
Statement exc = edge.getDestination();
if (edge.getExceptions() == null && exc.getLastBasicType() == LASTBASICTYPE_GENERAL && setHandlers.contains(exc)) {
List<StatEdge> lstSuccs = exc.getSuccessorEdges(STATEDGE_DIRECT_ALL);
if (lstSuccs.isEmpty() || lstSuccs.get(0).getType() != StatEdge.TYPE_REGULAR) {
List<StatEdge> lstSuccs = exc.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (lstSuccs.isEmpty() || lstSuccs.get(0).getType() != EdgeType.REGULAR) {
if (head.isMonitorEnter() || exc.isMonitorEnter()) {
return null;
@@ -108,7 +109,7 @@ public final class CatchAllStatement extends Statement {
tracer.incrementCurrentSourceLine();
}
List<StatEdge> lstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = first.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (first.type == TYPE_TRY_CATCH && first.varDefinitions.isEmpty() && isFinally &&
!labeled && !first.isLabeled() && (lstSuccs.isEmpty() || !lstSuccs.get(0).explicit)) {
TextBuffer content = ExprProcessor.jmpWrapper(first, indent, true, tracer);

View File

@@ -9,11 +9,15 @@ import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import org.jetbrains.java.decompiler.util.TextBuffer;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public final class CatchStatement extends Statement {
private final List<List<String>> exctstrings = new ArrayList<>();
@@ -33,7 +37,7 @@ public final class CatchStatement extends Statement {
first = head;
stats.addWithKey(first, first.id);
for (StatEdge edge : head.getSuccessorEdges(StatEdge.TYPE_EXCEPTION)) {
for (StatEdge edge : head.getSuccessorEdges(EdgeType.EXCEPTION)) {
Statement stat = edge.getDestination();
if (setHandlers.contains(stat)) {
@@ -66,13 +70,13 @@ public final class CatchStatement extends Statement {
int hnextcount = 0; // either no statements with connection to next, or more than 1
Statement next = null;
List<StatEdge> lstHeadSuccs = head.getSuccessorEdges(STATEDGE_DIRECT_ALL);
if (!lstHeadSuccs.isEmpty() && lstHeadSuccs.get(0).getType() == StatEdge.TYPE_REGULAR) {
List<StatEdge> lstHeadSuccs = head.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (!lstHeadSuccs.isEmpty() && lstHeadSuccs.get(0).getType() == EdgeType.REGULAR) {
next = lstHeadSuccs.get(0).getDestination();
hnextcount = 2;
}
for (StatEdge edge : head.getSuccessorEdges(StatEdge.TYPE_EXCEPTION)) {
for (StatEdge edge : head.getSuccessorEdges(EdgeType.EXCEPTION)) {
Statement stat = edge.getDestination();
boolean handlerok = true;
@@ -82,8 +86,8 @@ public final class CatchStatement extends Statement {
handlerok = false;
}
else {
List<StatEdge> lstStatSuccs = stat.getSuccessorEdges(STATEDGE_DIRECT_ALL);
if (!lstStatSuccs.isEmpty() && lstStatSuccs.get(0).getType() == StatEdge.TYPE_REGULAR) {
List<StatEdge> lstStatSuccs = stat.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (!lstStatSuccs.isEmpty() && lstStatSuccs.get(0).getType() == EdgeType.REGULAR) {
Statement statn = lstStatSuccs.get(0).getDestination();

View File

@@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.util.TextBuffer;
@@ -39,16 +40,16 @@ public final class DoStatement extends Statement {
if (head.getLastBasicType() == LASTBASICTYPE_GENERAL && !head.isMonitorEnter()) {
// at most one outgoing edge
StatEdge edge = null;
List<StatEdge> successorEdges = head.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> successorEdges = head.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (!successorEdges.isEmpty()) {
edge = successorEdges.get(0);
}
// regular loop
if (edge != null && edge.getType() == StatEdge.TYPE_REGULAR && edge.getDestination() == head) {
if (edge != null && edge.getType() == EdgeType.REGULAR && edge.getDestination() == head) {
return new DoStatement(head);
}
// continues
if (head.type != TYPE_DO && (edge == null || edge.getType() != StatEdge.TYPE_REGULAR) &&
if (head.type != TYPE_DO && (edge == null || edge.getType() != EdgeType.REGULAR) &&
head.getContinueSet().contains(head.getBasichead())) {
return new DoStatement(head);
}

View File

@@ -5,6 +5,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.IfExprent;
import org.jetbrains.java.decompiler.struct.match.IMatchable;
@@ -55,7 +56,7 @@ public final class IfStatement extends Statement {
first = head;
stats.addWithKey(head, head.id);
List<StatEdge> lstHeadSuccs = head.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstHeadSuccs = head.getSuccessorEdges(EdgeType.DIRECT_ALL);
switch (regedges) {
case 0:
@@ -68,7 +69,7 @@ public final class IfStatement extends Statement {
elsestat = null;
StatEdge edgeif = lstHeadSuccs.get(1);
if (edgeif.getType() != StatEdge.TYPE_REGULAR) {
if (edgeif.getType() != EdgeType.REGULAR) {
post = lstHeadSuccs.get(0).getDestination();
}
else {
@@ -80,13 +81,13 @@ public final class IfStatement extends Statement {
elsestat = lstHeadSuccs.get(0).getDestination();
ifstat = lstHeadSuccs.get(1).getDestination();
List<StatEdge> lstSucc = ifstat.getSuccessorEdges(StatEdge.TYPE_REGULAR);
List<StatEdge> lstSucc1 = elsestat.getSuccessorEdges(StatEdge.TYPE_REGULAR);
List<StatEdge> lstSucc = ifstat.getSuccessorEdges(EdgeType.REGULAR);
List<StatEdge> lstSucc1 = elsestat.getSuccessorEdges(EdgeType.REGULAR);
if (ifstat.getPredecessorEdges(StatEdge.TYPE_REGULAR).size() > 1 || lstSucc.size() > 1) {
if (ifstat.getPredecessorEdges(EdgeType.REGULAR).size() > 1 || lstSucc.size() > 1) {
post = ifstat;
}
else if (elsestat.getPredecessorEdges(StatEdge.TYPE_REGULAR).size() > 1 || lstSucc1.size() > 1) {
else if (elsestat.getPredecessorEdges(EdgeType.REGULAR).size() > 1 || lstSucc1.size() > 1) {
post = elsestat;
}
else {
@@ -159,7 +160,7 @@ public final class IfStatement extends Statement {
public static Statement isHead(Statement head) {
if (head.type == TYPE_BASIC_BLOCK && head.getLastBasicType() == LASTBASICTYPE_IF) {
int regsize = head.getSuccessorEdges(StatEdge.TYPE_REGULAR).size();
int regsize = head.getSuccessorEdges(EdgeType.REGULAR).size();
Statement p = null;
@@ -206,7 +207,7 @@ public final class IfStatement extends Statement {
boolean semicolon = false;
if (ifedge.explicit) {
semicolon = true;
if (ifedge.getType() == StatEdge.TYPE_BREAK) {
if (ifedge.getType() == EdgeType.BREAK) {
// break
buf.appendIndent(indent + 1).append("break");
}
@@ -234,8 +235,8 @@ public final class IfStatement extends Statement {
if (elsestat.type == Statement.TYPE_IF
&& elsestat.varDefinitions.isEmpty() && elsestat.getFirst().getExprents().isEmpty() &&
!elsestat.isLabeled() &&
(elsestat.getSuccessorEdges(STATEDGE_DIRECT_ALL).isEmpty()
|| !elsestat.getSuccessorEdges(STATEDGE_DIRECT_ALL).get(0).explicit)) { // else if
(elsestat.getSuccessorEdges(EdgeType.DIRECT_ALL).isEmpty()
|| !elsestat.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0).explicit)) { // else if
buf.appendIndent(indent).append("} else ");
TextBuffer content = ExprProcessor.jmpWrapper(elsestat, indent, false, tracer);
@@ -309,7 +310,7 @@ public final class IfStatement extends Statement {
elsestat = newstat;
}
List<StatEdge> lstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = first.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (iftype == IFTYPE_IF) {
ifedge = lstSuccs.get(0);
@@ -344,7 +345,7 @@ public final class IfStatement extends Statement {
first = stats.get(0);
List<StatEdge> lstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = first.getSuccessorEdges(EdgeType.DIRECT_ALL);
ifedge = lstSuccs.get((iftype == IFTYPE_IF || negated) ? 0 : 1);
if (stats.size() > 1) {
ifstat = stats.get(1);

View File

@@ -5,6 +5,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.util.TextBuffer;
import java.util.Arrays;
@@ -39,11 +40,11 @@ public class SequenceStatement extends Statement {
this(Arrays.asList(head, tail));
List<StatEdge> lstSuccs = tail.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = tail.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (!lstSuccs.isEmpty()) {
StatEdge edge = lstSuccs.get(0);
if (edge.getType() == StatEdge.TYPE_REGULAR && edge.getDestination() != head) {
if (edge.getType() == EdgeType.REGULAR && edge.getDestination() != head) {
post = edge.getDestination();
}
}
@@ -62,15 +63,15 @@ public class SequenceStatement extends Statement {
// at most one outgoing edge
StatEdge edge = null;
List<StatEdge> lstSuccs = head.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = head.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (!lstSuccs.isEmpty()) {
edge = lstSuccs.get(0);
}
if (edge != null && edge.getType() == StatEdge.TYPE_REGULAR) {
if (edge != null && edge.getType() == EdgeType.REGULAR) {
Statement stat = edge.getDestination();
if (stat != head && stat.getPredecessorEdges(StatEdge.TYPE_REGULAR).size() == 1
if (stat != head && stat.getPredecessorEdges(EdgeType.REGULAR).size() == 1
&& !stat.isMonitorEnter()) {
if (stat.getLastBasicType() == Statement.LASTBASICTYPE_GENERAL) {

View File

@@ -9,6 +9,7 @@ import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.StrongConnectivityHelper;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.modules.decompiler.stats.DoStatement.LoopType;
@@ -23,9 +24,6 @@ import java.util.*;
import java.util.Map.Entry;
public class Statement implements IMatchable {
public static final int STATEDGE_ALL = 0x80000000;
public static final int STATEDGE_DIRECT_ALL = 0x40000000;
public static final int DIRECTION_BACKWARD = 0;
public static final int DIRECTION_FORWARD = 1;
@@ -60,11 +58,11 @@ public class Statement implements IMatchable {
// private fields
// *****************************************************************************
private final Map<Integer, List<StatEdge>> mapSuccEdges = new HashMap<>();
private final Map<Integer, List<StatEdge>> mapPredEdges = new HashMap<>();
private final Map<EdgeType, List<StatEdge>> mapSuccEdges = new HashMap<>();
private final Map<EdgeType, List<StatEdge>> mapPredEdges = new HashMap<>();
private final Map<Integer, List<Statement>> mapSuccStates = new HashMap<>();
private final Map<Integer, List<Statement>> mapPredStates = new HashMap<>();
private final Map<EdgeType, List<Statement>> mapSuccStates = new HashMap<>();
private final Map<EdgeType, List<Statement>> mapPredStates = new HashMap<>();
// statement as graph
protected final VBStyleCollection<Statement, Integer> stats = new VBStyleCollection<>();
@@ -129,15 +127,15 @@ public class Statement implements IMatchable {
processMap(mapPredStates);
}
private static <T> void processMap(Map<Integer, List<T>> map) {
map.remove(StatEdge.TYPE_EXCEPTION);
private static <T> void processMap(Map<EdgeType, List<T>> map) {
map.remove(EdgeType.EXCEPTION);
List<T> lst = map.get(STATEDGE_DIRECT_ALL);
List<T> lst = map.get(EdgeType.DIRECT_ALL);
if (lst != null) {
map.put(STATEDGE_ALL, new ArrayList<>(lst));
map.put(EdgeType.ALL, new ArrayList<>(lst));
}
else {
map.remove(STATEDGE_ALL);
map.remove(EdgeType.ALL);
}
}
@@ -150,9 +148,9 @@ public class Statement implements IMatchable {
// post edges
if (post != null) {
for (StatEdge edge : post.getEdges(STATEDGE_DIRECT_ALL, DIRECTION_BACKWARD)) {
for (StatEdge edge : post.getEdges(EdgeType.DIRECT_ALL, DIRECTION_BACKWARD)) {
if (stat.containsStatementStrict(edge.getSource())) {
edge.getSource().changeEdgeType(DIRECTION_FORWARD, edge, StatEdge.TYPE_BREAK);
edge.getSource().changeEdgeType(DIRECTION_FORWARD, edge, EdgeType.BREAK);
stat.addLabeledEdge(edge);
}
}
@@ -161,9 +159,9 @@ public class Statement implements IMatchable {
// regular head edges
for (StatEdge prededge : head.getAllPredecessorEdges()) {
if (prededge.getType() != StatEdge.TYPE_EXCEPTION &&
if (prededge.getType() != EdgeType.EXCEPTION &&
stat.containsStatementStrict(prededge.getSource())) {
prededge.getSource().changeEdgeType(DIRECTION_FORWARD, prededge, StatEdge.TYPE_CONTINUE);
prededge.getSource().changeEdgeType(DIRECTION_FORWARD, prededge, EdgeType.CONTINUE);
stat.addLabeledEdge(prededge);
}
@@ -177,14 +175,14 @@ public class Statement implements IMatchable {
}
// exception edges
Set<Statement> setHandlers = new HashSet<>(head.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD));
Set<Statement> setHandlers = new HashSet<>(head.getNeighbours(EdgeType.EXCEPTION, DIRECTION_FORWARD));
for (Statement node : setNodes) {
setHandlers.retainAll(node.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD));
setHandlers.retainAll(node.getNeighbours(EdgeType.EXCEPTION, DIRECTION_FORWARD));
}
if (!setHandlers.isEmpty()) {
for (StatEdge edge : head.getEdges(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)) {
for (StatEdge edge : head.getEdges(EdgeType.EXCEPTION, DIRECTION_FORWARD)) {
Statement handler = edge.getDestination();
if (setHandlers.contains(handler)) {
@@ -195,7 +193,7 @@ public class Statement implements IMatchable {
}
for (Statement node : setNodes) {
for (StatEdge edge : node.getEdges(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)) {
for (StatEdge edge : node.getEdges(EdgeType.EXCEPTION, DIRECTION_FORWARD)) {
if (setHandlers.contains(edge.getDestination())) {
node.removeSuccessor(edge);
}
@@ -204,8 +202,8 @@ public class Statement implements IMatchable {
}
if (post != null &&
!stat.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD).contains(post)) { // TODO: second condition redundant?
stat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, stat, post));
!stat.getNeighbours(EdgeType.EXCEPTION, DIRECTION_FORWARD).contains(post)) { // TODO: second condition redundant?
stat.addSuccessor(new StatEdge(EdgeType.REGULAR, stat, post));
}
@@ -244,9 +242,9 @@ public class Statement implements IMatchable {
this.getLabelEdges().add(edge);
}
private void addEdgeDirectInternal(int direction, StatEdge edge, int edgetype) {
Map<Integer, List<StatEdge>> mapEdges = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
Map<Integer, List<Statement>> mapStates = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
private void addEdgeDirectInternal(int direction, StatEdge edge, EdgeType edgetype) {
Map<EdgeType, List<StatEdge>> mapEdges = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
Map<EdgeType, List<Statement>> mapStates = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
mapEdges.computeIfAbsent(edgetype, k -> new ArrayList<>()).add(edge);
@@ -254,25 +252,25 @@ public class Statement implements IMatchable {
}
private void addEdgeInternal(int direction, StatEdge edge) {
int type = edge.getType();
EdgeType type = edge.getType();
int[] arrtypes;
if (type == StatEdge.TYPE_EXCEPTION) {
arrtypes = new int[]{STATEDGE_ALL, StatEdge.TYPE_EXCEPTION};
EdgeType[] arrtypes;
if (type == EdgeType.EXCEPTION) {
arrtypes = new EdgeType[]{EdgeType.ALL, EdgeType.EXCEPTION};
}
else {
arrtypes = new int[]{STATEDGE_ALL, STATEDGE_DIRECT_ALL, type};
arrtypes = new EdgeType[]{EdgeType.ALL, EdgeType.DIRECT_ALL, type};
}
for (int edgetype : arrtypes) {
for (EdgeType edgetype : arrtypes) {
addEdgeDirectInternal(direction, edge, edgetype);
}
}
private void removeEdgeDirectInternal(int direction, StatEdge edge, int edgetype) {
private void removeEdgeDirectInternal(int direction, StatEdge edge, EdgeType edgetype) {
Map<Integer, List<StatEdge>> mapEdges = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
Map<Integer, List<Statement>> mapStates = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
Map<EdgeType, List<StatEdge>> mapEdges = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
Map<EdgeType, List<Statement>> mapStates = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
List<StatEdge> lst = mapEdges.get(edgetype);
if (lst != null) {
@@ -286,17 +284,17 @@ public class Statement implements IMatchable {
private void removeEdgeInternal(int direction, StatEdge edge) {
int type = edge.getType();
EdgeType type = edge.getType();
int[] arrtypes;
if (type == StatEdge.TYPE_EXCEPTION) {
arrtypes = new int[]{STATEDGE_ALL, StatEdge.TYPE_EXCEPTION};
EdgeType[] arrtypes;
if (type == EdgeType.EXCEPTION) {
arrtypes = new EdgeType[]{EdgeType.ALL, EdgeType.EXCEPTION};
}
else {
arrtypes = new int[]{STATEDGE_ALL, STATEDGE_DIRECT_ALL, type};
arrtypes = new EdgeType[]{EdgeType.ALL, EdgeType.DIRECT_ALL, type};
}
for (int edgetype : arrtypes) {
for (EdgeType edgetype : arrtypes) {
removeEdgeDirectInternal(direction, edge, edgetype);
}
}
@@ -365,7 +363,7 @@ public class Statement implements IMatchable {
}
}
for (StatEdge edge : getEdges(StatEdge.TYPE_CONTINUE, DIRECTION_FORWARD)) {
for (StatEdge edge : getEdges(EdgeType.CONTINUE, DIRECTION_FORWARD)) {
continueSet.add(edge.getDestination().getBasichead());
}
@@ -573,7 +571,7 @@ public class Statement implements IMatchable {
Statement succ = edge.getDestination();
if (!setVisited.contains(succ) &&
(edge.getType() == StatEdge.TYPE_REGULAR || edge.getType() == StatEdge.TYPE_EXCEPTION)) { // TODO: edge filter?
(edge.getType() == EdgeType.REGULAR || edge.getType() == EdgeType.EXCEPTION)) { // TODO: edge filter?
stackIndex.add(index + 1);
@@ -600,7 +598,7 @@ public class Statement implements IMatchable {
}
setVisited.add(stat);
for (StatEdge prededge : stat.getEdges(StatEdge.TYPE_REGULAR | StatEdge.TYPE_EXCEPTION, DIRECTION_BACKWARD)) {
for (StatEdge prededge : stat.getEdges(EdgeType.REGULAR.unite(EdgeType.EXCEPTION), DIRECTION_BACKWARD)) {
Statement pred = prededge.getSource();
if (!setVisited.contains(pred)) {
addToPostReversePostOrderList(pred, lst, setVisited);
@@ -616,20 +614,20 @@ public class Statement implements IMatchable {
public void changeEdgeNode(int direction, StatEdge edge, Statement value) {
Map<Integer, List<StatEdge>> mapEdges = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
Map<Integer, List<Statement>> mapStates = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
Map<EdgeType, List<StatEdge>> mapEdges = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
Map<EdgeType, List<Statement>> mapStates = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
int type = edge.getType();
EdgeType type = edge.getType();
int[] arrtypes;
if (type == StatEdge.TYPE_EXCEPTION) {
arrtypes = new int[]{STATEDGE_ALL, StatEdge.TYPE_EXCEPTION};
EdgeType[] arrtypes;
if (type == EdgeType.EXCEPTION) {
arrtypes = new EdgeType[]{EdgeType.ALL, EdgeType.EXCEPTION};
}
else {
arrtypes = new int[]{STATEDGE_ALL, STATEDGE_DIRECT_ALL, type};
arrtypes = new EdgeType[]{EdgeType.ALL, EdgeType.DIRECT_ALL, type};
}
for (int edgetype : arrtypes) {
for (EdgeType edgetype : arrtypes) {
List<StatEdge> lst = mapEdges.get(edgetype);
if (lst != null) {
int index = lst.indexOf(edge);
@@ -647,14 +645,14 @@ public class Statement implements IMatchable {
}
}
public void changeEdgeType(int direction, StatEdge edge, int newtype) {
public void changeEdgeType(int direction, StatEdge edge, EdgeType newtype) {
int oldtype = edge.getType();
EdgeType oldtype = edge.getType();
if (oldtype == newtype) {
return;
}
if (oldtype == StatEdge.TYPE_EXCEPTION || newtype == StatEdge.TYPE_EXCEPTION) {
if (oldtype == EdgeType.EXCEPTION || newtype == EdgeType.EXCEPTION) {
throw new RuntimeException("Invalid edge type!");
}
@@ -669,19 +667,19 @@ public class Statement implements IMatchable {
}
private List<StatEdge> getEdges(int type, int direction) {
private List<StatEdge> getEdges(EdgeType type, int direction) {
Map<Integer, List<StatEdge>> map = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
Map<EdgeType, List<StatEdge>> map = direction == DIRECTION_BACKWARD ? mapPredEdges : mapSuccEdges;
List<StatEdge> res;
if ((type & (type - 1)) == 0) {
if ((type.mask() & (type.mask() - 1)) == 0) {
res = map.get(type);
res = res == null ? new ArrayList<>() : new ArrayList<>(res);
}
else {
res = new ArrayList<>();
for (int edgetype : StatEdge.TYPES) {
if ((type & edgetype) != 0) {
for (EdgeType edgetype : EdgeType.types()) {
if ((type.mask() & edgetype.mask()) != 0) {
List<StatEdge> lst = map.get(edgetype);
if (lst != null) {
res.addAll(lst);
@@ -693,19 +691,19 @@ public class Statement implements IMatchable {
return res;
}
public List<Statement> getNeighbours(int type, int direction) {
public List<Statement> getNeighbours(EdgeType type, int direction) {
Map<Integer, List<Statement>> map = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
Map<EdgeType, List<Statement>> map = direction == DIRECTION_BACKWARD ? mapPredStates : mapSuccStates;
List<Statement> res;
if ((type & (type - 1)) == 0) {
if ((type.mask() & (type.mask() - 1)) == 0) {
res = map.get(type);
res = res == null ? new ArrayList<>() : new ArrayList<>(res);
}
else {
res = new ArrayList<>();
for (int edgetype : StatEdge.TYPES) {
if ((type & edgetype) != 0) {
for (EdgeType edgetype : EdgeType.types()) {
if ((type.mask() & edgetype.mask()) != 0) {
List<Statement> lst = map.get(edgetype);
if (lst != null) {
res.addAll(lst);
@@ -717,24 +715,24 @@ public class Statement implements IMatchable {
return res;
}
public Set<Statement> getNeighboursSet(int type, int direction) {
public Set<Statement> getNeighboursSet(EdgeType type, int direction) {
return new HashSet<>(getNeighbours(type, direction));
}
public List<StatEdge> getSuccessorEdges(int type) {
public List<StatEdge> getSuccessorEdges(EdgeType type) {
return getEdges(type, DIRECTION_FORWARD);
}
public List<StatEdge> getPredecessorEdges(int type) {
public List<StatEdge> getPredecessorEdges(EdgeType type) {
return getEdges(type, DIRECTION_BACKWARD);
}
public List<StatEdge> getAllSuccessorEdges() {
return getEdges(STATEDGE_ALL, DIRECTION_FORWARD);
return getEdges(EdgeType.ALL, DIRECTION_FORWARD);
}
public List<StatEdge> getAllPredecessorEdges() {
return getEdges(STATEDGE_ALL, DIRECTION_BACKWARD);
return getEdges(EdgeType.ALL, DIRECTION_BACKWARD);
}
public Statement getFirst() {

View File

@@ -11,6 +11,7 @@ import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.SwitchHelper;
import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
@@ -37,13 +38,13 @@ public final class SwitchStatement extends Statement {
first = head;
stats.addWithKey(head, head.id);
// find post node
Set<Statement> regularSuccessors = new HashSet<>(head.getNeighbours(StatEdge.TYPE_REGULAR, DIRECTION_FORWARD));
Set<Statement> regularSuccessors = new HashSet<>(head.getNeighbours(EdgeType.REGULAR, DIRECTION_FORWARD));
// cluster nodes
if (postStatement != null) {
post = postStatement;
regularSuccessors.remove(post);
}
defaultEdge = head.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0);
defaultEdge = head.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0);
for (Statement successor : regularSuccessors) {
stats.addWithKey(successor, successor.id);
}
@@ -155,13 +156,13 @@ public final class SwitchStatement extends Statement {
@Override
public void initSimpleCopy() {
first = stats.get(0);
defaultEdge = first.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0);
defaultEdge = first.getSuccessorEdges(EdgeType.DIRECT_ALL).get(0);
sortEdgesAndNodes();
}
public void sortEdgesAndNodes() {
Map<StatEdge, Integer> edgeIndicesMapping = new HashMap<>();
List<StatEdge> firstSuccessors = first.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> firstSuccessors = first.getSuccessorEdges(EdgeType.DIRECT_ALL);
for (int i = 0; i < firstSuccessors.size(); i++) {
edgeIndicesMapping.put(firstSuccessors.get(i), i == 0 ? firstSuccessors.size() : i);
}
@@ -192,7 +193,7 @@ public final class SwitchStatement extends Statement {
for (List<Integer> indices : edgeIndices) {
List<StatEdge> edges = new ArrayList<>(indices.size());
List<Exprent> valueExprents = new ArrayList<>(indices.size());
List<StatEdge> firstSuccessors = first.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> firstSuccessors = first.getSuccessorEdges(EdgeType.DIRECT_ALL);
for (Integer in : indices) {
int index = in == firstSuccessors.size() ? 0 : in;
edges.add(firstSuccessors.get(index));
@@ -209,7 +210,7 @@ public final class SwitchStatement extends Statement {
for (int i = 1; i < stats.size(); i++) {
Statement statement = stats.get(i);
List<Integer> regularEdgeIndices = new ArrayList<>();
for (StatEdge regularEdge : statement.getPredecessorEdges(StatEdge.TYPE_REGULAR)) {
for (StatEdge regularEdge : statement.getPredecessorEdges(EdgeType.REGULAR)) {
if (regularEdge.getSource() == first) {
regularEdgeIndices.add(edgeIndicesMapping.get(regularEdge));
}
@@ -223,7 +224,7 @@ public final class SwitchStatement extends Statement {
private void collectExitEdgesIndices(@NotNull Map<StatEdge, Integer> edgeIndicesMapping,
@NotNull List<@Nullable Statement> nodes,
@NotNull List<List<Integer>> edgeIndices) {
List<StatEdge> firstExitEdges = first.getSuccessorEdges(StatEdge.TYPE_BREAK | StatEdge.TYPE_CONTINUE);
List<StatEdge> firstExitEdges = first.getSuccessorEdges(EdgeType.BREAK.unite(EdgeType.CONTINUE));
while (!firstExitEdges.isEmpty()) {
StatEdge exitEdge = firstExitEdges.get(0);
List<Integer> exitEdgeIndices = new ArrayList<>();
@@ -252,7 +253,7 @@ public final class SwitchStatement extends Statement {
for (int index = 0; index < nodes.size(); index++) {
Statement node = nodes.get(index);
if (node == null) continue;
HashSet<Statement> nodePredecessors = new HashSet<>(node.getNeighbours(StatEdge.TYPE_REGULAR, DIRECTION_BACKWARD));
HashSet<Statement> nodePredecessors = new HashSet<>(node.getNeighbours(EdgeType.REGULAR, DIRECTION_BACKWARD));
nodePredecessors.remove(first);
if (nodePredecessors.isEmpty()) continue;
// assumption: at most one predecessor node besides the head. May not hold true for obfuscated code.
@@ -284,7 +285,7 @@ public final class SwitchStatement extends Statement {
StatEdge sampleEdge = edges.get(i).get(0);
basicBlock.addSuccessor(new StatEdge(sampleEdge.getType(), basicBlock, sampleEdge.getDestination(), sampleEdge.closure));
for (StatEdge edge : edges.get(i)) {
edge.getSource().changeEdgeType(DIRECTION_FORWARD, edge, StatEdge.TYPE_REGULAR);
edge.getSource().changeEdgeType(DIRECTION_FORWARD, edge, EdgeType.REGULAR);
edge.closure.getLabelEdges().remove(edge);
edge.getDestination().removePredecessor(edge);
edge.getSource().changeEdgeNode(DIRECTION_FORWARD, edge, basicBlock);

View File

@@ -7,6 +7,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.SequenceHelper;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge.EdgeType;
import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
import org.jetbrains.java.decompiler.util.TextBuffer;
@@ -42,10 +43,10 @@ public class SynchronizedStatement extends Statement {
stats.addWithKey(exc, exc.id);
List<StatEdge> lstSuccs = body.getSuccessorEdges(STATEDGE_DIRECT_ALL);
List<StatEdge> lstSuccs = body.getSuccessorEdges(EdgeType.DIRECT_ALL);
if (!lstSuccs.isEmpty()) {
StatEdge edge = lstSuccs.get(0);
if (edge.getType() == StatEdge.TYPE_REGULAR) {
if (edge.getType() == EdgeType.REGULAR) {
post = edge.getDestination();
}
}