in java/io/bazel/rules/closure/Tarjan.java [122:164]
private Vertex<V> connectStrongly(V vertex) {
// Set the depth index for v to the smallest unused index.
Vertex<V> v = new Vertex<>(vertex, index++);
vertices.put(vertex, v);
stack.add(v);
v.onStack = true;
// Consider successors of v.
for (V vertex2 : edges.get(v.vertex)) {
Vertex<V> w = vertices.get(vertex2);
if (w == null) {
// Successor w has not yet been visited; recurse on it.
w = connectStrongly(vertex2);
v.lowlink = Math.min(v.lowlink, w.lowlink);
} else if (w.onStack) {
// Successor w is in stack and hence in the current SCC.
v.lowlink = Math.min(v.lowlink, w.index);
}
if (w.equals(v)) {
w.selfReferential = true;
}
}
// If v is a root node, pop the stack and generate an SCC.
if (v.lowlink == v.index) {
if (!v.selfReferential && v.equals(stack.get(stack.size() - 1))) {
sorted.add(stack.remove(stack.size() - 1).vertex);
v.onStack = false;
} else {
ImmutableSet.Builder<V> scc = new ImmutableSet.Builder<>();
Vertex<V> w;
do {
w = stack.remove(stack.size() - 1);
w.onStack = false;
sorted.add(w.vertex);
scc.add(w.vertex);
} while (!w.equals(v));
result.add(scc.build());
}
}
return v;
}