diff options
Diffstat (limited to 'platform/projectModel-impl')
4 files changed, 132 insertions, 29 deletions
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java index e87d3c749b10..70eb213d86c8 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java @@ -17,7 +17,6 @@ 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; @@ -26,8 +25,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; 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"; @@ -65,10 +62,4 @@ public abstract class DirectoryIndex { @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); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java index 8140a3c15211..eb8a9ddf5587 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java @@ -18,17 +18,18 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.fileTypes.FileTypeRegistry; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ContentIterator; -import com.intellij.openapi.roots.ModuleFileIndex; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; 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; @@ -79,12 +80,12 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde @Override @NotNull public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile fileOrDir) { - return myDirectoryIndex.findAllOrderEntriesWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule); + return findAllOrderEntriesWithOwnerModule(myModule, myDirectoryIndex.getOrderEntries(getInfoForFileOrDirectory(fileOrDir))); } @Override public OrderEntry getOrderEntryForFile(@NotNull VirtualFile fileOrDir) { - return myDirectoryIndex.findOrderEntryWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule); + return findOrderEntryWithOwnerModule(myModule, myDirectoryIndex.getOrderEntries(getInfoForFileOrDirectory(fileOrDir))); } @Override @@ -100,6 +101,97 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde return info.isInModuleSource() && myModule.equals(info.getModule()) && rootTypes.contains(myDirectoryIndex.getSourceRootType(info)); } + @Nullable + static OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule, @NotNull OrderEntry[] orderEntries) { + if (orderEntries.length < 10) { + for (OrderEntry entry : orderEntries) { + if (entry.getOwnerModule() == ownerModule) return entry; + } + return null; + } + int index = Arrays.binarySearch(orderEntries, new FakeOrderEntry(ownerModule), RootIndex.BY_OWNER_MODULE); + return index < 0 ? null : orderEntries[index]; + } + + @NotNull + private static List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule, @NotNull OrderEntry[] entries) { + 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, new FakeOrderEntry(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); + } + + private static class FakeOrderEntry implements OrderEntry { + private final Module myOwnerModule; + + public FakeOrderEntry(Module ownerModule) { + myOwnerModule = ownerModule; + } + + @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 myOwnerModule; + } + + @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(); + } + } + private class ContentFilter implements VirtualFileFilter { @Override public boolean accept(@NotNull VirtualFile file) { diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java index e2417193149e..aec6e11a6d15 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java @@ -30,6 +30,7 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import org.jetbrains.jps.model.module.JpsModuleSourceRootType; @@ -91,10 +92,18 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn @Override public Module getModuleForFile(@NotNull VirtualFile file) { + return getModuleForFile(file, true); + } + + @Nullable + @Override + public Module getModuleForFile(@NotNull VirtualFile file, boolean honorExclusion) { if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate(); DirectoryInfo info = getInfoForFileOrDirectory(file); - if (!info.isInProject()) return null; - return info.getModule(); + if (info.isInProject() || !honorExclusion && info.isExcluded()) { + return info.getModule(); + } + return null; } @Override @@ -119,9 +128,16 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn @Override public VirtualFile getContentRootForFile(@NotNull VirtualFile file) { + return getContentRootForFile(file, true); + } + + @Override + public VirtualFile getContentRootForFile(@NotNull VirtualFile file, final boolean honorExclusion) { final DirectoryInfo info = getInfoForFileOrDirectory(file); - if (!info.isInProject()) return null; - return info.getContentRoot(); + if (info.isInProject() || !honorExclusion && info.isExcluded()) { + return info.getContentRoot(); + } + return null; } @Override diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index eb04fb6c103e..bc85dabc9aec 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -497,10 +497,11 @@ public class RootIndex { } @Nullable - private Module findParentModuleForExcluded(@NotNull List<VirtualFile> hierarchy) { + private VirtualFile findNearestContentRootForExcluded(@NotNull List<VirtualFile> hierarchy) { for (VirtualFile root : hierarchy) { - Module module = contentRootOf.get(root); - if (module != null) return module; + if (contentRootOf.containsKey(root)) { + return root; + } } return null; } @@ -604,10 +605,14 @@ public class RootIndex { 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) { - parentModuleForExcluded = info.findParentModuleForExcluded(hierarchy); - if (parentModuleForExcluded == null) { + boolean inProject = moduleContentRoot != null || libraryClassRoot != null || librarySourceRoot != null; + VirtualFile nearestContentRoot; + if (inProject) { + nearestContentRoot = moduleContentRoot; + } + else { + nearestContentRoot = info.findNearestContentRootForExcluded(hierarchy); + if (nearestContentRoot == null) { return new Pair<DirectoryInfo, String>(NonProjectDirectoryInfo.EXCLUDED, null); } } @@ -619,10 +624,9 @@ public class RootIndex { boolean inLibrarySource = librarySourceRoot != null; int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0; - Module module = parentModuleForExcluded != null ? parentModuleForExcluded : info.contentRootOf.get(moduleContentRoot); + Module module = info.contentRootOf.get(nearestContentRoot); DirectoryInfo directoryInfo = - new DirectoryInfoImpl(root, module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource, - parentModuleForExcluded != null, typeId); + new DirectoryInfoImpl(root, module, nearestContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource, !inProject, typeId); String packagePrefix = info.calcPackagePrefix(root, hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot); |