diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java index a35b87bad093..91a157318b1b 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java @@ -32,6 +32,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +import static com.intellij.openapi.vfs.VirtualFileVisitor.Result; +import static com.intellij.openapi.vfs.VirtualFileVisitor.VisitorException; + public class VfsUtilCore { /** * Checks whether the ancestor {@link com.intellij.openapi.vfs.VirtualFile} is parent of file @@ -175,7 +178,7 @@ public class VfsUtilCore { public static boolean iterateChildrenRecursively(@NotNull final VirtualFile root, @Nullable final VirtualFileFilter filter, @NotNull final ContentIterator iterator) { - final VirtualFileVisitor.Result result = visitChildrenRecursively(root, new VirtualFileVisitor() { + final Result result = visitChildrenRecursively(root, new VirtualFileVisitor() { @NotNull @Override public Result visitFileEx(@NotNull VirtualFile file) { @@ -188,12 +191,12 @@ public class VfsUtilCore { } @SuppressWarnings("UnsafeVfsRecursion") - public static VirtualFileVisitor.Result visitChildrenRecursively(@NotNull VirtualFile file, @NotNull VirtualFileVisitor visitor) { + public static Result visitChildrenRecursively(@NotNull VirtualFile file, @NotNull VirtualFileVisitor visitor) throws VisitorException { visitor.pushFrame(); try { final boolean visited = visitor.allowVisitFile(file); if (visited) { - VirtualFileVisitor.Result result = visitor.visitFileEx(file); + Result result = visitor.visitFileEx(file); if (result.skipChildren) return result; } @@ -215,7 +218,7 @@ public class VfsUtilCore { if (childrenIterable != null) { for (VirtualFile child : childrenIterable) { - VirtualFileVisitor.Result result = visitChildrenRecursively(child, visitor); + Result result = visitChildrenRecursively(child, visitor); if (result.skipToParent != null && result.skipToParent != child) return result; } } @@ -231,6 +234,23 @@ public class VfsUtilCore { } } + public static Result visitChildrenRecursively(@NotNull VirtualFile file, + @NotNull VirtualFileVisitor visitor, + @NotNull Class... classes) throws E { + try { + return visitChildrenRecursively(file, visitor); + } + catch (VisitorException e) { + final Throwable cause = e.getCause(); + for (Class eClass : classes) { + if (eClass.isInstance(cause)) { + throw eClass.cast(cause); + } + } + throw e; + } + } + public static boolean isInvalidLink(@NotNull VirtualFile link) { final VirtualFile target = link.getCanonicalFile(); return target == null || target == link || isAncestor(target, link, true); diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileVisitor.java b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileVisitor.java index b41afb1b6cac..0ea7dc528eea 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileVisitor.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileVisitor.java @@ -73,6 +73,13 @@ public abstract class VirtualFileVisitor { } + protected static class VisitorException extends RuntimeException { + public VisitorException(Throwable cause) { + super(cause); + } + } + + private boolean myFollowSymLinks = true; private boolean mySkipRoot = false; private int myDepthLimit = -1; @@ -150,7 +157,7 @@ public abstract class VirtualFileVisitor { frame.put(parameter, value); } - @Nullable + @SuppressWarnings("ConstantConditions") public final T get(@NotNull Key parameter) { if (myParameters == null || myParameters.isEmpty()) { return null;