Skip to content

Commit

Permalink
Ensure different session is generated for different file and create t…
Browse files Browse the repository at this point in the history
…hem for library files
  • Loading branch information
goodwinnk committed Aug 14, 2013
1 parent 7330837 commit d25ac97
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 35 deletions.
Expand Up @@ -54,6 +54,10 @@ public CancelableResolveSession getLazyResolveSession() {
return lazyResolveCache.getValue();
}

public boolean areDeclarationsAvailable(@NotNull JetFile jetFile) {
return JetFilesProvider.getInstance(project).isFileInScope(jetFile, GlobalSearchScope.allScope(project));
}

private static class CancelableResolveSessionValueProvider implements CachedValueProvider<CancelableResolveSession> {
private final Project project;
private final TargetPlatform platform;
Expand Down
Expand Up @@ -21,7 +21,6 @@
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;
Expand Down Expand Up @@ -72,12 +71,7 @@ public KotlinDeclarationsCache getPossiblyIncompleteDeclarationsForLightClassGen
}

@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);
Expand Down
Expand Up @@ -28,7 +28,10 @@
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;
Expand All @@ -42,10 +45,7 @@
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;
Expand Down Expand Up @@ -165,39 +165,55 @@ private static void handleError(@NotNull Throwable e) {
LOG.error(e);
}

private final static Key<ParameterizedCachedValue<CancelableResolveSession, JetFile>> 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<CancelableResolveSession> 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<CancelableResolveSession, JetFile> {
private static final PerFileLazyResolveSessionProvider INSTANCE = new PerFileLazyResolveSessionProvider();

private static final SLRUCache<JetFile, CachedValue<CancelableResolveSession>> PER_FILE_SESSION_CACHE = new SLRUCache<JetFile, CachedValue<CancelableResolveSession>>(2, 3) {
@NotNull
@Override
public CachedValueProvider.Result<CancelableResolveSession> compute(@NotNull JetFile file) {
Project project = file.getProject();
Collection<JetFile> files = JetFilesProvider.getInstance(project).allInScope(GlobalSearchScope.allScope(project));
public CachedValue<CancelableResolveSession> 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<CancelableResolveSession>() {
@Nullable
@Override
public Result<CancelableResolveSession> compute() {
Project project = file.getProject();


Collection<JetFile> files = JetFilesProvider.getInstance(project).allInScope(GlobalSearchScope.allScope(project));

JetFile originalFile = (JetFile) file.getOriginalFile();
assert originalFile != file: "Should be used only for non-physical files";
// Add requested file to the list of files for searching declarations
files.add(file);

// Virtual file can differ from the original and there can be requests to psi elements from this file
files.remove(originalFile);
files.add(file);
if (file != file.getOriginalFile()) {
// Given file can be a non-physical copy of the file in list (completion case). Remove the prototype file.

ResolveSession resolveSession =
AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).getLazyResolveSession(project, files);
//noinspection SuspiciousMethodCalls
files.remove(file.getOriginalFile());
}

return CachedValueProvider.Result.create(new CancelableResolveSession(file, resolveSession),
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
ResolveSession resolveSession = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).getLazyResolveSession(fileProject, files);
return Result.create(new CancelableResolveSession(file, resolveSession), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
}
},
true);
}
}
};
}

0 comments on commit d25ac97

Please sign in to comment.