org.jetbrains.kotlin.utils.DFS Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* Copyright 2010-2015 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.kotlin.utils;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class DFS {
public static R dfs(@NotNull Collection nodes, @NotNull Neighbors neighbors, @NotNull Visited visited, @NotNull NodeHandler handler) {
for (N node : nodes) {
doDfs(node, neighbors, visited, handler);
}
return handler.result();
}
public static R dfs(
@NotNull Collection nodes,
@NotNull Neighbors neighbors,
@NotNull NodeHandler handler
) {
return dfs(nodes, neighbors, new VisitedWithSet(), handler);
}
public static Boolean ifAny(
@NotNull Collection nodes,
@NotNull Neighbors neighbors,
@NotNull final Function1 predicate
) {
final boolean[] result = new boolean[1];
return dfs(nodes, neighbors, new AbstractNodeHandler() {
@Override
public boolean beforeChildren(N current) {
if (predicate.invoke(current)) {
result[0] = true;
}
return !result[0];
}
@Override
public Boolean result() {
return result[0];
}
});
}
public static R dfsFromNode(@NotNull N node, @NotNull Neighbors neighbors, @NotNull Visited visited, @NotNull NodeHandler handler) {
doDfs(node, neighbors, visited, handler);
return handler.result();
}
public static void dfsFromNode(
@NotNull N node,
@NotNull Neighbors neighbors,
@NotNull Visited visited
) {
dfsFromNode(node, neighbors, visited, new AbstractNodeHandler() {
@Override
public Void result() {
return null;
}
});
}
public static List topologicalOrder(@NotNull Iterable nodes, @NotNull Neighbors neighbors, @NotNull Visited visited) {
TopologicalOrder handler = new TopologicalOrder();
for (N node : nodes) {
doDfs(node, neighbors, visited, handler);
}
return handler.result();
}
public static List topologicalOrder(@NotNull Iterable nodes, @NotNull Neighbors neighbors) {
return topologicalOrder(nodes, neighbors, new VisitedWithSet());
}
private static void doDfs(@NotNull N current, @NotNull Neighbors neighbors, @NotNull Visited visited, @NotNull NodeHandler handler) {
if (!visited.checkAndMarkVisited(current)) return;
if (!handler.beforeChildren(current)) return;
for (N neighbor : neighbors.getNeighbors(current)) {
doDfs(neighbor, neighbors, visited, handler);
}
handler.afterChildren(current);
}
public interface NodeHandler {
boolean beforeChildren(N current);
void afterChildren(N current);
R result();
}
public interface Neighbors {
@NotNull
Iterable getNeighbors(N current);
}
public interface Visited {
boolean checkAndMarkVisited(N current);
}
public static abstract class AbstractNodeHandler implements NodeHandler {
@Override
public boolean beforeChildren(N current) {
return true;
}
@Override
public void afterChildren(N current) {
}
}
public static class VisitedWithSet implements Visited {
private final Set visited;
public VisitedWithSet() {
this(new HashSet());
}
public VisitedWithSet(@NotNull Set visited) {
this.visited = visited;
}
@Override
public boolean checkAndMarkVisited(N current) {
return visited.add(current);
}
}
public static abstract class CollectingNodeHandler> extends AbstractNodeHandler {
@NotNull
protected final C result;
protected CollectingNodeHandler(@NotNull C result) {
this.result = result;
}
@Override
@NotNull
public C result() {
return result;
}
}
public static abstract class NodeHandlerWithListResult extends CollectingNodeHandler> {
protected NodeHandlerWithListResult() {
super(new LinkedList());
}
}
public static class TopologicalOrder extends NodeHandlerWithListResult {
@Override
public void afterChildren(N current) {
result.addFirst(current);
}
}
}