DFS: Terminate traversal if node handler returns false
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user