blob: b24b72c261ea576254188837fbfb6a1ff0917067 [file] [log] [blame]
/*
* 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);
}
}