DirectoryIndex: store info for excluded and ignored directories

This commit is contained in:
nik
2014-07-18 11:27:46 +04:00
parent df68af8efe
commit fb4de8d85f
13 changed files with 314 additions and 216 deletions
@@ -178,7 +178,7 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper
}
List<OrderEntry> orderEntries = index.getOrderEntriesForFile(virtualFile);
if (orderEntries.isEmpty()) {
LOG.error("Inconsistent: " + DirectoryIndex.getInstance(myProject).getInfoForDirectory(folder).toString());
LOG.error("Inconsistent: " + DirectoryIndex.getInstance(myProject).getInfoForFile(folder).toString());
}
final VirtualFile[] files = orderEntries.get(0).getFiles(OrderRootType.CLASSES);
for (VirtualFile rootFile : files) {
@@ -188,7 +188,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
public void testDirInfos() throws IOException {
checkInfoNull(myRootVFile);
checkNotInProject(myRootVFile);
// beware: files in directory index
checkInfo(myFileLibSrc, null, false, true, "", null, myModule);
@@ -206,21 +206,21 @@ public class DirectoryIndexTest extends IdeaTestCase {
checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3);
checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3);
assertEquals(myLibSrcDir, checkInfoNotNull(myLibSrcDir).getSourceRoot());
assertEquals(myLibSrcDir, checkInProject(myLibSrcDir).getSourceRoot());
checkInfo(myModule2Dir, myModule2, false, false, null, null);
checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
checkInfoNull(myCvsDir);
checkInfoNull(myExcludeDir);
checkInfoNull(myExcludedLibClsDir);
checkInfoNull(myExcludedLibSrcDir);
checkNotInProject(myCvsDir);
checkExcluded(myExcludeDir, myModule2);
checkExcluded(myExcludedLibClsDir, myModule);
checkExcluded(myExcludedLibSrcDir, myModule);
assertEquals(myModule1Dir, checkInfoNotNull(myLibClsDir).getContentRoot());
assertEquals(myModule1Dir, checkInProject(myLibClsDir).getContentRoot());
checkInfo(myModule3Dir, myModule3, false, false, null, null);
VirtualFile cvs = myPack1Dir.createChildDirectory(this, "CVS");
checkInfoNull(cvs);
checkNotInProject(cvs);
assertNull(ProjectRootManager.getInstance(myProject).getFileIndex().getPackageNameByDirectory(cvs));
}
@@ -332,7 +332,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile newDir = myModule1Dir.createChildDirectory(this, "newDir");
myIndex.checkConsistency();
checkInfoNotNull(newDir);
checkInProject(newDir);
final FileTypeManagerEx fileTypeManager = (FileTypeManagerEx)FileTypeManager.getInstance();
final String list = fileTypeManager.getIgnoredFilesList();
@@ -345,7 +345,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
});
myIndex.checkConsistency();
checkInfoNull(newDir);
checkNotInProject(newDir);
}
finally {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@@ -354,7 +354,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
fileTypeManager.setIgnoredFilesList(list);
}
});
checkInfoNotNull(newDir);
checkInProject(newDir);
}
}
@@ -379,16 +379,18 @@ public class DirectoryIndexTest extends IdeaTestCase {
public void testModuleUnderIgnoredDir() throws IOException {
final VirtualFile ignored = myRootVFile.createChildDirectory(this, "RCS");
assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
assertTrue(ProjectRootManager.getInstance(myProject).getFileIndex().isIgnored(ignored));
final VirtualFile module4 = ignored.createChildDirectory(this, "module4");
assertFalse(FileTypeManager.getInstance().isFileIgnored(module4));
assertTrue(ProjectRootManager.getInstance(myProject).getFileIndex().isIgnored(module4));
new WriteCommandAction.Simple(getProject()) {
@Override
protected void run() throws Throwable {
ModuleManager moduleManager = ModuleManager.getInstance(myProject);
Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
PsiTestUtil.addContentRoot(module, module4);
checkInfoNull(ignored);
checkNotInProject(ignored);
checkInfo(module4, module, false, false, null, null);
}
}.execute().throwException();
@@ -436,20 +438,20 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile output1 = myModule1Dir.createChildDirectory(this, "output1");
VirtualFile output2 = myModule1Dir.createChildDirectory(this, "output2");
checkInfoNotNull(output1);
checkInfoNotNull(output2);
checkInProject(output1);
checkInProject(output2);
getCompilerProjectExtension().setCompilerOutputUrl(output1.getUrl());
fireRootsChanged();
checkInfoNull(output1);
checkInfoNotNull(output2);
checkExcluded(output1, myModule);
checkInProject(output2);
getCompilerProjectExtension().setCompilerOutputUrl(output2.getUrl());
fireRootsChanged();
checkInfoNotNull(output1);
checkInfoNull(output2);
checkInProject(output1);
checkExcluded(output2, myModule);
}
private void fireRootsChanged() {
@@ -460,12 +462,12 @@ public class DirectoryIndexTest extends IdeaTestCase {
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.<String>emptyList(), Arrays.asList(mySrcDir1.getUrl()));
checkInfo(mySrcDir1, myModule, false, true, "", JavaSourceRootType.SOURCE, myModule, myModule);
OrderEntry[] entries = myIndex.getInfoForDirectory(mySrcDir1).getOrderEntries();
OrderEntry[] entries = myIndex.getInfoForFile(mySrcDir1).getOrderEntries();
assertInstanceOf(entries[0], LibraryOrderEntry.class);
assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
checkInfo(myTestSrc1, myModule, false, true, "testSrc", JavaSourceRootType.TEST_SOURCE, myModule, myModule);
entries = myIndex.getInfoForDirectory(myTestSrc1).getOrderEntries();
entries = myIndex.getInfoForFile(myTestSrc1).getOrderEntries();
assertInstanceOf(entries[0], LibraryOrderEntry.class);
assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
}
@@ -473,7 +475,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
public void testModuleSourceAsLibraryClasses() throws Exception {
ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Arrays.asList(mySrcDir1.getUrl()), Collections.<String>emptyList());
checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
assertInstanceOf(assertOneElement(checkInfoNotNull(mySrcDir1).getOrderEntries()), ModuleSourceOrderEntry.class);
assertInstanceOf(assertOneElement(checkInProject(mySrcDir1).getOrderEntries()), ModuleSourceOrderEntry.class);
}
public void testModulesWithSameSourceContentRoot() {
@@ -487,7 +489,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
checkInfo(myResDir, myModule, false, false, "", JavaResourceRootType.RESOURCE, myModule);
checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
assertEquals(myModule2Dir, myIndex.getInfoForDirectory(mySrcDir2).getContentRoot());
assertEquals(myModule2Dir, myIndex.getInfoForFile(mySrcDir2).getContentRoot());
}
public void testModuleWithSameSourceRoot() {
@@ -503,7 +505,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
public void testSameSourceAndOutput() {
PsiTestUtil.setCompilerOutputPath(myModule, mySrcDir1.getUrl(), false);
checkInfoNull(mySrcDir1);
checkExcluded(mySrcDir1, myModule);
}
public void testExcludedDirShouldBeExcludedRightAfterItsCreation() throws Exception {
@@ -512,10 +514,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile module2Output = myModule1Dir.createChildDirectory(this, "module2Output");
VirtualFile module2TestOutput = myModule2Dir.createChildDirectory(this, "module2TestOutput");
checkInfoNotNull(excluded);
checkInfoNotNull(projectOutput);
checkInfoNotNull(module2Output);
checkInfoNotNull(module2TestOutput);
checkInProject(excluded);
checkInProject(projectOutput);
checkInProject(module2Output);
checkInProject(module2TestOutput);
getCompilerProjectExtension().setCompilerOutputUrl(projectOutput.getUrl());
@@ -524,10 +526,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
PsiTestUtil.setCompilerOutputPath(myModule2, module2TestOutput.getUrl(), true);
PsiTestUtil.setExcludeCompileOutput(myModule2, true);
checkInfoNull(excluded);
checkInfoNull(projectOutput);
checkInfoNull(module2Output);
checkInfoNull(module2TestOutput);
checkExcluded(excluded, myModule);
checkExcluded(projectOutput, myModule);
checkExcluded(module2Output, myModule);
checkExcluded(module2TestOutput, myModule2);
assertFalse(myIndex.isProjectExcludeRoot(excluded));
assertFalse(myIndex.isProjectExcludeRoot(projectOutput));
@@ -544,10 +546,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
@Override
public void fileCreated(@NotNull VirtualFileEvent e) {
VirtualFile file = e.getFile();
checkInfoNull(file);
created.add(file);
String fileName = e.getFileName();
checkExcluded(file, fileName.contains("module2TestOutput") ? myModule2 : myModule);
created.add(file);
if (fileName.equals("projectOutput")) {
assertFalse(myIndex.isProjectExcludeRoot(file));
}
@@ -573,10 +575,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName());
assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput));
checkInfoNull(excluded);
checkInfoNull(projectOutput);
checkInfoNull(module2Output);
checkInfoNull(module2TestOutput);
checkExcluded(excluded, myModule);
checkExcluded(projectOutput, myModule);
checkExcluded(module2Output, myModule);
checkExcluded(module2TestOutput, myModule2);
assertEquals(created.toString(), 4, created.size());
@@ -607,9 +609,9 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertEquals("dir", e.getFileName());
VirtualFile file = e.getFile();
checkInfoNotNull(file);
checkInfoNull(file.findFileByRelativePath("excluded"));
checkInfoNull(file.findFileByRelativePath("excluded/foo"));
checkInProject(file);
checkExcluded(file.findFileByRelativePath("excluded"), myModule);
checkExcluded(file.findFileByRelativePath("excluded/foo"), myModule);
}
};
@@ -638,8 +640,8 @@ public class DirectoryIndexTest extends IdeaTestCase {
});
checkInfoNull(LocalFileSystem.getInstance().findFileByIoFile(f.getParentFile().getParentFile()));
checkInfoNotNull(LocalFileSystem.getInstance().findFileByIoFile(f));
checkExcluded(LocalFileSystem.getInstance().findFileByIoFile(f.getParentFile().getParentFile()), myModule);
checkInProject(LocalFileSystem.getInstance().findFileByIoFile(f));
}
public void testLibraryDirInContent() throws Exception {
@@ -661,7 +663,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3);
checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule);
assertInstanceOf(assertOneElement(checkInfoNotNull(myResDir).getOrderEntries()), ModuleSourceOrderEntry.class);
assertInstanceOf(assertOneElement(checkInProject(myResDir).getOrderEntries()), ModuleSourceOrderEntry.class);
checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule);
checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3);
@@ -682,6 +684,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertTrue(fileIndex.isIgnored(myModule1OutputDir));
assertFalse(fileIndex.isIgnored(myOutputDir.getParent()));
assertTrue(myIndex.isProjectExcludeRoot(myOutputDir));
checkExcluded(myOutputDir, null);
assertFalse(myIndex.isProjectExcludeRoot(myModule1OutputDir));
String moduleOutputUrl = myModule1OutputDir.getUrl();
@@ -692,7 +695,9 @@ public class DirectoryIndexTest extends IdeaTestCase {
myModule1OutputDir = myOutputDir.createChildDirectory(this, "module1");
assertTrue(myIndex.isProjectExcludeRoot(myOutputDir));
checkExcluded(myOutputDir, null);
assertTrue(myIndex.isProjectExcludeRoot(myModule1OutputDir));
checkExcluded(myModule1OutputDir, null);
assertTrue(fileIndex.isIgnored(myModule1OutputDir));
PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true);
@@ -703,6 +708,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
// now no module inherits project output dir, but it still should be project-excluded
assertTrue(myIndex.isProjectExcludeRoot(myOutputDir));
checkExcluded(myOutputDir, null);
// project output inside module content shouldn't be projectExcludeRoot
VirtualFile projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent");
@@ -725,7 +731,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
VirtualFile fileTestSourceRoot = myRootVFile.createChildData(this, "fileTestSourceRoot.txt");
checkInfoNull(fileRoot);
checkNotInProject(fileRoot);
assertFalse(fileIndex.isInContent(fileRoot));
assertIteratedContent(fileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot));
@@ -758,7 +764,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
// removing file content root
PsiTestUtil.removeContentEntry(myModule, contentEntry);
checkInfoNull(fileRoot);
checkNotInProject(fileRoot);
assertFalse(fileIndex.isInContent(fileRoot));
assertFalse(fileIndex.isInSource(fileRoot));
assertIteratedContent(fileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Arrays.asList(fileRoot));
@@ -785,7 +791,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile fileSourceRoot = myModule1Dir.createChildData(this, "fileSourceRoot.txt");
assertTrue(fileIndex.isInContent(fileSourceRoot));
assertFalse(fileIndex.isInSource(fileSourceRoot));
checkInfoNull(fileSourceRoot);
PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
assertTrue(fileIndex.isInContent(fileSourceRoot));
@@ -796,7 +801,6 @@ public class DirectoryIndexTest extends IdeaTestCase {
PsiTestUtil.removeSourceRoot(myModule, fileSourceRoot);
assertTrue(fileIndex.isInContent(fileSourceRoot));
assertFalse(fileIndex.isInSource(fileSourceRoot));
checkInfoNull(fileSourceRoot);
}
public void testFileModuleExcludeRootUnderDirectoryRoot() throws IOException {
@@ -805,20 +809,18 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile fileExcludeRoot = mySrcDir1.createChildData(this, "fileExcludeRoot.txt");
assertTrue(fileIndex.isInContent(fileExcludeRoot));
assertTrue(fileIndex.isInSource(fileExcludeRoot));
checkInfoNull(fileExcludeRoot);
assertIteratedContent(fileIndex, Arrays.asList(fileExcludeRoot), null);
PsiTestUtil.addExcludedRoot(myModule, fileExcludeRoot);
assertFalse(fileIndex.isInContent(fileExcludeRoot));
assertFalse(fileIndex.isInSource(fileExcludeRoot));
checkInfoNull(fileExcludeRoot);
checkExcluded(fileExcludeRoot, myModule);
assertIteratedContent(fileIndex, null, Arrays.asList(fileExcludeRoot));
// removing file exclude root
PsiTestUtil.removeExcludedRoot(myModule, fileExcludeRoot);
assertTrue(fileIndex.isInContent(fileExcludeRoot));
assertTrue(fileIndex.isInSource(fileExcludeRoot));
checkInfoNull(fileExcludeRoot);
assertIteratedContent(fileIndex, Arrays.asList(fileExcludeRoot), null);
}
@@ -833,7 +835,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
PsiTestUtil.addExcludedRoot(myModule, fileRoot);
assertFalse(fileIndex.isInContent(fileRoot));
checkInfoNull(fileRoot);
checkExcluded(fileRoot, myModule);
assertIteratedContent(fileIndex, null, Arrays.asList(fileRoot));
// removing file exclude root
@@ -860,7 +862,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
VirtualFile temp = myRootVFile.createChildDirectory(this, "temp");
VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
@@ -870,7 +872,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
// delete and recreate
fileSourceRoot.delete(this);
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
assertFalse(fileIndex.isInContent(fileSourceRoot));
assertFalse(fileIndex.isInSource(fileSourceRoot));
fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
@@ -880,11 +882,11 @@ public class DirectoryIndexTest extends IdeaTestCase {
// delete and move from another dir
fileSourceRoot.delete(this);
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
assertFalse(fileIndex.isInContent(fileSourceRoot));
assertFalse(fileIndex.isInSource(fileSourceRoot));
fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
fileSourceRoot.move(this, myRootVFile);
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
assertTrue(fileIndex.isInContent(fileSourceRoot));
@@ -892,11 +894,11 @@ public class DirectoryIndexTest extends IdeaTestCase {
// delete and copy from another dir
fileSourceRoot.delete(this);
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
assertFalse(fileIndex.isInContent(fileSourceRoot));
assertFalse(fileIndex.isInSource(fileSourceRoot));
fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
fileSourceRoot = fileSourceRoot.copy(this, myRootVFile, "fileSourceRoot.txt");
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
assertTrue(fileIndex.isInContent(fileSourceRoot));
@@ -904,11 +906,11 @@ public class DirectoryIndexTest extends IdeaTestCase {
// delete and rename from another file
fileSourceRoot.delete(this);
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
assertFalse(fileIndex.isInContent(fileSourceRoot));
assertFalse(fileIndex.isInSource(fileSourceRoot));
fileSourceRoot = myRootVFile.createChildData(this, "temp_file.txt");
checkInfoNull(fileSourceRoot);
checkNotInProject(fileSourceRoot);
fileSourceRoot.rename(this, "fileSourceRoot.txt");
checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
assertTrue(fileIndex.isInContent(fileSourceRoot));
@@ -922,7 +924,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
@Nullable String packageName,
@Nullable final JpsModuleSourceRootType<?> moduleSourceRootType,
Module... modulesOfOrderEntries) {
DirectoryInfo info = checkInfoNotNull(dir);
DirectoryInfo info = checkInProject(dir);
assertEquals(module, info.getModule());
if (moduleSourceRootType != null) {
assertTrue("isInModuleSource", info.isInModuleSource());
@@ -946,12 +948,21 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
}
private void checkInfoNull(VirtualFile dir) {
assertNull(myIndex.getInfoForDirectory(dir));
private void checkNotInProject(VirtualFile dir) {
DirectoryInfo info = myIndex.getInfoForFile(dir);
assertFalse(info.toString(), info.isInProject());
assertFalse(info.toString(), info.isExcluded());
}
private DirectoryInfo checkInfoNotNull(VirtualFile output2) {
DirectoryInfo info = myIndex.getInfoForDirectory(output2);
assertNotNull(output2.toString(), info);
private void checkExcluded(VirtualFile dir, Module module) {
DirectoryInfo info = myIndex.getInfoForFile(dir);
assertTrue(info.toString(), info.isExcluded());
assertEquals(module, info.getModule());
}
private DirectoryInfo checkInProject(VirtualFile output2) {
DirectoryInfo info = myIndex.getInfoForFile(output2);
assertTrue(output2.toString(), info.isInProject());
info.assertConsistency();
return info;
}
@@ -33,9 +33,9 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.impl.DirectoryIndex;
import com.intellij.openapi.roots.impl.DirectoryInfo;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
@@ -46,7 +46,10 @@ import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class ProjectViewDirectoryHelper {
protected static final Logger LOG = Logger.getInstance("#" + ProjectViewDirectoryHelper.class.getName());
@@ -196,13 +199,13 @@ public class ProjectViewDirectoryHelper {
}
private boolean isInProject(VirtualFile dir) {
if (myIndex.getInfoForDirectory(dir) != null) {
return true;
DirectoryInfo directoryInfo = myIndex.getInfoForFile(dir);
if (directoryInfo.isInProject()) return true;
if (!Registry.is("ide.hide.excluded.files")) {
return directoryInfo.isExcluded();
}
if (Registry.is("ide.hide.excluded.files")) {
return false;
}
return VfsUtilCore.isUnder(dir, new HashSet<VirtualFile>(getTopLevelRoots()));
return false;
}
// used only for non-flatten packages mode
@@ -18,14 +18,12 @@ package com.intellij.internal;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.impl.DirectoryIndex;
import com.intellij.openapi.roots.impl.DirectoryInfo;
import com.intellij.openapi.vfs.VirtualFile;
/**
@@ -53,10 +51,7 @@ public class DumpDirectoryInfoAction extends AnAction {
public boolean processFile(VirtualFile fileOrDir) {
LOG.info(fileOrDir.getPath());
final DirectoryInfo directoryInfo = index.getInfoForDirectory(fileOrDir);
if (directoryInfo != null) {
LOG.info(directoryInfo.toString());
}
LOG.info(index.getInfoForFile(fileOrDir).toString());
return true;
}
};
@@ -149,12 +149,19 @@ public class DirectoryIndexImpl extends DirectoryIndex {
@Override
public DirectoryInfo getInfoForDirectory(@NotNull VirtualFile dir) {
DirectoryInfo info = getInfoForFile(dir);
return info.isInProject() ? info : null;
}
@NotNull
@Override
public DirectoryInfo getInfoForFile(@NotNull VirtualFile file) {
checkAvailability();
dispatchPendingEvents();
if (!(dir instanceof NewVirtualFile)) return null;
if (!(file instanceof NewVirtualFile)) return NonProjectDirectoryInfo.NOT_SUPPORTED_VIRTUAL_FILE_IMPLEMENTATION;
return getRootIndex().getInfoForDirectory(dir);
return getRootIndex().getInfoForFile(file);
}
@Override
@@ -174,14 +181,6 @@ public class DirectoryIndexImpl extends DirectoryIndex {
return getRootIndex().isProjectExcludeRoot(dir);
}
@Override
public boolean isModuleExcludeRoot(@NotNull VirtualFile dir) {
checkAvailability();
if (!(dir instanceof NewVirtualFile)) return false;
return getRootIndex().isModuleExcludeRoot(dir);
}
@Override
public String getPackageName(@NotNull VirtualFile dir) {
checkAvailability();
@@ -34,13 +34,21 @@ public abstract class DirectoryIndex {
@TestOnly
public abstract void checkConsistency();
/**
* The same as {@link #getInfoForFile} but works only for directories or file roots and returns {@code null} for directories
* which aren't included in project content or libraries
* @deprecated use {@link #getInfoForFile(com.intellij.openapi.vfs.VirtualFile)} instead
*/
@Deprecated
public abstract DirectoryInfo getInfoForDirectory(@NotNull VirtualFile dir);
@NotNull
public abstract DirectoryInfo getInfoForFile(@NotNull VirtualFile file);
@Nullable
public abstract JpsModuleSourceRootType<?> getSourceRootType(@NotNull DirectoryInfo info);
public abstract boolean isProjectExcludeRoot(@NotNull VirtualFile dir);
public abstract boolean isModuleExcludeRoot(@NotNull VirtualFile dir);
@NotNull
public abstract
@@ -34,7 +34,7 @@ import java.util.Comparator;
import java.util.List;
public abstract class DirectoryInfo {
public static final int MAX_ROOT_TYPE_ID = (1 << (Byte.SIZE - 2)) - 1;
public static final int MAX_ROOT_TYPE_ID = (1 << (Byte.SIZE - 3)) - 1;
private final Module module; // module to which content it belongs or null
private final VirtualFile libraryClassRoot; // class root in library
private final VirtualFile contentRoot;
@@ -42,18 +42,33 @@ public abstract class DirectoryInfo {
private static final byte MODULE_SOURCE_FLAG = 1; // set if files in this directory belongs to sources of the module (if field 'module' is not null)
private static final byte LIBRARY_SOURCE_FLAG = 2; // set if it's a directory with sources of some library
private final byte sourceRootTypeData;//two least significant bits are used for MODULE_SOURCE_FLAG and LIBRARY_SOURCE_FLAG, the remaining bits store module root type id (source/tests/resources/...)
private static final byte EXCLUDED_FLAG = 4; // set if it's a directory under 'excluded' folder of a module
private final byte rootTypeData;//three least significant bits are used for MODULE_SOURCE_FLAG, LIBRARY_SOURCE_FLAG and EXCLUDED_FLAG, the remaining bits store module root type id (source/tests/resources/...)
DirectoryInfo(Module module,
VirtualFile contentRoot,
VirtualFile sourceRoot,
VirtualFile libraryClassRoot,
byte sourceRootTypeData) {
byte rootTypeData) {
this.module = module;
this.libraryClassRoot = libraryClassRoot;
this.contentRoot = contentRoot;
this.sourceRoot = sourceRoot;
this.sourceRootTypeData = sourceRootTypeData;
this.rootTypeData = rootTypeData;
}
/**
* @return {@code true} if located under project content or library roots and not excluded or ignored
*/
public boolean isInProject() {
return !isExcluded();
}
/**
* @return {@code true} if located under ignored directory
*/
public boolean isIgnored() {
return false;
}
@Override
@@ -63,7 +78,7 @@ public abstract class DirectoryInfo {
DirectoryInfo info = (DirectoryInfo)o;
return sourceRootTypeData == info.sourceRootTypeData &&
return rootTypeData == info.rootTypeData &&
Comparing.equal(contentRoot, info.contentRoot) &&
Comparing.equal(libraryClassRoot, info.libraryClassRoot) &&
Comparing.equal(module, info.module) &&
@@ -77,7 +92,7 @@ public abstract class DirectoryInfo {
result = 31 * result + (libraryClassRoot != null ? libraryClassRoot.hashCode() : 0);
result = 31 * result + (contentRoot != null ? contentRoot.hashCode() : 0);
result = 31 * result + (sourceRoot != null ? sourceRoot.hashCode() : 0);
result = 31 * result + (int)sourceRootTypeData;
result = 31 * result + (int)rootTypeData;
return result;
}
@@ -88,6 +103,7 @@ public abstract class DirectoryInfo {
", isInModuleSource=" + isInModuleSource() +
", rootTypeId=" + getSourceRootTypeId() +
", isInLibrarySource=" + isInLibrarySource() +
", isExcludedFromModule=" + isExcluded() +
", libraryClassRoot=" + getLibraryClassRoot() +
", contentRoot=" + getContentRoot() +
", sourceRoot=" + getSourceRoot() +
@@ -214,11 +230,15 @@ public abstract class DirectoryInfo {
}
public boolean isInModuleSource() {
return BitUtil.isSet(sourceRootTypeData, MODULE_SOURCE_FLAG);
return BitUtil.isSet(rootTypeData, MODULE_SOURCE_FLAG);
}
public boolean isInLibrarySource() {
return BitUtil.isSet(sourceRootTypeData, LIBRARY_SOURCE_FLAG);
return BitUtil.isSet(rootTypeData, LIBRARY_SOURCE_FLAG);
}
public boolean isExcluded() {
return BitUtil.isSet(rootTypeData, EXCLUDED_FLAG);
}
public Module getModule() {
@@ -234,13 +254,15 @@ public abstract class DirectoryInfo {
}
public int getSourceRootTypeId() {
return sourceRootTypeData >> 2;
return rootTypeData >> 3;
}
public static int createSourceRootTypeData(boolean isInModuleSources, boolean isInLibrarySource, int moduleSourceRootTypeId) {
public static int createRootTypeData(boolean isInModuleSources, boolean isInLibrarySource, boolean isExcludedFromModule,
int moduleSourceRootTypeId) {
if (moduleSourceRootTypeId > MAX_ROOT_TYPE_ID) {
throw new IllegalArgumentException("Module source root type id " + moduleSourceRootTypeId + " exceeds the maximum allowable value (" + MAX_ROOT_TYPE_ID + ")");
}
return (isInModuleSources ? MODULE_SOURCE_FLAG : 0) | (isInLibrarySource ? LIBRARY_SOURCE_FLAG : 0) | moduleSourceRootTypeId << 2;
return (isInModuleSources ? MODULE_SOURCE_FLAG : 0) | (isInLibrarySource ? LIBRARY_SOURCE_FLAG : 0) | (isExcludedFromModule ? EXCLUDED_FLAG : 0)
| moduleSourceRootTypeId << 3;
}
}
@@ -5,7 +5,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.FileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author nik
@@ -19,21 +18,9 @@ public abstract class FileIndexBase implements FileIndex {
myFileTypeRegistry = fileTypeManager;
}
@Nullable
@NotNull
protected DirectoryInfo getInfoForFileOrDirectory(@NotNull VirtualFile file) {
if (!file.isDirectory() && file.getParent() == null) return null; // e.g. LightVirtualFile in test
DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(file);
if (info != null) {
return info;
}
if (!file.isDirectory() && !myDirectoryIndex.isModuleExcludeRoot(file)) {
VirtualFile dir = file.getParent();
if (dir != null) {
return myDirectoryIndex.getInfoForDirectory(dir);
}
}
return null;
return myDirectoryIndex.getInfoForFile(file);
}
@Override
@@ -29,7 +29,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -49,8 +48,8 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde
for (VirtualFile contentRoot : contentRoots) {
VirtualFile parent = contentRoot.getParent();
if (parent != null) {
DirectoryInfo parentInfo = myDirectoryIndex.getInfoForDirectory(parent);
if (parentInfo != null && myModule.equals(parentInfo.getModule())) continue; // inner content - skip it
DirectoryInfo parentInfo = myDirectoryIndex.getInfoForFile(parent);
if (parentInfo.isInProject() && myModule.equals(parentInfo.getModule())) continue; // inner content - skip it
}
boolean finished = VfsUtilCore.iterateChildrenRecursively(contentRoot, myContentFilter, iterator);
@@ -68,50 +67,45 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde
@Override
public boolean isInContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && myModule.equals(info.getModule());
return info.isInProject() && myModule.equals(info.getModule());
}
@Override
public boolean isInSourceContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.isInModuleSource() && myModule.equals(info.getModule());
return info.isInModuleSource() && myModule.equals(info.getModule());
}
@Override
@NotNull
public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
if (info == null) return Collections.emptyList();
return info.findAllOrderEntriesWithOwnerModule(myModule);
return getInfoForFileOrDirectory(fileOrDir).findAllOrderEntriesWithOwnerModule(myModule);
}
@Override
public OrderEntry getOrderEntryForFile(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
if (info == null) return null;
return info.findOrderEntryWithOwnerModule(myModule);
return getInfoForFileOrDirectory(fileOrDir).findOrderEntryWithOwnerModule(myModule);
}
@Override
public boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.isInModuleSource() && myModule.equals(info.getModule())
return info.isInModuleSource() && myModule.equals(info.getModule())
&& JavaModuleSourceRootTypes.isTestSourceOrResource(myDirectoryIndex.getSourceRootType(info));
}
@Override
public boolean isUnderSourceRootOfType(@NotNull VirtualFile fileOrDir, @NotNull Set<? extends JpsModuleSourceRootType<?>> rootTypes) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.isInModuleSource() && myModule.equals(info.getModule())
&& rootTypes.contains(myDirectoryIndex.getSourceRootType(info));
return info.isInModuleSource() && myModule.equals(info.getModule()) && rootTypes.contains(myDirectoryIndex.getSourceRootType(info));
}
private class ContentFilter implements VirtualFileFilter {
@Override
public boolean accept(@NotNull VirtualFile file) {
if (file.isDirectory()) {
DirectoryInfo info = myDirectoryIndex.getInfoForDirectory(file);
return info != null && myModule.equals(info.getModule());
DirectoryInfo info = myDirectoryIndex.getInfoForFile(file);
return info.isInProject() && myModule.equals(info.getModule());
}
else {
return !myFileTypeRegistry.isFileIgnored(file);
@@ -0,0 +1,89 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.OrderEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
/**
* @author nik
*/
class NonProjectDirectoryInfo extends DirectoryInfo {
public static final NonProjectDirectoryInfo IGNORED = new NonProjectDirectoryInfo("ignored") {
@Override
public boolean isIgnored() {
return true;
}
};
public static final NonProjectDirectoryInfo EXCLUDED = new NonProjectDirectoryInfo("excluded from project") {
@Override
public boolean isExcluded() {
return true;
}
};
public static final NonProjectDirectoryInfo NOT_UNDER_PROJECT_ROOTS = new NonProjectDirectoryInfo("not under project roots");
public static final NonProjectDirectoryInfo INVALID = new NonProjectDirectoryInfo("invalid");
public static final NonProjectDirectoryInfo NOT_SUPPORTED_VIRTUAL_FILE_IMPLEMENTATION = new NonProjectDirectoryInfo("not supported VirtualFile implementation");
private final String myDebugName;
private NonProjectDirectoryInfo(String debugName) {
super(null, null, null, null, (byte)0);
myDebugName = debugName;
}
@Override
public boolean isInProject() {
return false;
}
@NotNull
@Override
public OrderEntry[] getOrderEntries() {
return OrderEntry.EMPTY_ARRAY;
}
@Nullable
@Override
OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) {
return null;
}
@NotNull
@Override
List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) {
return Collections.emptyList();
}
@Override
public String toString() {
return "DirectoryInfo: " + myDebugName;
}
@Override
public boolean equals(Object o) {
return this == o;
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
}
@@ -83,7 +83,7 @@ public class ProjectFileIndexFacade extends FileIndexFacade {
while (true) {
if (childDir == null) return false;
if (childDir.equals(baseDir)) return true;
if (myDirectoryIndex.getInfoForDirectory(childDir) == null) return false;
if (!myDirectoryIndex.getInfoForFile(childDir).isInProject()) return false;
childDir = childDir.getParent();
}
}
@@ -34,7 +34,6 @@ import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -57,13 +56,13 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
for (VirtualFile contentRoot : contentRoots) {
DirectoryInfo info = getInfoForFileOrDirectory(contentRoot);
if (info == null) continue; // is excluded or ignored
if (!info.isInProject()) continue; // is excluded or ignored
if (!module.equals(info.getModule())) continue; // maybe 2 modules have the same content root?
VirtualFile parent = contentRoot.getParent();
if (parent != null) {
DirectoryInfo parentInfo = getInfoForFileOrDirectory(parent);
if (parentInfo != null && parentInfo.getModule() != null) continue; // inner content - skip it
if (parentInfo.isInProject() && parentInfo.getModule() != null) continue; // inner content - skip it
}
boolean finished = VfsUtilCore.iterateChildrenRecursively(contentRoot, myContentFilter, iterator);
@@ -81,60 +80,42 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
@Override
public boolean isIgnored(@NotNull VirtualFile file) {
if (myFileTypeRegistry.isFileIgnored(file)) return true;
VirtualFile dir = file.isDirectory() ? file : file.getParent();
if (dir == null) return false;
DirectoryInfo info = getInfoForFileOrDirectory(dir);
if (info != null) return false;
if (myDirectoryIndex.isProjectExcludeRoot(dir)) return true;
VirtualFile parent = dir.getParent();
while (true) {
if (parent == null) return false;
DirectoryInfo parentInfo = getInfoForFileOrDirectory(parent);
if (parentInfo != null) return true;
if (myDirectoryIndex.isProjectExcludeRoot(parent)) return true;
parent = parent.getParent();
}
DirectoryInfo info = getInfoForFileOrDirectory(file);
return info.isIgnored() || info.isExcluded();
}
@Override
public Module getModuleForFile(@NotNull VirtualFile file) {
if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate();
VirtualFile dir = file.isDirectory() ? file : file.getParent();
if (dir == null) return null;
DirectoryInfo info = getInfoForFileOrDirectory(dir);
if (info == null) return null;
DirectoryInfo info = getInfoForFileOrDirectory(file);
if (!info.isInProject()) return null;
return info.getModule();
}
@Override
@NotNull
public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile file) {
DirectoryInfo info = getInfoForFileOrDirectory(file);
if (info == null) return Collections.emptyList();
return Arrays.asList(info.getOrderEntries());
return Arrays.asList(getInfoForFileOrDirectory(file).getOrderEntries());
}
@Override
public VirtualFile getClassRootForFile(@NotNull VirtualFile file) {
final DirectoryInfo info = getInfoForFileOrDirectory(file);
if (info == null) return null;
if (!info.isInProject()) return null;
return info.getLibraryClassRoot();
}
@Override
public VirtualFile getSourceRootForFile(@NotNull VirtualFile file) {
final DirectoryInfo info = getInfoForFileOrDirectory(file);
if (info == null) return null;
if (!info.isInProject()) return null;
return info.getSourceRoot();
}
@Override
public VirtualFile getContentRootForFile(@NotNull VirtualFile file) {
final DirectoryInfo info = getInfoForFileOrDirectory(file);
if (info == null) return null;
if (!info.isInProject()) return null;
return info.getContentRoot();
}
@@ -147,58 +128,55 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
@Override
public boolean isLibraryClassFile(@NotNull VirtualFile file) {
if (file.isDirectory()) return false;
if (myFileTypeRegistry.isFileIgnored(file)) return false;
DirectoryInfo parentInfo = getInfoForFileOrDirectory(file);
return parentInfo != null && parentInfo.hasLibraryClassRoot();
return parentInfo.isInProject() && parentInfo.hasLibraryClassRoot();
}
@Override
public boolean isInSource(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && (info.isInModuleSource() || info.isInLibrarySource());
return info.isInModuleSource() || info.isInLibrarySource();
}
@Override
public boolean isInLibraryClasses(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.hasLibraryClassRoot();
return info.isInProject() && info.hasLibraryClassRoot();
}
@Override
public boolean isInLibrarySource(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.isInLibrarySource();
return getInfoForFileOrDirectory(fileOrDir).isInLibrarySource();
}
@Override
public boolean isInContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.getModule() != null;
return info.isInProject() && info.getModule() != null;
}
@Override
public boolean isInSourceContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.isInModuleSource();
return getInfoForFileOrDirectory(fileOrDir).isInModuleSource();
}
@Override
public boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.isInModuleSource() && JavaModuleSourceRootTypes.isTestSourceOrResource(myDirectoryIndex.getSourceRootType(info));
return info.isInModuleSource() && JavaModuleSourceRootTypes.isTestSourceOrResource(myDirectoryIndex.getSourceRootType(info));
}
@Override
public boolean isUnderSourceRootOfType(@NotNull VirtualFile fileOrDir, @NotNull Set<? extends JpsModuleSourceRootType<?>> rootTypes) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info != null && info.isInModuleSource() && rootTypes.contains(myDirectoryIndex.getSourceRootType(info));
return info.isInModuleSource() && rootTypes.contains(myDirectoryIndex.getSourceRootType(info));
}
private class ContentFilter implements VirtualFileFilter {
@Override
public boolean accept(@NotNull VirtualFile file) {
DirectoryInfo info = getInfoForFileOrDirectory(file);
if (info == null || info.getModule() == null) return false;
if (!info.isInProject() || info.getModule() == null) return false;
if (file.isDirectory()) {
return true;
@@ -43,16 +43,8 @@ import java.util.*;
public class RootIndex extends DirectoryIndex {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.RootIndex");
private static final DirectoryInfo NULL_INFO = new DirectoryInfo(null, null, null, null, (byte)0) {
@NotNull
@Override
public OrderEntry[] getOrderEntries() {
throw new UnsupportedOperationException("Not implemented");
}
};
private final Set<VirtualFile> myProjectExcludedRoots = ContainerUtil.newHashSet();
private final Set<VirtualFile> myModuleExcludedRoots;
private final MultiMap<String, VirtualFile> myPackagePrefixRoots = new MultiMap<String, VirtualFile>() {
@NotNull
@Override
@@ -77,15 +69,15 @@ public class RootIndex extends DirectoryIndex {
Set<VirtualFile> allRoots = info.getAllRoots();
for (VirtualFile root : allRoots) {
List<VirtualFile> hierarchy = getHierarchy(root, allRoots, info);
Pair<DirectoryInfo, String> pair = hierarchy == null ? new Pair<DirectoryInfo, String>(null, null) : calcDirectoryInfo(root, hierarchy, info);
Pair<DirectoryInfo, String> pair = hierarchy != null
? calcDirectoryInfo(root, hierarchy, info)
: new Pair<DirectoryInfo, String>(NonProjectDirectoryInfo.IGNORED, null);
cacheInfos(root, root, pair.first);
myPackagePrefixRoots.putValue(pair.second, root);
if (info.shouldMarkAsProjectExcluded(root, hierarchy)) {
myProjectExcludedRoots.add(root);
}
}
myModuleExcludedRoots = info.excludedFromModule.keySet();
}
@NotNull
@@ -263,14 +255,27 @@ public class RootIndex extends DirectoryIndex {
}
@Override
@Nullable
public DirectoryInfo getInfoForDirectory(@NotNull final VirtualFile dir) {
if (!dir.isValid()) {
return null;
public DirectoryInfo getInfoForDirectory(@NotNull VirtualFile dir) {
DirectoryInfo info = getInfoForFile(dir);
return info.isInProject() ? info : null;
}
@NotNull
@Override
public DirectoryInfo getInfoForFile(@NotNull VirtualFile file) {
if (!file.isValid()) {
return NonProjectDirectoryInfo.INVALID;
}
if (!dir.isDirectory()) {
DirectoryInfo info = myInfoCache.getCachedInfo(dir);
return info == NULL_INFO ? null : info;
VirtualFile dir;
if (!file.isDirectory()) {
DirectoryInfo info = myInfoCache.getCachedInfo(file);
if (info != null) {
return info;
}
dir = file.getParent();
}
else {
dir = file;
}
int count = 0;
@@ -283,21 +288,21 @@ public class RootIndex extends DirectoryIndex {
if (!dir.equals(root)) {
cacheInfos(dir, root, info);
}
return info == NULL_INFO ? null : info;
return info;
}
if (isIgnored(root)) {
return cacheInfos(dir, root, null);
return cacheInfos(dir, root, NonProjectDirectoryInfo.IGNORED);
}
}
return cacheInfos(dir, null, null);
return cacheInfos(dir, null, NonProjectDirectoryInfo.NOT_UNDER_PROJECT_ROOTS);
}
@Nullable
private DirectoryInfo cacheInfos(VirtualFile dir, @Nullable VirtualFile stopAt, @Nullable DirectoryInfo info) {
@NotNull
private DirectoryInfo cacheInfos(VirtualFile dir, @Nullable VirtualFile stopAt, @NotNull DirectoryInfo info) {
while (dir != null) {
myInfoCache.cacheInfo(dir, info == null ? NULL_INFO : info);
myInfoCache.cacheInfo(dir, info);
if (dir.equals(stopAt)) {
break;
}
@@ -311,11 +316,6 @@ public class RootIndex extends DirectoryIndex {
return myProjectExcludedRoots.contains(dir);
}
@Override
public boolean isModuleExcludeRoot(@NotNull final VirtualFile dir) {
return myModuleExcludedRoots.contains(dir);
}
@Override
@NotNull
public Query<VirtualFile> getDirectoriesByPackageName(@NotNull final String packageName, final boolean includeLibrarySources) {
@@ -327,7 +327,8 @@ public class RootIndex extends DirectoryIndex {
String shortName = StringUtil.getShortName(packageName);
for (VirtualFile parentDir : getDirectoriesByPackageName(StringUtil.getPackageName(packageName), true)) {
VirtualFile child = parentDir.findChild(shortName);
if (child != null && child.isDirectory() && getInfoForDirectory(child) != null && packageName.equals(getPackageName(child))) {
if (child != null && child.isDirectory() && getInfoForFile(child).isInProject()
&& packageName.equals(getPackageName(child))) {
result.add(child);
}
}
@@ -344,8 +345,8 @@ public class RootIndex extends DirectoryIndex {
result = ContainerUtil.filter(result, new Condition<VirtualFile>() {
@Override
public boolean value(VirtualFile file) {
DirectoryInfo info = getInfoForDirectory(file);
return info != null && (!info.isInLibrarySource() || info.isInModuleSource() || info.hasLibraryClassRoot());
DirectoryInfo info = getInfoForFile(file);
return info.isInProject() && (!info.isInLibrarySource() || info.isInModuleSource() || info.hasLibraryClassRoot());
}
});
}
@@ -397,7 +398,7 @@ public class RootIndex extends DirectoryIndex {
return false;
}
@Nullable
@Nullable("returns null only if dir is under ignored folder")
private static List<VirtualFile> getHierarchy(VirtualFile dir, @NotNull Set<VirtualFile> allRoots, @NotNull RootInfo info) {
List<VirtualFile> hierarchy = ContainerUtil.newArrayList();
boolean hasContentRoots = false;
@@ -471,6 +472,15 @@ public class RootIndex extends DirectoryIndex {
return null;
}
@Nullable
private Module findParentModuleForExcluded(@NotNull List<VirtualFile> hierarchy) {
for (VirtualFile root : hierarchy) {
Module module = contentRootOf.get(root);
if (module != null) return module;
}
return null;
}
@Nullable
private VirtualFile findLibraryRootInfo(@NotNull List<VirtualFile> hierarchy, boolean source) {
Set<Library> librariesToIgnore = ContainerUtil.newHashSet();
@@ -566,8 +576,12 @@ public class RootIndex extends DirectoryIndex {
VirtualFile moduleContentRoot = info.findModuleRootInfo(hierarchy);
VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false);
VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true);
Module parentModuleForExcluded = null;
if (moduleContentRoot == null && libraryClassRoot == null && librarySourceRoot == null) {
return new Pair<DirectoryInfo, String>(null, null);
parentModuleForExcluded = info.findParentModuleForExcluded(hierarchy);
if (parentModuleForExcluded == null) {
return new Pair<DirectoryInfo, String>(NonProjectDirectoryInfo.EXCLUDED, null);
}
}
VirtualFile sourceRoot = info.findPackageRootInfo(hierarchy, moduleContentRoot, null, librarySourceRoot);
@@ -577,11 +591,9 @@ public class RootIndex extends DirectoryIndex {
boolean inLibrarySource = librarySourceRoot != null;
int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0;
DirectoryInfo directoryInfo = new DirectoryInfo(info.contentRootOf.get(moduleContentRoot),
moduleContentRoot,
sourceRoot,
libraryClassRoot,
(byte)DirectoryInfo.createSourceRootTypeData(inModuleSources, inLibrarySource, typeId)) {
Module module = parentModuleForExcluded != null ? parentModuleForExcluded : info.contentRootOf.get(moduleContentRoot);
byte rootTypeData = (byte)DirectoryInfo.createRootTypeData(inModuleSources, inLibrarySource, parentModuleForExcluded != null, typeId);
DirectoryInfo directoryInfo = new DirectoryInfo(module, moduleContentRoot, sourceRoot, libraryClassRoot, rootTypeData) {
@NotNull
@Override
public OrderEntry[] getOrderEntries() {