diff options
Diffstat (limited to 'src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java')
-rw-r--r-- | src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java new file mode 100644 index 0000000..b35f801 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java @@ -0,0 +1,136 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.modules.decompiler.sforms; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.sforms.FlattenStatementsHelper.FinallyPathWrapper; +import org.jetbrains.java.decompiler.util.VBStyleCollection; + + +public class DirectGraph { + + public VBStyleCollection<DirectNode, String> nodes = new VBStyleCollection<DirectNode, String>(); + + public DirectNode first; + + // exit, [source, destination] + public HashMap<String, List<FinallyPathWrapper>> mapShortRangeFinallyPaths = new HashMap<String, List<FinallyPathWrapper>>(); + + // exit, [source, destination] + public HashMap<String, List<FinallyPathWrapper>> mapLongRangeFinallyPaths = new HashMap<String, List<FinallyPathWrapper>>(); + + // negative if branches (recorded for handling of && and ||) + public HashMap<String, String> mapNegIfBranch = new HashMap<String, String>(); + + // nodes, that are exception exits of a finally block with monitor variable + public HashMap<String, String> mapFinallyMonitorExceptionPathExits = new HashMap<String, String>(); + + public void sortReversePostOrder() { + LinkedList<DirectNode> res = new LinkedList<DirectNode>(); + addToReversePostOrderListIterative(first, res); + + nodes.clear(); + for(DirectNode node: res) { + nodes.addWithKey(node, node.id); + } + } + + private void addToReversePostOrderListIterative(DirectNode root, List<DirectNode> lst) { + + LinkedList<DirectNode> stackNode = new LinkedList<DirectNode>(); + LinkedList<Integer> stackIndex = new LinkedList<Integer>(); + + HashSet<DirectNode> setVisited = new HashSet<DirectNode>(); + + stackNode.add(root); + stackIndex.add(0); + + while(!stackNode.isEmpty()) { + + DirectNode node = stackNode.getLast(); + int index = stackIndex.removeLast(); + + setVisited.add(node); + + for(;index<node.succs.size();index++) { + DirectNode succ = node.succs.get(index); + + if(!setVisited.contains(succ)) { + stackIndex.add(index+1); + + stackNode.add(succ); + stackIndex.add(0); + + break; + } + } + + if(index == node.succs.size()) { + lst.add(0, node); + + stackNode.removeLast(); + } + } + + } + + + public boolean iterateExprents(ExprentIterator iter) { + + LinkedList<DirectNode> stack = new LinkedList<DirectNode>(); + stack.add(first); + + HashSet<DirectNode> setVisited = new HashSet<DirectNode>(); + + while(!stack.isEmpty()) { + + DirectNode node = stack.removeFirst(); + + if(setVisited.contains(node)) { + continue; + } + setVisited.add(node); + + for(int i=0;i<node.exprents.size();i++) { + int res = iter.processExprent(node.exprents.get(i)); + + if(res == 1) { + return false; + } + + if(res == 2) { + node.exprents.remove(i); + i--; + } + } + + stack.addAll(node.succs); + } + + return true; + } + + public interface ExprentIterator { + // 0 - success, do nothing + // 1 - cancel iteration + // 2 - success, delete exprent + public int processExprent(Exprent exprent); + } +} |