mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
JspFileIndex refactored to use FBI
This commit is contained in:
@@ -35,7 +35,7 @@ public abstract class JspContextManager {
|
||||
|
||||
public abstract BaseJspFile[] getSuitableContextFiles(@NotNull PsiFile file);
|
||||
|
||||
public abstract void setContextFile(@NotNull PsiFile file, @Nullable BaseJspFile contextFile, final boolean userDefined);
|
||||
public abstract void setContextFile(@NotNull PsiFile file, @Nullable BaseJspFile contextFile);
|
||||
|
||||
public abstract @Nullable
|
||||
BaseJspFile getContextFile(@NotNull PsiFile file);
|
||||
|
||||
@@ -35,16 +35,12 @@ public class FileIncludeInfo {
|
||||
this.runtimeOnly = runtimeOnly;
|
||||
}
|
||||
|
||||
public FileIncludeInfo(@NotNull String fileName, @NotNull String path, int offset) {
|
||||
this(fileName, path, offset, false);
|
||||
}
|
||||
|
||||
public FileIncludeInfo(@NotNull String fileName, @NotNull String path) {
|
||||
this(fileName, path, -1, false);
|
||||
public FileIncludeInfo(@NotNull String path, int offset) {
|
||||
this(getFileName(path), path, offset, false);
|
||||
}
|
||||
|
||||
public FileIncludeInfo(@NotNull String path) {
|
||||
this(getFileName(path), path, -1, false);
|
||||
this(path, -1);
|
||||
}
|
||||
|
||||
private static String getFileName(String path) {
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.intellij.psi.impl.include;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -36,6 +38,8 @@ public abstract class FileIncludeManager {
|
||||
|
||||
public abstract VirtualFile[] getIncludingFiles(VirtualFile file, boolean compileTimeOnly);
|
||||
|
||||
public abstract void processIncludingFiles(PsiFile context, Processor<Pair<VirtualFile, FileIncludeInfo>> processor);
|
||||
|
||||
@Nullable
|
||||
public abstract PsiFileSystemItem resolveFileReference(String text, PsiFile context);
|
||||
public abstract PsiFileSystemItem resolveFileInclude(FileIncludeInfo info, PsiFile context);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public class FileIncludeIndex extends FileBasedIndexExtension<FileIncludeIndex.K
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
interface Key {
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.intellij.psi.impl.include;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
@@ -26,7 +28,7 @@ class FileIncludeInfoImpl extends FileIncludeInfo {
|
||||
public final String providerId;
|
||||
|
||||
public FileIncludeInfoImpl(@NotNull String path, int offset, boolean runtimeOnly, String providerId) {
|
||||
super("", path, offset, runtimeOnly);
|
||||
super(new File(path).getName(), path, offset, runtimeOnly);
|
||||
this.providerId = providerId;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.intellij.psi.impl.include;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
@@ -34,12 +35,11 @@ import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.ParameterizedCachedValue;
|
||||
import com.intellij.psi.util.ParameterizedCachedValueProvider;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
@@ -54,46 +54,68 @@ public class FileIncludeManagerImpl extends FileIncludeManager {
|
||||
|
||||
private final IncludeCacheHolder myIncludedHolder = new IncludeCacheHolder("compile time includes", "runtime includes") {
|
||||
@Override
|
||||
protected VirtualFile[] computeFiles(PsiFile file, boolean compileTimeOnly) {
|
||||
GlobalSearchScope scope = GlobalSearchScope.allScope(myProject);
|
||||
List<FileIncludeInfoImpl> infoList = FileIncludeIndex.getIncludes(file.getVirtualFile(), scope);
|
||||
ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
|
||||
for (FileIncludeInfoImpl info : infoList) {
|
||||
if (compileTimeOnly && info.runtimeOnly) {
|
||||
continue;
|
||||
}
|
||||
FileIncludeProvider includeProvider = myProviderMap.get(info.providerId);
|
||||
if (includeProvider != null) {
|
||||
PsiFileSystemItem virtualFile = includeProvider.resolveInclude(info, file, myProject);
|
||||
if (virtualFile != null) {
|
||||
files.add(virtualFile.getVirtualFile());
|
||||
protected VirtualFile[] computeFiles(final PsiFile file, final boolean compileTimeOnly) {
|
||||
final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
|
||||
processIncludes(file, new Processor<FileIncludeInfo>() {
|
||||
@Override
|
||||
public boolean process(FileIncludeInfo info) {
|
||||
if (compileTimeOnly != info.runtimeOnly) {
|
||||
PsiFileSystemItem virtualFile = resolveFileInclude(info, file);
|
||||
if (virtualFile != null) {
|
||||
files.add(virtualFile.getVirtualFile());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
return files.toArray(new VirtualFile[files.size()]);
|
||||
}
|
||||
};
|
||||
|
||||
public void processIncludes(PsiFile file, Processor<FileIncludeInfo> processor) {
|
||||
GlobalSearchScope scope = GlobalSearchScope.allScope(myProject);
|
||||
List<FileIncludeInfoImpl> infoList = FileIncludeIndex.getIncludes(file.getVirtualFile(), scope);
|
||||
for (FileIncludeInfoImpl info : infoList) {
|
||||
if (!processor.process(info)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final IncludeCacheHolder myIncludingHolder = new IncludeCacheHolder("compile time contexts", "runtime contexts") {
|
||||
@Override
|
||||
protected VirtualFile[] computeFiles(PsiFile context, boolean compileTimeOnly) {
|
||||
final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
|
||||
processIncludingFiles(context, new Processor<Pair<VirtualFile, FileIncludeInfo>>() {
|
||||
@Override
|
||||
public boolean process(Pair<VirtualFile, FileIncludeInfo> virtualFileFileIncludeInfoPair) {
|
||||
files.add(virtualFileFileIncludeInfoPair.first);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return VfsUtil.toVirtualFileArray(files);
|
||||
}
|
||||
};
|
||||
|
||||
private final IncludeCacheHolder myIncludingHolder = new IncludeCacheHolder("compile time contexts", "runtime contexts") {
|
||||
@Override
|
||||
protected VirtualFile[] computeFiles(PsiFile file, boolean compileTimeOnly) {
|
||||
MultiMap<VirtualFile,FileIncludeInfoImpl> infoList = FileIncludeIndex.getIncludingFileCandidates(file.getName(), GlobalSearchScope.allScope(myProject));
|
||||
ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
|
||||
for (VirtualFile candidate : infoList.keySet()) {
|
||||
PsiFile psiFile = myPsiManager.findFile(candidate);
|
||||
if (psiFile == null) continue;
|
||||
for (FileIncludeInfoImpl info : infoList.get(candidate)) {
|
||||
FileIncludeProvider includeProvider = myProviderMap.get(info.providerId);
|
||||
if (includeProvider != null) {
|
||||
if (file.equals(includeProvider.resolveInclude(info, psiFile, myProject))) {
|
||||
files.add(candidate);
|
||||
}
|
||||
public void processIncludingFiles(PsiFile context, Processor<Pair<VirtualFile, FileIncludeInfo>> processor) {
|
||||
context = context.getOriginalFile();
|
||||
VirtualFile contextFile = context.getVirtualFile();
|
||||
if (contextFile == null) return;
|
||||
MultiMap<VirtualFile,FileIncludeInfoImpl> infoList = FileIncludeIndex.getIncludingFileCandidates(context.getName(), GlobalSearchScope.allScope(myProject));
|
||||
for (VirtualFile candidate : infoList.keySet()) {
|
||||
PsiFile psiFile = myPsiManager.findFile(candidate);
|
||||
if (psiFile == null || context.equals(psiFile)) continue;
|
||||
for (FileIncludeInfo info : infoList.get(candidate)) {
|
||||
PsiFileSystemItem item = resolveFileInclude(info, psiFile);
|
||||
if (item != null && contextFile.equals(item.getVirtualFile())) {
|
||||
if (!processor.process(Pair.create(candidate, info))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return VfsUtil.toVirtualFileArray(files);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public FileIncludeManagerImpl(Project project, PsiManager psiManager, PsiFileFactory psiFileFactory,
|
||||
CachedValuesManager cachedValuesManager) {
|
||||
@@ -120,19 +142,23 @@ public class FileIncludeManagerImpl extends FileIncludeManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VirtualFile[] getIncludingFiles(VirtualFile file, boolean compileTimeOnly) {
|
||||
return myIncludingHolder.getAllFiles(file, compileTimeOnly);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFileSystemItem resolveFileReference(String text, PsiFile context) {
|
||||
|
||||
PsiFileImpl psiFile = (PsiFileImpl)myPsiFileFactory.createFileFromText("dummy.txt", text);
|
||||
public PsiFileSystemItem resolveFileInclude(FileIncludeInfo info, PsiFile context) {
|
||||
|
||||
PsiFileImpl psiFile = (PsiFileImpl)myPsiFileFactory.createFileFromText("dummy.txt", info.path);
|
||||
psiFile.setOriginalFile(context);
|
||||
|
||||
return new FileReferenceSet(psiFile).resolve();
|
||||
return new FileReferenceSet(psiFile) {
|
||||
@Override
|
||||
protected boolean useIncludingFileAsContext() {
|
||||
return false;
|
||||
}
|
||||
}.resolve();
|
||||
}
|
||||
|
||||
private abstract class IncludeCacheHolder {
|
||||
@@ -140,14 +166,14 @@ public class FileIncludeManagerImpl extends FileIncludeManager {
|
||||
private final Key<ParameterizedCachedValue<VirtualFile[], PsiFile>> COMPILE_TIME_KEY;
|
||||
private final Key<ParameterizedCachedValue<VirtualFile[], PsiFile>> RUNTIME_KEY;
|
||||
|
||||
private final ParameterizedCachedValueProvider<VirtualFile[], PsiFile> COMPILE_TIME_PROVIDER = new IncludedFilesProvider(false) {
|
||||
private final ParameterizedCachedValueProvider<VirtualFile[], PsiFile> COMPILE_TIME_PROVIDER = new IncludedFilesProvider(true) {
|
||||
@Override
|
||||
protected VirtualFile[] computeFiles(PsiFile file, boolean compileTimeOnly) {
|
||||
return IncludeCacheHolder.this.computeFiles(file, compileTimeOnly);
|
||||
}
|
||||
};
|
||||
|
||||
private final ParameterizedCachedValueProvider<VirtualFile[], PsiFile> RUNTIME_PROVIDER = new IncludedFilesProvider(true) {
|
||||
private final ParameterizedCachedValueProvider<VirtualFile[], PsiFile> RUNTIME_PROVIDER = new IncludedFilesProvider(false) {
|
||||
@Override
|
||||
protected VirtualFile[] computeFiles(PsiFile file, boolean compileTimeOnly) {
|
||||
return IncludeCacheHolder.this.computeFiles(file, compileTimeOnly);
|
||||
@@ -160,36 +186,20 @@ public class FileIncludeManagerImpl extends FileIncludeManager {
|
||||
}
|
||||
|
||||
public VirtualFile[] getAllFiles(VirtualFile file, boolean compileTimeOnly) {
|
||||
ArrayList<VirtualFile[]> result = new ArrayList<VirtualFile[]>();
|
||||
Set<VirtualFile> result = new HashSet<VirtualFile>();
|
||||
getFilesRecursively(file, compileTimeOnly, result);
|
||||
switch (result.size()) {
|
||||
case 0:
|
||||
return VirtualFile.EMPTY_ARRAY;
|
||||
case 1:
|
||||
return result.get(0);
|
||||
default:
|
||||
int size = 0;
|
||||
for (VirtualFile[] files : result) {
|
||||
size+=files.length;
|
||||
}
|
||||
VirtualFile[] files = new VirtualFile[size];
|
||||
int pos = 0;
|
||||
for (VirtualFile[] virtualFiles : result) {
|
||||
System.arraycopy(virtualFiles, 0, files, pos, virtualFiles.length);
|
||||
pos += virtualFiles.length;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
return result.toArray(new VirtualFile[result.size()]);
|
||||
}
|
||||
|
||||
private void getFilesRecursively(VirtualFile file, boolean compileTimeOnly, List<VirtualFile[]> result) {
|
||||
private void getFilesRecursively(VirtualFile file, boolean compileTimeOnly, Set<VirtualFile> result) {
|
||||
if (result.contains(file)) return;
|
||||
PsiFile psiFile = myPsiManager.findFile(file);
|
||||
if (psiFile == null) return;
|
||||
VirtualFile[] includes = compileTimeOnly
|
||||
? myCachedValuesManager.getParameterizedCachedValue(psiFile, COMPILE_TIME_KEY, COMPILE_TIME_PROVIDER, false, psiFile)
|
||||
: myCachedValuesManager.getParameterizedCachedValue(psiFile, RUNTIME_KEY, RUNTIME_PROVIDER, false, psiFile);
|
||||
if (includes.length != 0) {
|
||||
result.add(includes);
|
||||
result.addAll(Arrays.asList(includes));
|
||||
for (VirtualFile include : includes) {
|
||||
getFilesRecursively(include, compileTimeOnly, result);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,9 @@
|
||||
package com.intellij.psi.impl.include;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.util.indexing.FileContent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
@@ -39,9 +35,4 @@ public abstract class FileIncludeProvider {
|
||||
|
||||
@NotNull
|
||||
public abstract FileIncludeInfo[] getIncludeInfos(FileContent content);
|
||||
|
||||
@Nullable
|
||||
public PsiFileSystemItem resolveInclude(FileIncludeInfo include, PsiFile context, Project project) {
|
||||
return FileIncludeManager.getManager(project).resolveFileReference(include.path, context);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-18
@@ -22,15 +22,10 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.util.CachedValue;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -46,7 +41,6 @@ public class FileReferenceSet {
|
||||
private static final FileType[] EMPTY_FILE_TYPES = {};
|
||||
private static final char SEPARATOR = '/';
|
||||
private static final String SEPARATOR_STRING = "/";
|
||||
private static final Key<CachedValue<Collection<PsiFileSystemItem>>> DEFAULT_CONTEXTS_KEY = new Key<CachedValue<Collection<PsiFileSystemItem>>>("default file contexts");
|
||||
public static final CustomizableReferenceProvider.CustomizationKey<Function<PsiFile, Collection<PsiFileSystemItem>>> DEFAULT_PATH_EVALUATOR_OPTION =
|
||||
new CustomizableReferenceProvider.CustomizationKey<Function<PsiFile, Collection<PsiFileSystemItem>>>(PsiBundle.message("default.path.evaluator.option"));
|
||||
public static final Function<PsiFile, Collection<PsiFileSystemItem>> ABSOLUTE_TOP_LEVEL = new Function<PsiFile, Collection<PsiFileSystemItem>>() {
|
||||
@@ -262,17 +256,7 @@ public class FileReferenceSet {
|
||||
return getAbsoluteTopLevelDirLocations(file);
|
||||
}
|
||||
|
||||
final CachedValueProvider<Collection<PsiFileSystemItem>> myDefaultContextProvider = new CachedValueProvider<Collection<PsiFileSystemItem>>() {
|
||||
public Result<Collection<PsiFileSystemItem>> compute() {
|
||||
final Collection<PsiFileSystemItem> contexts = getContextByFile(file);
|
||||
return Result.createSingleDependency(contexts,
|
||||
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||
}
|
||||
};
|
||||
final CachedValuesManager cachedValuesManager = CachedValuesManager.getManager(myElement.getProject());
|
||||
final Collection<PsiFileSystemItem> value =
|
||||
cachedValuesManager.getCachedValue(file, DEFAULT_CONTEXTS_KEY, myDefaultContextProvider, false);
|
||||
return value == null ? Collections.<PsiFileSystemItem>emptyList() : value;
|
||||
return getContextByFile(file);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -285,7 +269,7 @@ public class FileReferenceSet {
|
||||
return file.getOriginalFile();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
private Collection<PsiFileSystemItem> getContextByFile(@NotNull PsiFile file) {
|
||||
final PsiElement context = file.getContext();
|
||||
if (context != null) file = context.getContainingFile();
|
||||
|
||||
Reference in New Issue
Block a user