DFS: Terminate traversal if node handler returns false

This commit is contained in:
Alexey Sedunov
2014-06-23 19:26:41 +04:00
parent e5ce5b7127
commit 96557e6d3f
4 changed files with 45 additions and 9 deletions
@@ -540,6 +540,38 @@ public class OverridingUtil {
);
}
public static boolean traverseOverridenDescriptors(
@NotNull CallableDescriptor originalDescriptor,
@NotNull final Function1<CallableDescriptor, Boolean> handler
) {
return DFS.dfs(
Collections.singletonList(originalDescriptor),
new DFS.Neighbors<CallableDescriptor>() {
@NotNull
@Override
public Iterable<? extends CallableDescriptor> getNeighbors(CallableDescriptor current) {
return current.getOverriddenDescriptors();
}
},
new DFS.AbstractNodeHandler<CallableDescriptor, Boolean>() {
private boolean result = true;
@Override
public boolean beforeChildren(CallableDescriptor current) {
if (!handler.invoke(current)) {
result = false;
}
return result;
}
@Override
public Boolean result() {
return result;
}
}
);
}
public interface DescriptorSink {
void addToScope(@NotNull CallableMemberDescriptor fakeOverride);
@@ -147,13 +147,15 @@ public class DescriptorSubstitutor {
},
new DFS.NodeHandlerWithListResult<JetType, TypeParameterDescriptor>() {
@Override
public void beforeChildren(JetType current) {
public boolean beforeChildren(JetType current) {
ClassifierDescriptor declarationDescriptor = current.getConstructor().getDeclarationDescriptor();
// typeParameters in a list, but it contains very few elements, so it's fine to call contains() on it
//noinspection SuspiciousMethodCalls
if (typeParameters.contains(declarationDescriptor)) {
result.add((TypeParameterDescriptor) declarationDescriptor);
}
return true;
}
}
);
@@ -634,7 +634,7 @@ public class TypeUtils {
},
new DFS.NodeHandlerWithListResult<JetType, TypeConstructor>() {
@Override
public void beforeChildren(JetType current) {
public boolean beforeChildren(JetType current) {
TypeConstructor constructor = current.getConstructor();
Set<JetType> instances = constructorToAllInstances.get(constructor);
@@ -643,6 +643,8 @@ public class TypeUtils {
constructorToAllInstances.put(constructor, instances);
}
instances.add(current);
return true;
}
@Override
@@ -68,10 +68,9 @@ public class DFS {
}
private static <N> void doDfs(@NotNull N current, @NotNull Neighbors<N> neighbors, @NotNull Visited<N> visited, @NotNull NodeHandler<N, ?> handler) {
if (!visited.checkAndMarkVisited(current)) {
return;
}
handler.beforeChildren(current);
if (!visited.checkAndMarkVisited(current)) return;
if (!handler.beforeChildren(current)) return;
for (N neighbor : neighbors.getNeighbors(current)) {
doDfs(neighbor, neighbors, visited, handler);
}
@@ -79,8 +78,8 @@ public class DFS {
}
public interface NodeHandler<N, R> {
@KotlinSignature("fun beforeChildren(current: N): Unit")
void beforeChildren(N current);
@KotlinSignature("fun beforeChildren(current: N): Boolean")
boolean beforeChildren(N current);
@KotlinSignature("fun afterChildren(current: N): Unit")
void afterChildren(N current);
@@ -100,7 +99,8 @@ public class DFS {
public static abstract class AbstractNodeHandler<N, R> implements NodeHandler<N, R> {
@Override
public void beforeChildren(N current) {
public boolean beforeChildren(N current) {
return true;
}
@Override