/*
* Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan
*
* 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.goide.stubs.index;
import com.goide.runconfig.testing.GoTestFinder;
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.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.BitSet;
public class GoIdFilter extends IdFilter {
public static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultFileNavigationContributor");
private static final Key<CachedValue<IdFilter>> PRODUCTION_FILTER = Key.create("PRODUCTION");
private static final Key<CachedValue<IdFilter>> TESTS_FILTER = Key.create("TESTS");
private final BitSet myIdSet;
private GoIdFilter(@NotNull BitSet idSet) {
myIdSet = idSet;
}
@Override
public boolean containsFileId(int id) {
return id >= 0 && myIdSet.get(id);
}
public static IdFilter getProductionFilter(@NotNull Project project) {
return createIdFilter(project, PRODUCTION_FILTER, file -> !file.isDirectory() && !GoTestFinder.isTestFile(file));
}
public static IdFilter getTestsFilter(@NotNull Project project) {
return createIdFilter(project, TESTS_FILTER, file -> !file.isDirectory() && GoTestFinder.isTestFile(file));
}
private static IdFilter createIdFilter(@NotNull Project project,
@NotNull Key<CachedValue<IdFilter>> cacheKey,
@NotNull Condition<VirtualFile> filterCondition) {
return CachedValuesManager.getManager(project).getCachedValue(project, cacheKey, () -> {
BitSet bitSet = new BitSet();
ContentIterator iterator = fileOrDir -> {
if (filterCondition.value(fileOrDir)) {
addToBitSet(bitSet, fileOrDir);
}
ProgressManager.checkCanceled();
return true;
};
FileBasedIndex.getInstance().iterateIndexableFiles(iterator, project, null);
return CachedValueProvider.Result.create(new GoIdFilter(bitSet), ProjectRootManager.getInstance(project),
VirtualFileManager.VFS_STRUCTURE_MODIFICATIONS);
}, false);
}
@Nullable
public static IdFilter getFilesFilter(@NotNull GlobalSearchScope scope) {
if (scope instanceof GlobalSearchScope.FilesScope) {
BitSet bitSet = new BitSet();
for (VirtualFile file : (GlobalSearchScope.FilesScope)scope) {
addToBitSet(bitSet, file);
}
return new GoIdFilter(bitSet);
}
return null;
}
private static void addToBitSet(@NotNull BitSet set, @NotNull VirtualFile file) {
if (file instanceof VirtualFileWithId) {
int id = ((VirtualFileWithId)file).getId();
if (id < 0) id = -id; // workaround for encountering invalid files, see EA-49915, EA-50599
set.set(id);
}
}
}