diff --git a/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspContextManager.java b/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspContextManager.java index 976932ac0ad7..21d1701b096d 100644 --- a/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspContextManager.java +++ b/java/jsp-spi/src/com/intellij/psi/impl/source/jsp/JspContextManager.java @@ -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); diff --git a/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeInfo.java b/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeInfo.java index 82ed4f5c4c1c..f4b925897175 100644 --- a/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeInfo.java +++ b/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeInfo.java @@ -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) { diff --git a/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeManager.java b/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeManager.java index 834f6772f29d..7d56a7e75cb2 100644 --- a/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeManager.java +++ b/platform/lang-api/src/com/intellij/psi/impl/include/FileIncludeManager.java @@ -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> processor); + @Nullable - public abstract PsiFileSystemItem resolveFileReference(String text, PsiFile context); + public abstract PsiFileSystemItem resolveFileInclude(FileIncludeInfo info, PsiFile context); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java b/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java index 997c4578e2f4..e12030ffd4cf 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeIndex.java @@ -163,7 +163,7 @@ public class FileIncludeIndex extends FileBasedIndexExtension infoList = FileIncludeIndex.getIncludes(file.getVirtualFile(), scope); - ArrayList files = new ArrayList(); - 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 files = new ArrayList(); + processIncludes(file, new Processor() { + @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 processor) { + GlobalSearchScope scope = GlobalSearchScope.allScope(myProject); + List 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 files = new ArrayList(); + processIncludingFiles(context, new Processor>() { + @Override + public boolean process(Pair 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 infoList = FileIncludeIndex.getIncludingFileCandidates(file.getName(), GlobalSearchScope.allScope(myProject)); - ArrayList files = new ArrayList(); - 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> processor) { + context = context.getOriginalFile(); + VirtualFile contextFile = context.getVirtualFile(); + if (contextFile == null) return; + MultiMap 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> COMPILE_TIME_KEY; private final Key> RUNTIME_KEY; - private final ParameterizedCachedValueProvider COMPILE_TIME_PROVIDER = new IncludedFilesProvider(false) { + private final ParameterizedCachedValueProvider COMPILE_TIME_PROVIDER = new IncludedFilesProvider(true) { @Override protected VirtualFile[] computeFiles(PsiFile file, boolean compileTimeOnly) { return IncludeCacheHolder.this.computeFiles(file, compileTimeOnly); } }; - private final ParameterizedCachedValueProvider RUNTIME_PROVIDER = new IncludedFilesProvider(true) { + private final ParameterizedCachedValueProvider 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 result = new ArrayList(); + Set result = new HashSet(); 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 result) { + private void getFilesRecursively(VirtualFile file, boolean compileTimeOnly, Set 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); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeProvider.java index 031865cffb30..2161f95fa29f 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeProvider.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/include/FileIncludeProvider.java @@ -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); - } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java index 828fdc42cc23..6de47a442bf5 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java @@ -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>> DEFAULT_CONTEXTS_KEY = new Key>>("default file contexts"); public static final CustomizableReferenceProvider.CustomizationKey>> DEFAULT_PATH_EVALUATOR_OPTION = new CustomizableReferenceProvider.CustomizationKey>>(PsiBundle.message("default.path.evaluator.option")); public static final Function> ABSOLUTE_TOP_LEVEL = new Function>() { @@ -262,17 +256,7 @@ public class FileReferenceSet { return getAbsoluteTopLevelDirLocations(file); } - final CachedValueProvider> myDefaultContextProvider = new CachedValueProvider>() { - public Result> compute() { - final Collection contexts = getContextByFile(file); - return Result.createSingleDependency(contexts, - PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); - } - }; - final CachedValuesManager cachedValuesManager = CachedValuesManager.getManager(myElement.getProject()); - final Collection value = - cachedValuesManager.getCachedValue(file, DEFAULT_CONTEXTS_KEY, myDefaultContextProvider, false); - return value == null ? Collections.emptyList() : value; + return getContextByFile(file); } @Nullable @@ -285,7 +269,7 @@ public class FileReferenceSet { return file.getOriginalFile(); } - @Nullable + @NotNull private Collection getContextByFile(@NotNull PsiFile file) { final PsiElement context = file.getContext(); if (context != null) file = context.getContainingFile();