Implementations of FileNameIndex & FileTypeIndex were hidden in order to have ability to modify them

This commit is contained in:
Maxim.Mossienko
2016-11-21 15:00:33 +01:00
parent ca4d506d9e
commit 30047ff895
8 changed files with 373 additions and 211 deletions
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2016 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.psi.search;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
interface FileNameIndexService {
Collection<VirtualFile> getVirtualFilesByName(Project project, String name, GlobalSearchScope scope, @Nullable IdFilter idFilter);
void processAllFileNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter);
Collection<VirtualFile> getFilesWithFileType(FileType type, GlobalSearchScope scope);
boolean processFilesWithFileType(FileType type, Processor<VirtualFile> processor, GlobalSearchScope scope);
}
@@ -15,135 +15,33 @@
*/
package com.intellij.psi.search;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.indexing.*;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.util.indexing.ID;
import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import static com.intellij.psi.search.FilenameIndex.getService;
/**
* @author Dmitry Avdeev
*/
public class FileTypeIndex extends ScalarIndexExtension<FileType>
implements FileBasedIndex.InputFilter, KeyDescriptor<FileType>, DataIndexer<FileType, Void, FileContent> {
public class FileTypeIndex {
@Deprecated
public static final ID<FileType, Void> NAME = ID.create("filetypes");
private final FileTypeRegistry myFileTypeManager;
public FileTypeIndex(FileTypeRegistry fileTypeRegistry) {
myFileTypeManager = fileTypeRegistry;
}
@NotNull
@Override
public ID<FileType, Void> getName() {
return NAME;
}
@NotNull
@Override
public DataIndexer<FileType, Void, FileContent> getIndexer() {
return this;
}
@NotNull
@Override
public KeyDescriptor<FileType> getKeyDescriptor() {
return this;
}
@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return this;
}
@Override
public boolean dependsOnFileContent() {
return false;
}
@Override
public int getVersion() {
FileType[] types = myFileTypeManager.getRegisteredFileTypes();
int version = 2;
for (FileType type : types) {
version += type.getName().hashCode();
}
version *= 31;
for (FileTypeRegistry.FileTypeDetector detector : Extensions.getExtensions(FileTypeRegistry.FileTypeDetector.EP_NAME)) {
version += detector.getVersion();
}
return version;
}
@Override
public boolean acceptInput(@NotNull VirtualFile file) {
return !file.isDirectory();
}
@Override
public void save(@NotNull DataOutput out, FileType value) throws IOException {
EnumeratorStringDescriptor.INSTANCE.save(out, value.getName());
}
@Override
public FileType read(@NotNull DataInput in) throws IOException {
String read = EnumeratorStringDescriptor.INSTANCE.read(in);
return myFileTypeManager.findFileTypeByName(read);
}
@Override
public int getHashCode(FileType value) {
return value.getName().hashCode();
}
@Override
public boolean isEqual(FileType val1, FileType val2) {
if (val1 instanceof SubstitutedFileType) val1 = ((SubstitutedFileType)val1).getOriginalFileType();
if (val2 instanceof SubstitutedFileType) val2 = ((SubstitutedFileType)val2).getOriginalFileType();
return Comparing.equal(val1, val2);
}
@NotNull
@Override
public Map<FileType, Void> map(@NotNull FileContent inputData) {
return Collections.singletonMap(inputData.getFileType(), null);
}
public static boolean containsFileOfType(@NotNull FileType type, @NotNull GlobalSearchScope scope) {
return !processFiles(type, file -> false, scope);
}
@NotNull
public static Collection<VirtualFile> getFiles(@NotNull FileType fileType, @NotNull GlobalSearchScope scope) {
return FileBasedIndex.getInstance().getContainingFiles(NAME, fileType, scope);
return getService().getFilesWithFileType(fileType, scope);
}
public static boolean processFiles(@NotNull FileType fileType, @NotNull Processor<VirtualFile> processor, GlobalSearchScope scope) {
return FileBasedIndex.getInstance().processValues(
NAME,
fileType,
null,
new FileBasedIndex.ValueProcessor<Void>() {
@Override
public boolean process(VirtualFile file, Void value) {
return processor.process(file);
}
}, scope);
public static boolean containsFileOfType(@NotNull FileType type, @NotNull GlobalSearchScope scope) {
return !getService().processFilesWithFileType(type, file -> false, scope);
}
public static boolean processFiles(@NotNull FileType fileType, @NotNull Processor<VirtualFile> processor, @NotNull GlobalSearchScope scope) {
return getService().processFilesWithFileType(fileType, processor, scope);
}
}
@@ -16,6 +16,7 @@
package com.intellij.psi.search;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
@@ -26,9 +27,8 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import com.intellij.util.Processors;
import com.intellij.util.SmartList;
import com.intellij.util.indexing.*;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.util.indexing.ID;
import com.intellij.util.indexing.IdFilter;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -39,65 +39,33 @@ import java.util.*;
/**
* @author yole
*/
public class FilenameIndex extends ScalarIndexExtension<String> {
@NonNls public static final ID<String, Void> NAME = ID.create("FilenameIndex");
private final MyDataIndexer myDataIndexer = new MyDataIndexer();
private final MyInputFilter myInputFilter = new MyInputFilter();
@NotNull
@Override
public ID<String,Void> getName() {
return NAME;
}
@NotNull
@Override
public DataIndexer<String, Void, FileContent> getIndexer() {
return myDataIndexer;
}
@NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return EnumeratorStringDescriptor.INSTANCE;
}
@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return myInputFilter;
}
@Override
public boolean dependsOnFileContent() {
return false;
}
@Override
public boolean indexDirectories() {
return true;
}
@Override
public int getVersion() {
return 1 + (FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping ? 2 : 0);
}
public class FilenameIndex {
@Deprecated
public @NonNls static final ID<String, Void> NAME = ID.create("FilenameIndex");
public static String[] getAllFilenames(Project project) {
final Collection<String> allKeys = FileBasedIndex.getInstance().getAllKeys(NAME, project);
return ArrayUtil.toStringArray(allKeys);
Set<String> names = new THashSet<>();
getService().processAllFileNames((String s) -> {
names.add(s);
return true;
}, project == null ? new EverythingGlobalScope() : GlobalSearchScope.allScope(project), null);
return ArrayUtil.toStringArray(names);
}
public static void processAllFileNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
getService().processAllFileNames(processor, scope, filter);
}
public static Collection<VirtualFile> getVirtualFilesByName(final Project project, final String name, final GlobalSearchScope scope) {
return FileBasedIndex.getInstance().getContainingFiles(NAME, name, scope);
return getService().getVirtualFilesByName(project, name, scope, null);
}
public static Collection<VirtualFile> getVirtualFilesByName(final Project project,
final String name,
public static Collection<VirtualFile> getVirtualFilesByName(final Project project,
final String name,
boolean caseSensitively,
final GlobalSearchScope scope) {
if (caseSensitively) return getVirtualFilesByName(project, name, scope);
return getVirtualFilesByNameIgnoringCase(name, scope, null);
return getVirtualFilesByNameIgnoringCase(name, scope, project, null);
}
public static PsiFile[] getFilesByName(final Project project, final String name, final GlobalSearchScope scope) {
@@ -112,7 +80,7 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
@Nullable IdFilter idFilter) {
return processFilesByName(name, includeDirs, true, processor, scope, project, idFilter);
}
public static boolean processFilesByName(@NotNull final String name,
boolean includeDirs,
boolean caseSensitively,
@@ -120,20 +88,13 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
@NotNull final GlobalSearchScope scope,
@NotNull final Project project,
@Nullable IdFilter idFilter) {
final Set<VirtualFile> files;
final Collection<VirtualFile> files;
if (caseSensitively) {
files = new THashSet<>();
FileBasedIndex.getInstance().processValues(NAME, name, null, new FileBasedIndex.ValueProcessor<Void>() {
@Override
public boolean process(final VirtualFile file, final Void value) {
files.add(file);
return true;
}
}, scope, idFilter);
files = getService().getVirtualFilesByName(project, name, scope, idFilter);
}
else {
files = getVirtualFilesByNameIgnoringCase(name, scope, idFilter);
files = getVirtualFilesByNameIgnoringCase(name, scope, project, idFilter);
}
if (files.isEmpty()) return false;
@@ -162,28 +123,29 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
@NotNull
private static Set<VirtualFile> getVirtualFilesByNameIgnoringCase(@NotNull final String name,
@NotNull final GlobalSearchScope scope,
@NotNull Project project,
@Nullable final IdFilter idFilter) {
final Set<String> keys = new THashSet<>();
final FileBasedIndex index = FileBasedIndex.getInstance();
index.processAllKeys(NAME, value -> {
FileNameIndexService fileNameIndexService = getService();
fileNameIndexService.processAllFileNames(value -> {
if (name.equalsIgnoreCase(value)) {
keys.add(value);
}
return true;
}, scope, idFilter);
// values accessed outside of provessAllKeys
// values accessed outside of provessAllKeys
final Set<VirtualFile> files = new THashSet<>();
for (String each : keys) {
files.addAll(index.getContainingFiles(NAME, each, scope));
files.addAll(fileNameIndexService.getVirtualFilesByName(project, each, scope, idFilter));
}
return files;
}
public static PsiFileSystemItem[] getFilesByName(final Project project,
final String name,
@NotNull final GlobalSearchScope scope,
boolean includeDirs) {
final String name,
@NotNull final GlobalSearchScope scope,
boolean includeDirs) {
SmartList<PsiFileSystemItem> result = new SmartList<>();
Processor<PsiFileSystemItem> processor = Processors.cancelableCollectProcessor(result);
processFilesByName(name, includeDirs, processor, scope, project, null);
@@ -195,25 +157,6 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
return result.toArray(new PsiFile[result.size()]);
}
public static void processAllFileNames(@NotNull Processor<String> processor, @NotNull GlobalSearchScope scope, @NotNull IdFilter filter) {
FileBasedIndex.getInstance().processAllKeys(NAME, processor, scope, filter);
}
private static class MyDataIndexer implements DataIndexer<String, Void, FileContent> {
@Override
@NotNull
public Map<String, Void> map(@NotNull final FileContent inputData) {
return Collections.singletonMap(inputData.getFileName(), null);
}
}
private static class MyInputFilter implements FileBasedIndex.InputFilter {
@Override
public boolean acceptInput(@NotNull final VirtualFile file) {
return true;
}
}
/**
* Returns all files in the project by extension
* @author Konstantin Bulenkov
@@ -224,7 +167,7 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
*/
@NotNull
public static Collection<VirtualFile> getAllFilesByExt(@NotNull Project project, @NotNull String ext) {
return getAllFilesByExt(project, ext, GlobalSearchScope.allScope(project));
return getAllFilesByExt(project, ext, GlobalSearchScope.allScope(project));
}
@NotNull
@@ -246,8 +189,7 @@ public class FilenameIndex extends ScalarIndexExtension<String> {
return files;
}
@Override
public boolean traceKeyHashToVirtualFileMapping() {
return FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
static FileNameIndexService getService() {
return ServiceManager.getService(FileNameIndexService.class);
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2000-2016 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.psi.search;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.indexing.IdFilter;
import gnu.trove.THashSet;
import java.util.Collection;
import java.util.Set;
public class FileNameIndexServiceImpl implements FileNameIndexService {
@Override
public Collection<VirtualFile> getVirtualFilesByName(Project project, String name, GlobalSearchScope scope, IdFilter filter) {
final Set<VirtualFile> files = new THashSet<VirtualFile>();
FileBasedIndex.getInstance().processValues(FilenameIndexImpl.NAME, name, null, (file, value) -> {
files.add(file);
return true;
}, scope, filter);
return files;
}
@Override
public void processAllFileNames(Processor<String> processor, GlobalSearchScope scope, IdFilter filter) {
final FileBasedIndex index = FileBasedIndex.getInstance();
index.processAllKeys(FilenameIndexImpl.NAME, processor, scope, filter);
}
@Override
public Collection<VirtualFile> getFilesWithFileType(FileType fileType, GlobalSearchScope scope) {
return FileBasedIndex.getInstance().getContainingFiles(FileTypeIndexImpl.NAME, fileType, scope);
}
@Override
public boolean processFilesWithFileType(FileType fileType, Processor<VirtualFile> processor, GlobalSearchScope scope) {
return FileBasedIndex.getInstance().processValues(
FileTypeIndexImpl.NAME,
fileType,
null,
(file, value) -> processor.process(file), scope);
}
}
@@ -0,0 +1,140 @@
/*
* Copyright 2000-2016 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.psi.search;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.indexing.*;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
public class FileTypeIndexImpl extends ScalarIndexExtension<FileType>
implements FileBasedIndex.InputFilter, KeyDescriptor<FileType>, DataIndexer<FileType, Void, FileContent> {
static final ID<FileType, Void> NAME = FileTypeIndex.NAME;
private final FileTypeRegistry myFileTypeManager;
public FileTypeIndexImpl(FileTypeRegistry fileTypeRegistry) {
myFileTypeManager = fileTypeRegistry;
}
@NotNull
@Override
public ID<FileType, Void> getName() {
return NAME;
}
@NotNull
@Override
public DataIndexer<FileType, Void, FileContent> getIndexer() {
return this;
}
@NotNull
@Override
public KeyDescriptor<FileType> getKeyDescriptor() {
return this;
}
@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return this;
}
@Override
public boolean dependsOnFileContent() {
return false;
}
@Override
public int getVersion() {
FileType[] types = myFileTypeManager.getRegisteredFileTypes();
int version = 2;
for (FileType type : types) {
version += type.getName().hashCode();
}
version *= 31;
for (FileTypeRegistry.FileTypeDetector detector : Extensions.getExtensions(FileTypeRegistry.FileTypeDetector.EP_NAME)) {
version += detector.getVersion();
}
return version;
}
@Override
public boolean acceptInput(@NotNull VirtualFile file) {
return !file.isDirectory();
}
@Override
public void save(@NotNull DataOutput out, FileType value) throws IOException {
EnumeratorStringDescriptor.INSTANCE.save(out, value.getName());
}
@Override
public FileType read(@NotNull DataInput in) throws IOException {
String read = EnumeratorStringDescriptor.INSTANCE.read(in);
return myFileTypeManager.findFileTypeByName(read);
}
@Override
public int getHashCode(FileType value) {
return value.getName().hashCode();
}
@Override
public boolean isEqual(FileType val1, FileType val2) {
if (val1 instanceof SubstitutedFileType) val1 = ((SubstitutedFileType)val1).getOriginalFileType();
if (val2 instanceof SubstitutedFileType) val2 = ((SubstitutedFileType)val2).getOriginalFileType();
return Comparing.equal(val1, val2);
}
@NotNull
@Override
public Map<FileType, Void> map(@NotNull FileContent inputData) {
return Collections.singletonMap(inputData.getFileType(), null);
}
public static boolean containsFileOfType(@NotNull FileType type, @NotNull GlobalSearchScope scope) {
return !processFiles(type, file -> false, scope);
}
@NotNull
public static Collection<VirtualFile> getFiles(@NotNull FileType fileType, @NotNull GlobalSearchScope scope) {
return FileBasedIndex.getInstance().getContainingFiles(NAME, fileType, scope);
}
public static boolean processFiles(@NotNull FileType fileType, @NotNull Processor<VirtualFile> processor, GlobalSearchScope scope) {
return FileBasedIndex.getInstance().processValues(
NAME,
fileType,
null,
(file, value) -> processor.process(file), scope);
}
}
@@ -0,0 +1,86 @@
/*
* Copyright 2000-2016 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.psi.search;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
import com.intellij.util.indexing.*;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.KeyDescriptor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Map;
public class FilenameIndexImpl extends ScalarIndexExtension<String> {
@NonNls static final ID<String, Void> NAME = FilenameIndex.NAME;
@NotNull
@Override
public ID<String,Void> getName() {
return NAME;
}
@NotNull
@Override
public DataIndexer<String, Void, FileContent> getIndexer() {
return new DataIndexer<String, Void, FileContent>() {
@NotNull
@Override
public Map<String, Void> map(@NotNull FileContent inputData) {
return Collections.singletonMap(inputData.getFileName(), null);
}
};
}
@NotNull
@Override
public KeyDescriptor<String> getKeyDescriptor() {
return EnumeratorStringDescriptor.INSTANCE;
}
@NotNull
@Override
public FileBasedIndex.InputFilter getInputFilter() {
return new FileBasedIndex.InputFilter() {
@Override
public boolean acceptInput(@NotNull final VirtualFile file) {
return file instanceof VirtualFileSystemEntry;
}
};
}
@Override
public boolean dependsOnFileContent() {
return false;
}
@Override
public boolean indexDirectories() {
return true;
}
@Override
public int getVersion() {
return 2 + (FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping ? 1 : 0);
}
@Override
public boolean traceKeyHashToVirtualFileMapping() {
return FileBasedIndex.ourEnableTracingOfKeyHashToVirtualFileMapping;
}
}
@@ -502,8 +502,10 @@
<internalFileTemplate name="XHTML File"/>
<fileBasedIndex implementation="com.intellij.psi.impl.cache.impl.todo.TodoIndex"/>
<fileBasedIndex implementation="com.intellij.psi.impl.cache.impl.id.IdIndexImpl"/>
<fileBasedIndex implementation="com.intellij.psi.search.FilenameIndex"/>
<fileBasedIndex implementation="com.intellij.psi.search.FileTypeIndex"/>
<fileBasedIndex implementation="com.intellij.psi.search.FilenameIndexImpl"/>
<applicationService serviceInterface="com.intellij.psi.search.FileNameIndexService"
serviceImplementation="com.intellij.psi.search.FileNameIndexServiceImpl"/>
<fileBasedIndex implementation="com.intellij.psi.search.FileTypeIndexImpl"/>
<fileBasedIndex implementation="com.intellij.psi.stubs.StubUpdatingIndex"/>
<fileBasedIndex implementation="com.intellij.find.ngrams.TrigramIndex"/>
@@ -20,7 +20,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.ex.FakeFileType;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.FileTypeIndexImpl;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
@@ -53,7 +53,7 @@ public class FileTypeIndexTest extends LightPlatformCodeInsightFixtureTestCase {
return "";
}
};
FileTypeIndex index = new FileTypeIndex(FileTypeManager.getInstance());
FileTypeIndexImpl index = new FileTypeIndexImpl(FileTypeManager.getInstance());
int version = index.getVersion();
try {