diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java index 8b1db4700ceb..4a863d155646 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java @@ -43,6 +43,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.NullableFunction; import com.intellij.util.SmartList; import com.intellij.util.containers.ConcurrentFactoryMap; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import gnu.trove.THashMap; import gnu.trove.THashSet; @@ -370,7 +371,7 @@ public class PsiClassImplUtil { @Override protected Map>> create(final MemberType key) { final Map>> map = new THashMap>>(); - + final List> allMembers = new ArrayList>(); map.put(ALL, allMembers); @@ -395,7 +396,7 @@ public class PsiClassImplUtil { } } }; - + processDeclarationsInClassNotCached(myPsiClass, processor, ResolveState.initial(), null, null, myPsiClass, false, PsiUtil.getLanguageLevel(myPsiClass), myResolveScope); return map; @@ -719,6 +720,41 @@ public class PsiClassImplUtil { return new TypeCorrector(resolveScope).mapType(originalType); } + private static List getScopeCorrectedSuperTypes(final PsiClass aClass, GlobalSearchScope resolveScope) { + Map> cache = + CachedValuesManager.getCachedValue(aClass, new CachedValueProvider>>() { + @Nullable + @Override + public Result>> compute() { + Map> map = new ConcurrentFactoryMap>() { + @NotNull + @Override + protected List create(final GlobalSearchScope resolveScope) { + return calcScopeCorrectedSuperTypes(resolveScope, aClass); + } + }; + return Result.create(map, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); + } + }); + return cache.get(resolveScope); + } + + @NotNull + private static List calcScopeCorrectedSuperTypes(GlobalSearchScope resolveScope, PsiClass aClass) { + List answer = ContainerUtil.newArrayList(); + for (PsiClassType type : aClass.getSuperTypes()) { + PsiClassType corrected = correctType(type, resolveScope); + if (corrected == null) continue; + + PsiClassType.ClassResolveResult result = corrected.resolveGenerics(); + PsiClass superClass = result.getElement(); + if (superClass == null || !PsiSearchScopeUtil.isInScope(resolveScope, superClass)) continue; + + answer.add(result); + } + return answer; + } + private static boolean processSuperTypes(@NotNull PsiClass aClass, @NotNull PsiScopeProcessor processor, @Nullable Set visited, @@ -729,13 +765,9 @@ public class PsiClassImplUtil { @NotNull PsiElementFactory factory, @NotNull LanguageLevel languageLevel, GlobalSearchScope resolveScope) { boolean resolved = false; - for (PsiClassType superType : aClass.getSuperTypes()) { - superType = correctType(superType, resolveScope); - if (superType == null) continue; - - final PsiClassType.ClassResolveResult superTypeResolveResult = superType.resolveGenerics(); + for (PsiClassType.ClassResolveResult superTypeResolveResult : getScopeCorrectedSuperTypes(aClass, resolveScope)) { PsiClass superClass = superTypeResolveResult.getElement(); - if (superClass == null || !PsiSearchScopeUtil.isInScope(resolveScope, superClass)) continue; + assert superClass != null; PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superTypeResolveResult.getSubstitutor(), aClass, state.get(PsiSubstitutor.KEY), factory, languageLevel); if (!processDeclarationsInClass(superClass, processor, state.put(PsiSubstitutor.KEY, finalSubstitutor), visited, last, place,