Compare commits

...

1 Commits

Author SHA1 Message Date
Vladimir Dolzhenko
42926bc9c8 Cache null package results in findPackages
Fixed #KT-33394
2020-02-22 17:18:00 +01:00
2 changed files with 30 additions and 8 deletions

View File

@@ -59,6 +59,21 @@ import java.util.concurrent.ConcurrentMap;
public class KotlinJavaPsiFacade {
private volatile KotlinPsiElementFinderWrapper[] elementFinders;
private static final PsiPackage NULL_PSI_PACKAGE = new PsiPackageImpl(null, null) {
@Override
public String toString() {
return "NULL_PSI_PACKAGE";
}
};
private static PsiPackage wrap(PsiPackage aPackage) {
return aPackage == null ? NULL_PSI_PACKAGE : aPackage;
}
private static PsiPackage unwrap(PsiPackage aPackage) {
return aPackage == null || aPackage == NULL_PSI_PACKAGE ? null : aPackage;
}
private static class PackageCache {
final ConcurrentMap<Pair<String, GlobalSearchScope>, PsiPackage> packageInScopeCache = ContainerUtil.newConcurrentMap();
final ConcurrentMap<String, Boolean> hasPackageInAllScopeCache = ContainerUtil.newConcurrentMap();
@@ -90,7 +105,7 @@ public class KotlinJavaPsiFacade {
if (lastTimeSeen != now) {
lastTimeSeen = now;
packageCache = null;
//packageCache = null;
}
}
});
@@ -105,7 +120,7 @@ public class KotlinJavaPsiFacade {
}
public JavaClass findClass(@NotNull JavaClassFinder.Request request, @NotNull GlobalSearchScope scope) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
ClassId classId = request.getClassId();
String qualifiedName = classId.asSingleFqName().asString();
@@ -215,7 +230,7 @@ public class KotlinJavaPsiFacade {
elementFinders.addAll(CollectionsKt.map(nonKotlinFinders, KotlinJavaPsiFacade::wrap));
return elementFinders.toArray(new KotlinPsiElementFinderWrapper[elementFinders.size()]);
return elementFinders.toArray(new KotlinPsiElementFinderWrapper[0]);
}
@NotNull
@@ -238,7 +253,7 @@ public class KotlinJavaPsiFacade {
Pair<String, GlobalSearchScope> key = new Pair<>(qualifiedName, searchScope);
PsiPackage aPackage = cache.packageInScopeCache.get(key);
if (aPackage != null) {
return aPackage;
return unwrap(aPackage);
}
KotlinPsiElementFinderWrapper[] finders = filteredFinders();
@@ -250,20 +265,25 @@ public class KotlinJavaPsiFacade {
// Package was found in AllScope with some of finders but is absent in packageCache for current scope.
// We check only finders that depend on scope.
for (KotlinPsiElementFinderWrapper finder : finders) {
//ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
if (!finder.isSameResultForAnyScope()) {
aPackage = finder.findPackage(qualifiedName, searchScope);
PsiPackage wrapper = ConcurrencyUtil.cacheOrGet(cache.packageInScopeCache, key, wrap(aPackage));
if (aPackage != null) {
return ConcurrencyUtil.cacheOrGet(cache.packageInScopeCache, key, aPackage);
return unwrap(wrapper);
}
} else {
cache.packageInScopeCache.putIfAbsent(key, NULL_PSI_PACKAGE);
}
}
}
else {
for (KotlinPsiElementFinderWrapper finder : finders) {
//ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
aPackage = finder.findPackage(qualifiedName, searchScope);
PsiPackage wrapper = ConcurrencyUtil.cacheOrGet(cache.packageInScopeCache, key, wrap(aPackage));
if (aPackage != null) {
return ConcurrencyUtil.cacheOrGet(cache.packageInScopeCache, key, aPackage);
return unwrap(wrapper);
}
}
@@ -290,7 +310,7 @@ public class KotlinJavaPsiFacade {
KotlinPsiElementFinderWrapper[] finders = finders();
if (dumbService.isDumb()) {
List<KotlinPsiElementFinderWrapper> list = dumbService.filterByDumbAwareness(Arrays.asList(finders));
finders = list.toArray(new KotlinPsiElementFinderWrapper[list.size()]);
finders = list.toArray(new KotlinPsiElementFinderWrapper[0]);
}
return finders;
}

View File

@@ -261,6 +261,8 @@ private class ModuleProductionSourceScope(module: Module) : ModuleSourceScope(mo
// KT-6206
override fun hashCode(): Int = 31 * module.hashCode()
override fun calcHashCode(): Int = 31 * module.hashCode()
override fun contains(file: VirtualFile) =
moduleFileIndex.isInSourceContentWithoutInjected(file) && !moduleFileIndex.isInTestSourceContentKotlinAware(file)