From d25ac975ffa6942831411ae208d0c0ef4296949a Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 14 Aug 2013 15:25:33 +0400 Subject: [PATCH] Ensure different session is generated for different file and create them for library files --- .../resolve/DeclarationsCacheProvider.java | 4 ++ .../caches/resolve/KotlinCacheManager.java | 8 +-- .../project/AnalyzerFacadeWithCache.java | 72 +++++++++++-------- 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/DeclarationsCacheProvider.java b/idea/src/org/jetbrains/jet/plugin/caches/resolve/DeclarationsCacheProvider.java index 07fbc87aaa3..75c8a5411bd 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/DeclarationsCacheProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/DeclarationsCacheProvider.java @@ -54,6 +54,10 @@ public abstract class DeclarationsCacheProvider { return lazyResolveCache.getValue(); } + public boolean areDeclarationsAvailable(@NotNull JetFile jetFile) { + return JetFilesProvider.getInstance(project).isFileInScope(jetFile, GlobalSearchScope.allScope(project)); + } + private static class CancelableResolveSessionValueProvider implements CachedValueProvider { private final Project project; private final TargetPlatform platform; diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheManager.java b/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheManager.java index a05e86a6598..a67b0bb9ae2 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheManager.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinCacheManager.java @@ -21,7 +21,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.plugin.project.CancelableResolveSession; import org.jetbrains.jet.plugin.project.TargetPlatform; import java.util.Map; @@ -72,12 +71,7 @@ public class KotlinCacheManager { } @NotNull - public CancelableResolveSession getLazyResolveSession(@NotNull TargetPlatform platform) { - return cacheProviders.get(platform).getLazyResolveSession(); - } - - @NotNull - private DeclarationsCacheProvider getRegisteredProvider(TargetPlatform platform) { + public DeclarationsCacheProvider getRegisteredProvider(@NotNull TargetPlatform platform) { DeclarationsCacheProvider provider = cacheProviders.get(platform); if (provider == null) { throw new IllegalStateException("Provider isn't registered for platform: " + platform); diff --git a/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java b/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java index efca4dfb0f6..07e8ab9a094 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java +++ b/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java @@ -28,7 +28,10 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.PsiModificationTrackerImpl; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.*; +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.containers.SLRUCache; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -42,10 +45,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.JetFilesProvider; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.types.ErrorUtils; -import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; -import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; -import org.jetbrains.jet.plugin.caches.resolve.KotlinDeclarationsCache; -import org.jetbrains.jet.plugin.caches.resolve.KotlinDeclarationsCacheImpl; +import org.jetbrains.jet.plugin.caches.resolve.*; import org.jetbrains.jet.plugin.util.ApplicationUtils; import java.util.Collection; @@ -165,39 +165,55 @@ public final class AnalyzerFacadeWithCache { LOG.error(e); } - private final static Key> PER_FILE_LAZY_RESOLVE_SESSION = Key.create("PER_FILE_LAZY_RESOLVE_SESSION"); - public static CancelableResolveSession getLazyResolveSessionForFile(@NotNull JetFile file) { Project project = file.getProject(); - if (file.getOriginalFile() != file) { - // Completion creates special non-physical file. Create a separate session for them. - return CachedValuesManager.getManager(project).getParameterizedCachedValue( - project, PER_FILE_LAZY_RESOLVE_SESSION, PerFileLazyResolveSessionProvider.INSTANCE, true, file); + DeclarationsCacheProvider provider = KotlinCacheManager.getInstance(project).getRegisteredProvider(TargetPlatformDetector.getPlatform(file)); + + if (!provider.areDeclarationsAvailable(file)) { + // There can be request for temp files (in completion) or non-source (in library) files. Create temp sessions for them. + CachedValue cachedValue; + + synchronized (PER_FILE_SESSION_CACHE) { + cachedValue = PER_FILE_SESSION_CACHE.get(file); + } + + return cachedValue.getValue(); } - return KotlinCacheManager.getInstance(project).getLazyResolveSession(TargetPlatformDetector.getPlatform(file)); + return provider.getLazyResolveSession(); } - private static class PerFileLazyResolveSessionProvider implements ParameterizedCachedValueProvider { - private static final PerFileLazyResolveSessionProvider INSTANCE = new PerFileLazyResolveSessionProvider(); - + private static final SLRUCache> PER_FILE_SESSION_CACHE = new SLRUCache>(2, 3) { + @NotNull @Override - public CachedValueProvider.Result compute(@NotNull JetFile file) { - Project project = file.getProject(); - Collection files = JetFilesProvider.getInstance(project).allInScope(GlobalSearchScope.allScope(project)); + public CachedValue createValue(final JetFile file) { + final Project fileProject = file.getProject(); + return CachedValuesManager.getManager(fileProject).createCachedValue( + // Each value monitors OUT_OF_CODE_BLOCK_MODIFICATION_COUNT and modification tracker of the stored value + new CachedValueProvider() { + @Nullable + @Override + public Result compute() { + Project project = file.getProject(); - JetFile originalFile = (JetFile) file.getOriginalFile(); - assert originalFile != file: "Should be used only for non-physical files"; - // Virtual file can differ from the original and there can be requests to psi elements from this file - files.remove(originalFile); - files.add(file); + Collection files = JetFilesProvider.getInstance(project).allInScope(GlobalSearchScope.allScope(project)); - ResolveSession resolveSession = - AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).getLazyResolveSession(project, files); + // Add requested file to the list of files for searching declarations + files.add(file); - return CachedValueProvider.Result.create(new CancelableResolveSession(file, resolveSession), - PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + if (file != file.getOriginalFile()) { + // Given file can be a non-physical copy of the file in list (completion case). Remove the prototype file. + + //noinspection SuspiciousMethodCalls + files.remove(file.getOriginalFile()); + } + + ResolveSession resolveSession = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).getLazyResolveSession(fileProject, files); + return Result.create(new CancelableResolveSession(file, resolveSession), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + } + }, + true); } - } + }; }