diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java index 578d071ffed..f5e744d2da5 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java @@ -540,6 +540,38 @@ public class OverridingUtil { ); } + public static boolean traverseOverridenDescriptors( + @NotNull CallableDescriptor originalDescriptor, + @NotNull final Function1 handler + ) { + return DFS.dfs( + Collections.singletonList(originalDescriptor), + new DFS.Neighbors() { + @NotNull + @Override + public Iterable getNeighbors(CallableDescriptor current) { + return current.getOverriddenDescriptors(); + } + }, + new DFS.AbstractNodeHandler() { + 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); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java b/core/descriptors/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java index 1d456a61807..3615141469b 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/DescriptorSubstitutor.java @@ -147,13 +147,15 @@ public class DescriptorSubstitutor { }, new DFS.NodeHandlerWithListResult() { @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; } } ); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java index 47a5f1fcbe8..3b81f28f08b 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -634,7 +634,7 @@ public class TypeUtils { }, new DFS.NodeHandlerWithListResult() { @Override - public void beforeChildren(JetType current) { + public boolean beforeChildren(JetType current) { TypeConstructor constructor = current.getConstructor(); Set instances = constructorToAllInstances.get(constructor); @@ -643,6 +643,8 @@ public class TypeUtils { constructorToAllInstances.put(constructor, instances); } instances.add(current); + + return true; } @Override diff --git a/core/util.runtime/src/org/jetbrains/jet/utils/DFS.java b/core/util.runtime/src/org/jetbrains/jet/utils/DFS.java index ca9103af9ff..17e738c75a0 100644 --- a/core/util.runtime/src/org/jetbrains/jet/utils/DFS.java +++ b/core/util.runtime/src/org/jetbrains/jet/utils/DFS.java @@ -68,10 +68,9 @@ public class DFS { } private static void doDfs(@NotNull N current, @NotNull Neighbors neighbors, @NotNull Visited visited, @NotNull NodeHandler 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 { - @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 implements NodeHandler { @Override - public void beforeChildren(N current) { + public boolean beforeChildren(N current) { + return true; } @Override