soot.jimple.toolkits.typing.StronglyConnectedComponents Maven / Gradle / Ivy
package soot.jimple.toolkits.typing;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 2000 Etienne Gagnon. All rights reserved.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class StronglyConnectedComponents {
private static final Logger logger = LoggerFactory.getLogger(StronglyConnectedComponents.class);
List variables;
Set black;
List finished;
List> forest = new LinkedList>();
List current_tree;
private static final boolean DEBUG = false;
public static void merge(List typeVariableList) throws TypeException {
new StronglyConnectedComponents(typeVariableList);
}
private StronglyConnectedComponents(List typeVariableList) throws TypeException {
variables = typeVariableList;
black = new TreeSet();
finished = new LinkedList();
for (TypeVariable var : variables) {
if (!black.add(var)) {
dfsg_visit(var);
}
}
black = new TreeSet();
for (TypeVariable var : finished) {
if (!black.add(var)) {
current_tree = new LinkedList();
forest.add(current_tree);
dfsgt_visit(var);
}
}
for (Iterator> i = forest.iterator(); i.hasNext();) {
List list = i.next();
TypeVariable previous = null;
StringBuffer s = null;
if (DEBUG) {
s = new StringBuffer("scc:\n");
}
for (Iterator j = list.iterator(); j.hasNext();) {
TypeVariable current = j.next();
if (DEBUG) {
s.append(" " + current + "\n");
}
if (previous == null) {
previous = current;
} else {
try {
previous = previous.union(current);
} catch (TypeException e) {
if (DEBUG) {
logger.debug("" + s);
}
throw e;
}
}
}
}
}
private void dfsg_visit(TypeVariable var) {
List parents = var.parents();
for (TypeVariable parent : parents) {
if (!black.add(parent)) {
dfsg_visit(parent);
}
}
finished.add(0, var);
}
private void dfsgt_visit(TypeVariable var) {
current_tree.add(var);
List children = var.children();
for (TypeVariable child : children) {
if (!black.add(child)) {
dfsgt_visit(child);
}
}
}
}