move super type cache to ScopedClassHierarchy

This commit is contained in:
peter
2016-04-25 12:19:26 +02:00
parent c1225e4409
commit cd26c23e0b
2 changed files with 41 additions and 41 deletions
@@ -736,38 +736,7 @@ public class PsiClassImplUtil {
}
public static List<PsiClassType.ClassResolveResult> getScopeCorrectedSuperTypes(final PsiClass aClass, GlobalSearchScope resolveScope) {
Map<GlobalSearchScope, List<PsiClassType.ClassResolveResult>> cache =
CachedValuesManager.getCachedValue(aClass, new CachedValueProvider<Map<GlobalSearchScope, List<PsiClassType.ClassResolveResult>>>() {
@Nullable
@Override
public Result<Map<GlobalSearchScope, List<PsiClassType.ClassResolveResult>>> compute() {
Map<GlobalSearchScope, List<PsiClassType.ClassResolveResult>> map = new ConcurrentFactoryMap<GlobalSearchScope, List<PsiClassType.ClassResolveResult>>() {
@NotNull
@Override
protected List<PsiClassType.ClassResolveResult> 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<PsiClassType.ClassResolveResult> calcScopeCorrectedSuperTypes(GlobalSearchScope resolveScope, PsiClass aClass) {
List<PsiClassType.ClassResolveResult> answer = ContainerUtil.newArrayList();
for (PsiClassType type : aClass.getSuperTypes()) {
PsiClassType corrected = correctType(type, resolveScope);
if (corrected == null) continue;
PsiClassType.ClassResolveResult result = ((PsiClassType)PsiUtil.captureToplevelWildcards(corrected, aClass)).resolveGenerics();
PsiClass superClass = result.getElement();
if (superClass == null || !PsiSearchScopeUtil.isInScope(resolveScope, superClass)) continue;
answer.add(result);
}
return answer;
return ScopedClassHierarchy.getHierarchy(aClass, resolveScope).getImmediateSupersWithCapturing();
}
private static boolean processSuperTypes(@NotNull PsiClass aClass,
@@ -18,6 +18,7 @@ package com.intellij.psi.impl;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchScopeUtil;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
@@ -53,26 +54,30 @@ class ScopedClassHierarchy {
return o1.getManager().areElementsEquivalent(o1, o2);
}
};
private final Map<PsiClass, PsiClassType.ClassResolveResult> mySupersWithSubstitutors = ContainerUtil.newTroveMap(CLASS_HASHING_STRATEGY);
private final PsiClass myPlaceClass;
private final GlobalSearchScope myResolveScope;
private volatile Map<PsiClass, PsiClassType.ClassResolveResult> mySupersWithSubstitutors;
private volatile List<PsiClassType.ClassResolveResult> myImmediateSupersWithCapturing;
private ScopedClassHierarchy(PsiClass psiClass, GlobalSearchScope resolveScope) {
visitType(resolveScope, JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, PsiSubstitutor.EMPTY));
myPlaceClass = psiClass;
myResolveScope = resolveScope;
}
private void visitType(GlobalSearchScope resolveScope, @NotNull PsiClassType type) {
private void visitType(@NotNull PsiClassType type, Map<PsiClass, PsiClassType.ClassResolveResult> map) {
PsiClassType.ClassResolveResult resolveResult = type.resolveGenerics();
PsiClass psiClass = resolveResult.getElement();
if (psiClass == null || InheritanceImplUtil.hasObjectQualifiedName(psiClass) || mySupersWithSubstitutors.containsKey(psiClass)) {
if (psiClass == null || InheritanceImplUtil.hasObjectQualifiedName(psiClass) || map.containsKey(psiClass)) {
return;
}
mySupersWithSubstitutors.put(psiClass, resolveResult);
map.put(psiClass, resolveResult);
for (PsiType superType : getSuperTypes(psiClass)) {
superType = type.isRaw() && superType instanceof PsiClassType ? ((PsiClassType)superType).rawType() : resolveResult.getSubstitutor().substitute(superType);
superType = PsiClassImplUtil.correctType(superType, resolveScope);
superType = PsiClassImplUtil.correctType(superType, myResolveScope);
if (superType instanceof PsiClassType) {
visitType(resolveScope, (PsiClassType)superType);
visitType((PsiClassType)superType, map);
}
}
}
@@ -89,7 +94,7 @@ class ScopedClassHierarchy {
}
@NotNull
private static ScopedClassHierarchy getHierarchy(@NotNull final PsiClass psiClass, @NotNull final GlobalSearchScope resolveScope) {
static ScopedClassHierarchy getHierarchy(@NotNull final PsiClass psiClass, @NotNull final GlobalSearchScope resolveScope) {
return CachedValuesManager.getCachedValue(psiClass, new CachedValueProvider<Map<GlobalSearchScope, ScopedClassHierarchy>>() {
@Nullable
@Override
@@ -108,7 +113,14 @@ class ScopedClassHierarchy {
@Nullable
static PsiSubstitutor getSuperClassSubstitutor(@NotNull PsiClass derivedClass, @NotNull GlobalSearchScope scope, @NotNull PsiClass superClass) {
PsiClassType.ClassResolveResult resolveResult = getHierarchy(derivedClass, scope).mySupersWithSubstitutors.get(superClass);
ScopedClassHierarchy hierarchy = getHierarchy(derivedClass, scope);
Map<PsiClass, PsiClassType.ClassResolveResult> map = hierarchy.mySupersWithSubstitutors;
if (map == null) {
map = ContainerUtil.newTroveMap(CLASS_HASHING_STRATEGY);
hierarchy.visitType(JavaPsiFacade.getElementFactory(derivedClass.getProject()).createType(derivedClass, PsiSubstitutor.EMPTY), map);
hierarchy.mySupersWithSubstitutors = map;
}
PsiClassType.ClassResolveResult resolveResult = map.get(superClass);
if (resolveResult == null) return null;
PsiClass cachedClass = assertNotNull(resolveResult.getElement());
@@ -131,4 +143,23 @@ class ScopedClassHierarchy {
return answer;
}
@NotNull
List<PsiClassType.ClassResolveResult> getImmediateSupersWithCapturing() {
List<PsiClassType.ClassResolveResult> list = myImmediateSupersWithCapturing;
if (list == null) {
list = ContainerUtil.newArrayList();
for (PsiClassType type : myPlaceClass.getSuperTypes()) {
PsiClassType corrected = PsiClassImplUtil.correctType(type, myResolveScope);
if (corrected == null) continue;
PsiClassType.ClassResolveResult result = ((PsiClassType)PsiUtil.captureToplevelWildcards(corrected, myPlaceClass)).resolveGenerics();
PsiClass superClass = result.getElement();
if (superClass == null || !PsiSearchScopeUtil.isInScope(myResolveScope, superClass)) continue;
list.add(result);
}
myImmediateSupersWithCapturing = list;
}
return list;
}
}