Commit e6903b5b authored by Alexey Kudravtsev's avatar Alexey Kudravtsev
Browse files

better iterateContent: do not even look inside the intermediate directories...

better iterateContent: do not even look inside the intermediate directories between excluded dir and children content dirs
parent c60148df
Showing with 52 additions and 29 deletions
+52 -29
......@@ -99,7 +99,6 @@ public class FileListeningTest extends IntegrationTestCase {
" excluded\n" +
" content\n" +
" f.txt\n" +
" subsubdir2\n" +
" f.class\n" +
" f.txt\n"
, buildDBFileStructure(myRoot, 0, new StringBuilder()).toString()
......
......@@ -9,7 +9,9 @@ import com.intellij.testFramework.PsiTestUtil;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DirectoryIndexBeneathTest extends DirectoryIndexTestCase {
public void testDirectoryInfoMustKnowAboutContentDirectoriesBeneathExcluded() throws IOException {
......@@ -17,6 +19,7 @@ public class DirectoryIndexBeneathTest extends DirectoryIndexTestCase {
assertNotNull(root);
/*
/root
/rootSub
/myModule (module content root)
/src (source root)
/src1 (source root)
......@@ -24,10 +27,13 @@ public class DirectoryIndexBeneathTest extends DirectoryIndexTestCase {
/e.txt
/excluded (excluded)
/myModule2 (module2 content root)
/src (module2 source root)
/my.txt
/src2 (module2 source root)
/my2.txt
/subExcluded
*/
assertFalse(myFileIndex.isInContent(root));
VirtualFile rootSub = createChildDirectory(root, "rootSub");
assertFalse(myFileIndex.isInContent(rootSub));
VirtualFile module = createChildDirectory(root, "myModule");
VirtualFile src = createChildDirectory(module, "src");
VirtualFile src1 = createChildDirectory(module, "src1");
......@@ -36,8 +42,8 @@ public class DirectoryIndexBeneathTest extends DirectoryIndexTestCase {
VirtualFile excluded = createChildDirectory(module, "excluded");
VirtualFile subExcluded = createChildDirectory(excluded, "subExcluded");
VirtualFile module2 = createChildDirectory(excluded, "myModule2");
VirtualFile src2 = createChildDirectory(module2, "src");
VirtualFile myTxt = createChildData(src2, "my.txt");
VirtualFile src2 = createChildDirectory(module2, "src2");
VirtualFile my2Txt = createChildData(src2, "my2.txt");
Module myModule = newModuleWithContent("myModule", module);
PsiTestUtil.addSourceRoot(myModule, src);
......@@ -48,22 +54,26 @@ public class DirectoryIndexBeneathTest extends DirectoryIndexTestCase {
Module myModule2 = newModuleWithContent("myModule2", module2);
PsiTestUtil.addSourceRoot(myModule2, src2);
check(excluded1, false, false);
check(eTxt, false, false);
check(excluded, false, true);
check(module2, true, false);
check(subExcluded, false, false);
checkIterate(root, module, src, src1, module2, src2, my2Txt);
checkIterate(src, src);
checkIterate(src1, src1);
checkIterate(excluded1);
checkIterate(module, module, src, src1, module2, src2, my2Txt);
checkIterate(eTxt);
checkIterate(excluded, module2, src2, my2Txt);
checkIterate(module2, module2, src2, my2Txt);
checkIterate(subExcluded);
assertIteratedContent(myFileIndex,
root,
Arrays.asList(module, src, src1, module2, src2, myTxt),
Arrays.asList(module, src, src1, module2, src2, my2Txt),
Arrays.asList(root, excluded1, eTxt, excluded, subExcluded));
}
private void check(@NotNull VirtualFile file, boolean expectInProject, boolean expectContentBeneathExcluded) {
DirectoryInfo info = DirectoryIndex.getInstance(getProject()).getInfoForFile(file);
assertEquals(expectInProject, info.isInProject(file));
assertEquals(expectContentBeneathExcluded, info.hasContentBeneathExcluded(file));
private void checkIterate(@NotNull VirtualFile file, @NotNull VirtualFile... expectToIterate) {
final List<VirtualFile> collected = new ArrayList<>();
myFileIndex.iterateContentUnderDirectory(file, fileOrDir -> collected.add(fileOrDir));
assertSameElements(collected, expectToIterate);
}
@NotNull
......
......@@ -5,6 +5,7 @@ package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
......@@ -67,7 +68,8 @@ public abstract class DirectoryInfo {
public abstract String getUnloadedModuleName();
/**
* @return true if {@code dir} is excluded and there are content entries under(including) the {@code dir}
* if {@code dir} is excluded and there are content entries under the {@code dir}, process them all and
* @return processing result
*/
public abstract boolean hasContentBeneathExcluded(@NotNull VirtualFile dir);
public abstract boolean processContentBeneathExcluded(@NotNull VirtualFile dir, @NotNull Processor<? super VirtualFile> processor);
}
......@@ -5,6 +5,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
......@@ -144,7 +145,9 @@ class DirectoryInfoImpl extends DirectoryInfo {
}
@Override
public boolean hasContentBeneathExcluded(@NotNull VirtualFile dir) {
return isExcluded(dir) && ContainerUtil.exists(myContentInfosBeneath, child -> VfsUtilCore.isAncestor(dir, child.myRoot, false));
public boolean processContentBeneathExcluded(@NotNull VirtualFile dir,
@NotNull Processor<? super VirtualFile> processor) {
return isExcluded(dir) &&
ContainerUtil.process(myContentInfosBeneath, child -> !VfsUtilCore.isAncestor(dir, child.myRoot, false) || processor.process(child.myRoot));
}
}
......@@ -65,7 +65,12 @@ public abstract class FileIndexBase implements FileIndex {
public Result visitFileEx(@NotNull VirtualFile file) {
if (file.isDirectory()) {
DirectoryInfo info = getInfoForFileOrDirectory(file);
if (info.isExcluded(file) && !info.hasContentBeneathExcluded(file)) return SKIP_CHILDREN;
if (info.isExcluded(file)) {
if (!info.processContentBeneathExcluded(file, content -> iterateContentUnderDirectory(content, processor, customFilter))) {
return skipTo(dir);
}
return SKIP_CHILDREN;
}
}
return !filter.accept(file) || processor.processFile(file) ? CONTINUE : skipTo(dir);
}
......
......@@ -5,6 +5,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
......@@ -115,8 +116,9 @@ class NonProjectDirectoryInfo extends DirectoryInfo {
}
@Override
public boolean hasContentBeneathExcluded(@NotNull VirtualFile dir) {
return false;
public boolean processContentBeneathExcluded(@NotNull VirtualFile dir,
@NotNull Processor<? super VirtualFile> processor) {
return true;
}
static class WithBeneathInfo extends NonProjectDirectoryInfo {
......@@ -131,8 +133,10 @@ class NonProjectDirectoryInfo extends DirectoryInfo {
}
@Override
public boolean hasContentBeneathExcluded(@NotNull VirtualFile dir) {
return ContainerUtil.exists(myContentInfosBeneath, child -> VfsUtilCore.isAncestor(dir, child.myRoot, false));
public boolean processContentBeneathExcluded(@NotNull VirtualFile dir,
@NotNull Processor<? super VirtualFile> processor) {
return isExcluded(dir) &&
ContainerUtil.process(myContentInfosBeneath, child -> !VfsUtilCore.isAncestor(dir, child.myRoot, false) || processor.process(child.myRoot));
}
@Override
......
......@@ -94,12 +94,12 @@ class RootIndex {
assert dirInfo != null;
boolean hasContent = !isExcluded(dirInfo) && dirInfo.getContentRoot() != null;
if (hasContent) {
// start with the strict parent and update all parent excluded dir infos
for (int k = 1; k < hierarchy.size(); k++) {
VirtualFile file = hierarchy.get(k);
DirectoryInfo parentInfo = myRootInfos.get(file);
// start with the strict parent and update parent excluded dir info
VirtualFile parentRoot = hierarchy.size() >= 2 ? hierarchy.get(1) : null;
if (parentRoot != null) {
DirectoryInfo parentInfo = myRootInfos.get(parentRoot);
if (isExcluded(parentInfo)) {
addContentBeneathExcludedInfo(parentInfo, file, dirInfo);
addContentBeneathExcludedInfo(parentInfo, parentRoot, dirInfo);
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment