From d3f92d820df5ce25f36972a3a2834d12762aacf2 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Thu, 21 Aug 2025 17:54:26 +0200 Subject: [PATCH] IDEA-367535 cache classes by name and scope if multiverse is enabled GitOrigin-RevId: 5c8d0a1d6eaf2aee46f3e3a6fa41743d45b06208 --- .../psi/impl/file/PsiPackageImpl.java | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java index 822b73574d07..dabfa54800be 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java @@ -44,7 +44,7 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya private static final Logger LOG = Logger.getInstance(PsiPackageImpl.class); private volatile CachedValue myAnnotationList; - private volatile SoftReference> myClassCache; + private volatile SoftReference>> myClassCache; private volatile CachedValue> myDirectories; private volatile CachedValue> myDirectoriesWithLibSources; private volatile CachedValue> myFiles; @@ -191,27 +191,33 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya return getCachedClassesInDumbMode(name, scope); } - if (CodeInsightContexts.isSharedSourceSupportEnabled(getProject())) { - // todo IJPL-339 this line introduces performance degradation, see IDEA-367535 - return findAllClasses(name, scope); - } - else { - Map map = dereference(myClassCache); - if (map == null) { - myClassCache = new SoftReference<>(map = ContainerUtil.createConcurrentSoftValueMap()); - } - PsiClass[] classes = map.get(name); - if (classes != null) { - return classes; - } + // if shared source support is enabled, we need to use the real scope, + // because we need to specify the proper context for files with several contexts + boolean sharedSourceSupportEnabled = CodeInsightContexts.isSharedSourceSupportEnabled(getProject()); + GlobalSearchScope effectiveScope = sharedSourceSupportEnabled ? scope : GlobalSearchScope.everythingScope(getProject()); - RecursionGuard.StackStamp stamp = RecursionManager.markStack(); - classes = findAllClasses(name, GlobalSearchScope.everythingScope(getProject())); - if (stamp.mayCacheNow()) { - map.put(name, classes); - } + return getCachedClassesByNameImpl(name, effectiveScope); + } + + private PsiClass @NotNull [] getCachedClassesByNameImpl(@NotNull String name, @NotNull GlobalSearchScope scope) { + Map> cache = dereference(myClassCache); + if (cache == null) { + cache = ContainerUtil.createConcurrentSoftValueMap(); + myClassCache = new SoftReference<>(cache); + } + + Map map = cache.computeIfAbsent(scope, __ -> ContainerUtil.createConcurrentSoftValueMap()); + PsiClass[] classes = map.get(name); + if (classes != null) { return classes; } + + RecursionGuard.StackStamp stamp = RecursionManager.markStack(); + classes = findAllClasses(name, scope); + if (stamp.mayCacheNow()) { + map.put(name, classes); + } + return classes; } private PsiClass @NotNull [] findAllClasses(@NotNull String shortName, @NotNull GlobalSearchScope scope) {