blob: aec6e11a6d15c31f99f3cd8b5d9bb749063bbf14 [file] [log] [blame]
/*
* Copyright 2000-2012 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.injected.editor.VirtualFileWindow;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.ProjectFileIndex;
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;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIndex {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.ProjectFileIndexImpl");
private final Project myProject;
private final ContentFilter myContentFilter;
public ProjectFileIndexImpl(@NotNull Project project, @NotNull DirectoryIndex directoryIndex, @NotNull FileTypeRegistry fileTypeManager) {
super(directoryIndex, fileTypeManager, project);
myProject = project;
myContentFilter = new ContentFilter();
}
@Override
public boolean iterateContent(@NotNull ContentIterator iterator) {
Module[] modules = ModuleManager.getInstance(myProject).getModules();
for (Module module : modules) {
if (module.isDisposed()) continue;
VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
for (VirtualFile contentRoot : contentRoots) {
DirectoryInfo info = getInfoForFileOrDirectory(contentRoot);
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.isInProject() && parentInfo.getModule() != null) continue; // inner content - skip it
}
boolean finished = VfsUtilCore.iterateChildrenRecursively(contentRoot, myContentFilter, iterator);
if (!finished) return false;
}
}
return true;
}
@Override
public boolean iterateContentUnderDirectory(@NotNull VirtualFile dir, @NotNull ContentIterator iterator) {
return VfsUtilCore.iterateChildrenRecursively(dir, myContentFilter, iterator);
}
@Override
public boolean isExcluded(@NotNull VirtualFile file) {
DirectoryInfo info = getInfoForFileOrDirectory(file);
return info.isIgnored() || info.isExcluded();
}
@Override
public boolean isUnderIgnored(@NotNull VirtualFile file) {
return getInfoForFileOrDirectory(file).isIgnored();
}
@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() || !honorExclusion && info.isExcluded()) {
return info.getModule();
}
return null;
}
@Override
@NotNull
public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile file) {
return Arrays.asList(myDirectoryIndex.getOrderEntries(getInfoForFileOrDirectory(file)));
}
@Override
public VirtualFile getClassRootForFile(@NotNull VirtualFile file) {
final DirectoryInfo info = getInfoForFileOrDirectory(file);
if (!info.isInProject()) return null;
return info.getLibraryClassRoot();
}
@Override
public VirtualFile getSourceRootForFile(@NotNull VirtualFile file) {
final DirectoryInfo info = getInfoForFileOrDirectory(file);
if (!info.isInProject()) return null;
return info.getSourceRoot();
}
@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() || !honorExclusion && info.isExcluded()) {
return info.getContentRoot();
}
return null;
}
@Override
public String getPackageNameByDirectory(@NotNull VirtualFile dir) {
LOG.assertTrue(dir.isDirectory());
return myDirectoryIndex.getPackageName(dir);
}
@Override
public boolean isLibraryClassFile(@NotNull VirtualFile file) {
if (file.isDirectory()) return false;
DirectoryInfo parentInfo = getInfoForFileOrDirectory(file);
return parentInfo.isInProject() && parentInfo.hasLibraryClassRoot();
}
@Override
public boolean isInSource(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info.isInModuleSource() || info.isInLibrarySource();
}
@Override
public boolean isInLibraryClasses(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info.isInProject() && info.hasLibraryClassRoot();
}
@Override
public boolean isInLibrarySource(@NotNull VirtualFile fileOrDir) {
return getInfoForFileOrDirectory(fileOrDir).isInLibrarySource();
}
@Override
public boolean isIgnored(@NotNull VirtualFile file) {
return isExcluded(file);
}
@Override
public boolean isInContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
return info.isInProject() && info.getModule() != null;
}
@Override
public boolean isInSourceContent(@NotNull VirtualFile fileOrDir) {
return getInfoForFileOrDirectory(fileOrDir).isInModuleSource();
}
@Override
public boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir) {
DirectoryInfo info = getInfoForFileOrDirectory(fileOrDir);
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.isInModuleSource() && rootTypes.contains(myDirectoryIndex.getSourceRootType(info));
}
private class ContentFilter implements VirtualFileFilter {
@Override
public boolean accept(@NotNull VirtualFile file) {
DirectoryInfo info = getInfoForFileOrDirectory(file);
if (!info.isInProject() || info.getModule() == null) return false;
if (file.isDirectory()) {
return true;
}
else {
return !myFileTypeRegistry.isFileIgnored(file);
}
}
}
}