simplification: getOrderEntries moved to DirectoryIndex

This commit is contained in:
nik
2014-07-25 10:05:20 +04:00
parent 9b94de6073
commit 0932bdbc71
9 changed files with 210 additions and 252 deletions
@@ -49,7 +49,7 @@ import static java.util.Collections.singletonList;
public class DirectoryIndexTest extends IdeaTestCase {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexTest");
private DirectoryIndex myIndex;
private DirectoryIndexImpl myIndex;
private Module myModule2, myModule3;
private VirtualFile myRootVFile;
@@ -176,7 +176,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
}
});
myIndex = DirectoryIndex.getInstance(myProject);
myIndex = (DirectoryIndexImpl)DirectoryIndex.getInstance(myProject);
// to not interfere with previous test firing vfs events
VirtualFileManager.getInstance().syncRefresh();
}
@@ -481,12 +481,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.getInfoForFile(mySrcDir1).getOrderEntries();
OrderEntry[] entries = myIndex.getOrderEntries(myIndex.getInfoForFile(mySrcDir1));
assertInstanceOf(entries[0], LibraryOrderEntry.class);
assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
checkInfo(myTestSrc1, myModule, false, true, "testSrc", JavaSourceRootType.TEST_SOURCE, myModule, myModule);
entries = myIndex.getInfoForFile(myTestSrc1).getOrderEntries();
entries = myIndex.getOrderEntries(myIndex.getInfoForFile(myTestSrc1));
assertInstanceOf(entries[0], LibraryOrderEntry.class);
assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
}
@@ -494,7 +494,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(assertInProject(mySrcDir1).getOrderEntries()), ModuleSourceOrderEntry.class);
assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(mySrcDir1))), ModuleSourceOrderEntry.class);
}
public void testModulesWithSameSourceContentRoot() {
@@ -657,7 +657,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3);
checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule);
assertInstanceOf(assertOneElement(assertInProject(myResDir).getOrderEntries()), ModuleSourceOrderEntry.class);
assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(myResDir))), ModuleSourceOrderEntry.class);
checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule);
checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3);
@@ -931,10 +931,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
assertEquals(packageName, fileIndex.getPackageNameByDirectory(file));
}
assertEquals(Arrays.toString(info.getOrderEntries()), modulesOfOrderEntries.length, info.getOrderEntries().length);
assertEquals(Arrays.toString(myIndex.getOrderEntries(info)), modulesOfOrderEntries.length, myIndex.getOrderEntries(info).length);
for (Module aModule : modulesOfOrderEntries) {
OrderEntry found = info.findOrderEntryWithOwnerModule(aModule);
assertNotNull("not found: " + aModule + " in " + Arrays.toString(info.getOrderEntries()), found);
OrderEntry found = myIndex.findOrderEntryWithOwnerModule(info, aModule);
assertNotNull("not found: " + aModule + " in " + Arrays.toString(myIndex.getOrderEntries(info)), found);
}
}
@@ -953,7 +953,7 @@ public class DirectoryIndexTest extends IdeaTestCase {
private DirectoryInfo assertInProject(VirtualFile file) {
DirectoryInfo info = myIndex.getInfoForFile(file);
assertTrue(file.toString(), info.isInProject());
info.assertConsistency();
myIndex.assertConsistency(info);
return info;
}
@@ -25,15 +25,14 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootAdapter;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap;
@@ -43,6 +42,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class DirectoryIndexImpl extends DirectoryIndex {
@@ -68,7 +69,7 @@ public class DirectoryIndexImpl extends DirectoryIndex {
});
}
private void subscribeToFileChanges() {
protected void subscribeToFileChanges() {
myConnection.subscribe(FileTypeManager.TOPIC, new FileTypeListener.Adapter() {
@Override
public void fileTypesChanged(@NotNull FileTypeEvent event) {
@@ -98,7 +99,7 @@ public class DirectoryIndexImpl extends DirectoryIndex {
});
}
private void markContentRootsForRefresh() {
protected void markContentRootsForRefresh() {
Module[] modules = ModuleManager.getInstance(myProject).getModules();
for (Module module : modules) {
VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
@@ -110,7 +111,7 @@ public class DirectoryIndexImpl extends DirectoryIndex {
}
}
private void dispatchPendingEvents() {
protected void dispatchPendingEvents() {
myConnection.deliverImmediately();
}
@@ -124,24 +125,27 @@ public class DirectoryIndexImpl extends DirectoryIndex {
private RootIndex getRootIndex() {
RootIndex rootIndex = myRootIndex;
if (rootIndex == null) {
myRootIndex = rootIndex = new RootIndex(myProject, new RootIndex.InfoCache() {
// Upsource can't use int-mapping because different files may have the same id there
private final ConcurrentIntObjectMap<DirectoryInfo> myInfoCache = new StripedLockIntObjectConcurrentHashMap<DirectoryInfo>();
@Override
public void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info) {
myInfoCache.put(((NewVirtualFile)dir).getId(), info);
}
@Override
public DirectoryInfo getCachedInfo(@NotNull VirtualFile dir) {
return myInfoCache.get(((NewVirtualFile)dir).getId());
}
});
myRootIndex = rootIndex = new RootIndex(myProject, createRootInfoCache());
}
return rootIndex;
}
@Override
protected RootIndex.InfoCache createRootInfoCache() {
return new RootIndex.InfoCache() {
// Upsource can't use int-mapping because different files may have the same id there
private final ConcurrentIntObjectMap<DirectoryInfo> myInfoCache = new StripedLockIntObjectConcurrentHashMap<DirectoryInfo>();
@Override
public void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info) {
myInfoCache.put(((NewVirtualFile)dir).getId(), info);
}
@Override
public DirectoryInfo getCachedInfo(@NotNull VirtualFile dir) {
return myInfoCache.get(((NewVirtualFile)dir).getId());
}
};
}
@TestOnly
public void checkConsistency() {
getRootIndex().checkConsistency();
@@ -181,6 +185,21 @@ public class DirectoryIndexImpl extends DirectoryIndex {
return getRootIndex().getPackageName(dir);
}
@NotNull
@Override
public OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info) {
checkAvailability();
return getRootIndex().getOrderEntries(info);
}
@TestOnly
void assertConsistency(DirectoryInfo info) {
OrderEntry[] entries = getOrderEntries(info);
for (int i = 1; i < entries.length; i++) {
assert RootIndex.BY_OWNER_MODULE.compare(entries[i - 1], entries[i]) <= 0;
}
}
private void checkAvailability() {
if (myDisposed) {
ProgressManager.checkCanceled();
@@ -188,4 +207,95 @@ public class DirectoryIndexImpl extends DirectoryIndex {
}
}
@NotNull
private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) {
return new OrderEntry() {
@NotNull
@Override
public VirtualFile[] getFiles(OrderRootType type) {
throw new IncorrectOperationException();
}
@NotNull
@Override
public String[] getUrls(OrderRootType rootType) {
throw new IncorrectOperationException();
}
@NotNull
@Override
public String getPresentableName() {
throw new IncorrectOperationException();
}
@Override
public boolean isValid() {
throw new IncorrectOperationException();
}
@NotNull
@Override
public Module getOwnerModule() {
return ownerModule;
}
@Override
public <R> R accept(RootPolicy<R> policy, @Nullable R initialValue) {
throw new IncorrectOperationException();
}
@Override
public int compareTo(@NotNull OrderEntry o) {
throw new IncorrectOperationException();
}
@Override
public boolean isSynthetic() {
throw new IncorrectOperationException();
}
};
}
@Override
@Nullable
OrderEntry findOrderEntryWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule) {
OrderEntry[] entries = getOrderEntries(info);
if (entries.length < 10) {
for (OrderEntry entry : entries) {
if (entry.getOwnerModule() == ownerModule) return entry;
}
return null;
}
int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), RootIndex.BY_OWNER_MODULE);
return index < 0 ? null : entries[index];
}
@Override
@NotNull
List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule) {
OrderEntry[] entries = getOrderEntries(info);
if (entries.length == 0) return Collections.emptyList();
if (entries.length == 1) {
OrderEntry entry = entries[0];
return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.<OrderEntry>emptyList();
}
int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), RootIndex.BY_OWNER_MODULE);
if (index < 0) {
return Collections.emptyList();
}
int firstIndex = index;
while (firstIndex - 1 >= 0 && entries[firstIndex - 1].getOwnerModule() == ownerModule) {
firstIndex--;
}
int lastIndex = index + 1;
while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) {
lastIndex++;
}
OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex];
System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex);
return Arrays.asList(subArray);
}
}
@@ -17,23 +17,23 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Query;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.List;
public abstract class DirectoryIndex {
public static DirectoryIndex getInstance(Project project) {
assert !project.isDefault() : "Must not call DirectoryIndex for default project";
return ServiceManager.getService(project, DirectoryIndex.class);
}
@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
@@ -62,4 +62,13 @@ public abstract class DirectoryIndex {
public boolean isInitialized() {
return true;
}
@NotNull
public abstract OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info);
@Nullable
abstract OrderEntry findOrderEntryWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule);
@NotNull
abstract List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule);
}
@@ -17,13 +17,8 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.List;
public abstract class DirectoryInfo {
/**
@@ -61,16 +56,4 @@ public abstract class DirectoryInfo {
@Nullable
public abstract Module getModule();
@NotNull
public abstract OrderEntry[] getOrderEntries();
@Nullable
abstract OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule);
@NotNull
abstract List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule);
@TestOnly
abstract void assertConsistency();
}
@@ -16,34 +16,16 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.RootPolicy;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @author nik
*/
public abstract class DirectoryInfoImpl extends DirectoryInfo {
public static final Comparator<OrderEntry> BY_OWNER_MODULE = new Comparator<OrderEntry>() {
@Override
public int compare(OrderEntry o1, OrderEntry o2) {
String name1 = o1.getOwnerModule().getName();
String name2 = o2.getOwnerModule().getName();
return name1.compareTo(name2);
}
};
public class DirectoryInfoImpl extends DirectoryInfo {
public static final int MAX_ROOT_TYPE_ID = Byte.MAX_VALUE;
private final VirtualFile myRoot;//original project root for which this information is calculated
private final Module module; // module to which content it belongs or null
private final VirtualFile libraryClassRoot; // class root in library
private final VirtualFile contentRoot;
@@ -53,8 +35,9 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
private final boolean myExcluded;
private final byte mySourceRootTypeId;
DirectoryInfoImpl(Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot,
DirectoryInfoImpl(@NotNull VirtualFile root, Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot,
boolean inModuleSource, boolean inLibrarySource, boolean isExcluded, int sourceRootTypeId) {
myRoot = root;
this.module = module;
this.libraryClassRoot = libraryClassRoot;
this.contentRoot = contentRoot;
@@ -74,30 +57,12 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DirectoryInfoImpl info = (DirectoryInfoImpl)o;
return mySourceRootTypeId == info.mySourceRootTypeId &&
myInModuleSource == info.myInModuleSource &&
myInLibrarySource == info.myInLibrarySource &&
myExcluded == info.myExcluded &&
Comparing.equal(contentRoot, info.contentRoot) &&
Comparing.equal(libraryClassRoot, info.libraryClassRoot) &&
Comparing.equal(module, info.module) &&
Arrays.equals(getOrderEntries(), info.getOrderEntries()) &&
Comparing.equal(sourceRoot, info.sourceRoot);
return myRoot.equals(((DirectoryInfoImpl)o).myRoot);
}
@Override
public int hashCode() {
int result = module != null ? module.hashCode() : 0;
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 + (myInModuleSource ? 1 : 0);
result = 31 * result + (myInLibrarySource ? 1 : 0);
result = 31 * result + (myExcluded ? 1 : 0);
result = 31 * result + (int)mySourceRootTypeId;
return result;
return myRoot.hashCode();
}
@SuppressWarnings({"HardCodedStringLiteral"})
@@ -111,98 +76,9 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
", libraryClassRoot=" + getLibraryClassRoot() +
", contentRoot=" + getContentRoot() +
", sourceRoot=" + getSourceRoot() +
", orderEntries=" + Arrays.toString(getOrderEntries()) +
"}";
}
@NotNull
private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) {
return new OrderEntry() {
@NotNull
@Override
public VirtualFile[] getFiles(OrderRootType type) {
throw new IncorrectOperationException();
}
@NotNull
@Override
public String[] getUrls(OrderRootType rootType) {
throw new IncorrectOperationException();
}
@NotNull
@Override
public String getPresentableName() {
throw new IncorrectOperationException();
}
@Override
public boolean isValid() {
throw new IncorrectOperationException();
}
@NotNull
@Override
public Module getOwnerModule() {
return ownerModule;
}
@Override
public <R> R accept(RootPolicy<R> policy, @Nullable R initialValue) {
throw new IncorrectOperationException();
}
@Override
public int compareTo(@NotNull OrderEntry o) {
throw new IncorrectOperationException();
}
@Override
public boolean isSynthetic() {
throw new IncorrectOperationException();
}
};
}
@Nullable
OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) {
OrderEntry[] entries = getOrderEntries();
if (entries.length < 10) {
for (OrderEntry entry : entries) {
if (entry.getOwnerModule() == ownerModule) return entry;
}
return null;
}
int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE);
return index < 0 ? null : entries[index];
}
@NotNull
List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) {
OrderEntry[] entries = getOrderEntries();
if (entries.length == 1) {
OrderEntry entry = entries[0];
return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.<OrderEntry>emptyList();
}
int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE);
if (index < 0) {
return Collections.emptyList();
}
int firstIndex = index;
while (firstIndex-1 >= 0 && entries[firstIndex-1].getOwnerModule() == ownerModule) {
firstIndex--;
}
int lastIndex = index+1;
while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) {
lastIndex++;
}
OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex];
System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex);
return Arrays.asList(subArray);
}
public boolean isInProject() {
return !isExcluded();
}
@@ -241,15 +117,12 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
return module;
}
@TestOnly
void assertConsistency() {
OrderEntry[] entries = getOrderEntries();
for (int i=1; i<entries.length; i++) {
assert BY_OWNER_MODULE.compare(entries[i-1], entries[i]) <= 0;
}
}
public int getSourceRootTypeId() {
return mySourceRootTypeId;
}
@NotNull
public VirtualFile getRoot() {
return myRoot;
}
}
@@ -79,12 +79,12 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde
@Override
@NotNull
public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile fileOrDir) {
return getInfoForFileOrDirectory(fileOrDir).findAllOrderEntriesWithOwnerModule(myModule);
return myDirectoryIndex.findAllOrderEntriesWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule);
}
@Override
public OrderEntry getOrderEntryForFile(@NotNull VirtualFile fileOrDir) {
return getInfoForFileOrDirectory(fileOrDir).findOrderEntryWithOwnerModule(myModule);
return myDirectoryIndex.findOrderEntryWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule);
}
@Override
@@ -16,14 +16,9 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
/**
* @author nik
*/
@@ -53,22 +48,6 @@ class NonProjectDirectoryInfo extends DirectoryInfo {
return false;
}
@NotNull
@Override
public OrderEntry[] getOrderEntries() {
return OrderEntry.EMPTY_ARRAY;
}
@Nullable
OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) {
return null;
}
@NotNull
List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) {
return Collections.emptyList();
}
@Override
public String toString() {
return "DirectoryInfo: " + myDebugName;
@@ -118,9 +97,6 @@ class NonProjectDirectoryInfo extends DirectoryInfo {
return null;
}
void assertConsistency() {
}
public int getSourceRootTypeId() {
return 0;
}
@@ -95,7 +95,7 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
@Override
@NotNull
public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile file) {
return Arrays.asList(getInfoForFileOrDirectory(file).getOrderEntries());
return Arrays.asList(myDirectoryIndex.getOrderEntries(getInfoForFileOrDirectory(file)));
}
@Override
@@ -41,7 +41,15 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.*;
public class RootIndex extends DirectoryIndex {
public class RootIndex {
public static final Comparator<OrderEntry> BY_OWNER_MODULE = new Comparator<OrderEntry>() {
@Override
public int compare(OrderEntry o1, OrderEntry o2) {
String name1 = o1.getOwnerModule().getName();
String name2 = o2.getOwnerModule().getName();
return name1.compareTo(name2);
}
};
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.RootIndex");
private final Set<VirtualFile> myProjectExcludedRoots = ContainerUtil.newHashSet();
@@ -145,7 +153,6 @@ public class RootIndex extends DirectoryIndex {
}
}
}
}
}
}
@@ -171,7 +178,8 @@ public class RootIndex extends DirectoryIndex {
if (orderEntry instanceof ModuleOrderEntry) {
final Module depModule = ((ModuleOrderEntry)orderEntry).getModule();
if (depModule != null) {
VirtualFile[] importedClassRoots = OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots();
VirtualFile[] importedClassRoots =
OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots();
for (VirtualFile importedClassRoot : importedClassRoots) {
depEntries.putValue(importedClassRoot, orderEntry);
}
@@ -197,7 +205,9 @@ public class RootIndex extends DirectoryIndex {
Set<VirtualFile> allRoots = rootInfo.getAllRoots();
for (VirtualFile file : allRoots) {
List<VirtualFile> hierarchy = getHierarchy(file, allRoots, rootInfo);
result.put(file, hierarchy == null ? OrderEntry.EMPTY_ARRAY : calcOrderEntries(rootInfo, depEntries, libClassRootEntries, libSourceRootEntries, hierarchy));
result.put(file, hierarchy == null
? OrderEntry.EMPTY_ARRAY
: calcOrderEntries(rootInfo, depEntries, libClassRootEntries, libSourceRootEntries, hierarchy));
}
myOrderEntries = result;
return result;
@@ -211,7 +221,8 @@ public class RootIndex extends DirectoryIndex {
@Nullable VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false);
@Nullable VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true);
Set<OrderEntry> orderEntries = ContainerUtil.newLinkedHashSet();
orderEntries.addAll(info.getLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, libClassRootEntries, libSourceRootEntries));
orderEntries
.addAll(info.getLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, libClassRootEntries, libSourceRootEntries));
for (VirtualFile root : hierarchy) {
orderEntries.addAll(depEntries.get(root));
}
@@ -224,12 +235,11 @@ public class RootIndex extends DirectoryIndex {
}
OrderEntry[] array = orderEntries.toArray(new OrderEntry[orderEntries.size()]);
Arrays.sort(array, DirectoryInfoImpl.BY_OWNER_MODULE);
Arrays.sort(array, BY_OWNER_MODULE);
return array;
}
@Override
public void checkConsistency() {
for (VirtualFile file : myProjectExcludedRoots) {
assert file.exists() : file.getPath() + " does not exist";
@@ -247,21 +257,14 @@ public class RootIndex extends DirectoryIndex {
int id = myRootTypes.size();
if (id > DirectoryInfoImpl.MAX_ROOT_TYPE_ID) {
LOG.error("Too many different types of module source roots (" + id + ") registered: " + myRootTypes);
LOG.error("Too many different types of module source roots (" + id + ") registered: " + myRootTypes);
}
myRootTypes.add(rootType);
myRootTypeId.put(rootType, id);
return id;
}
@Override
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;
@@ -314,13 +317,12 @@ public class RootIndex extends DirectoryIndex {
return info;
}
@Override
@NotNull
public Query<VirtualFile> getDirectoriesByPackageName(@NotNull final String packageName, final boolean includeLibrarySources) {
List<VirtualFile> result = myDirectoriesByPackageNameCache.get(packageName);
if (result == null) {
result = ContainerUtil.newSmartList();
if (StringUtil.isNotEmpty(packageName) && !StringUtil.startsWithChar(packageName, '.')) {
int i = packageName.lastIndexOf('.');
while (true) {
@@ -361,7 +363,6 @@ public class RootIndex extends DirectoryIndex {
return new CollectionQuery<VirtualFile>(result);
}
@Override
@Nullable
public String getPackageName(@NotNull final VirtualFile dir) {
if (dir.isDirectory()) {
@@ -390,7 +391,6 @@ public class RootIndex extends DirectoryIndex {
return parentPackageName.isEmpty() ? subdirName : parentPackageName + "." + subdirName;
}
@Override
@Nullable
public JpsModuleSourceRootType<?> getSourceRootType(@NotNull DirectoryInfo directoryInfo) {
return myRootTypes.get(directoryInfo.getSourceRootTypeId());
@@ -497,8 +497,9 @@ public class RootIndex extends DirectoryIndex {
if (source && libraryOrSdkSources.contains(root) &&
(!sourceOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(sourceOfLibraries.get(root)))) {
return root;
} else if (!source && libraryOrSdkClasses.contains(root) &&
(!classOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(classOfLibraries.get(root)))) {
}
else if (!source && libraryOrSdkClasses.contains(root) &&
(!classOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(classOfLibraries.get(root)))) {
return root;
}
}
@@ -579,8 +580,11 @@ public class RootIndex extends DirectoryIndex {
}
}
@NotNull
private Pair<DirectoryInfo, String> calcDirectoryInfo(@NotNull final VirtualFile root, @NotNull final List<VirtualFile> hierarchy, @NotNull RootInfo info) {
private static Pair<DirectoryInfo, String> calcDirectoryInfo(@NotNull final VirtualFile root,
@NotNull final List<VirtualFile> hierarchy,
@NotNull RootInfo info) {
VirtualFile moduleContentRoot = info.findModuleRootInfo(hierarchy);
VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false);
VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true);
@@ -600,23 +604,26 @@ public class RootIndex extends DirectoryIndex {
int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0;
Module module = parentModuleForExcluded != null ? parentModuleForExcluded : info.contentRootOf.get(moduleContentRoot);
DirectoryInfo directoryInfo = new DirectoryInfoImpl(module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource,
parentModuleForExcluded != null, typeId) {
@NotNull
@Override
public OrderEntry[] getOrderEntries() {
OrderEntry[] entries = RootIndex.this.getOrderEntries().get(root);
return entries == null ? OrderEntry.EMPTY_ARRAY : entries;
}
};
DirectoryInfo directoryInfo =
new DirectoryInfoImpl(root, module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource,
parentModuleForExcluded != null, typeId);
String packagePrefix = info.calcPackagePrefix(root, hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot);
return Pair.create(directoryInfo, packagePrefix);
}
public interface InfoCache {
@Nullable DirectoryInfo getCachedInfo(@NotNull VirtualFile dir);
void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info);
@NotNull
public OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info) {
if (!(info instanceof DirectoryInfoImpl)) return OrderEntry.EMPTY_ARRAY;
OrderEntry[] entries = this.getOrderEntries().get(((DirectoryInfoImpl)info).getRoot());
return entries == null ? OrderEntry.EMPTY_ARRAY : entries;
}
}
public interface InfoCache {
@Nullable
DirectoryInfo getCachedInfo(@NotNull VirtualFile dir);
void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info);
}
}