diff options
Diffstat (limited to 'plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java')
-rw-r--r-- | plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java new file mode 100644 index 000000000000..b24b72c261ea --- /dev/null +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java @@ -0,0 +1,136 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.modules.decompiler.sforms; + +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; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + + +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 static 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 + int processExprent(Exprent exprent); + } +} |