mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
faster supertypes caching
This commit is contained in:
@@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.JavaScopeProcessorEvent;
|
||||
@@ -26,10 +25,6 @@ import com.intellij.psi.scope.NameHint;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
import com.intellij.util.containers.ConcurrentHashMap;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex;
|
||||
@@ -56,6 +51,7 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.PropertyResolverProc
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
@@ -63,28 +59,6 @@ import java.util.*;
|
||||
@SuppressWarnings({"StringBufferReplaceableByString"})
|
||||
public class ResolveUtil {
|
||||
public static final PsiScopeProcessor.Event DECLARATION_SCOPE_PASSED = new PsiScopeProcessor.Event() {};
|
||||
private static final Key<CachedValue<FactoryMap<PsiType, Map<String, PsiType>>>> SUPER_TYPES = Key.create("SUPER_TYPES");
|
||||
|
||||
private static final TObjectHashingStrategy<PsiType> RAW_TYPE_HASHING_STRATEGY = new TObjectHashingStrategy<PsiType>() {
|
||||
@Override
|
||||
public int computeHashCode(PsiType object) {
|
||||
return stringify(object).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(PsiType o1, PsiType o2) {
|
||||
return stringify(o1).equals(stringify(o2));
|
||||
}
|
||||
|
||||
private String stringify(PsiType type) {
|
||||
final PsiClass cls = PsiUtil.resolveClassInType(type);
|
||||
if (cls instanceof PsiTypeParameter) {
|
||||
return cls.getName() + cls.getSuperClass().getName();
|
||||
}
|
||||
return rawCanonicalText(type);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private ResolveUtil() {
|
||||
}
|
||||
@@ -186,46 +160,47 @@ public class ResolveUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void collectSuperTypes(PsiType type, Map<String, PsiType> visited) {
|
||||
private static void collectSuperTypes(PsiType type, Map<String, PsiType> visited, Project project) {
|
||||
String qName = rawCanonicalText(type);
|
||||
|
||||
if (visited.put(qName, type) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (PsiType superType : type.getSuperTypes()) {
|
||||
collectSuperTypes(TypeConversionUtil.erasure(superType), visited);
|
||||
final PsiType[] superTypes = type.getSuperTypes();
|
||||
for (PsiType superType : superTypes) {
|
||||
collectSuperTypes(TypeConversionUtil.erasure(superType), visited, project);
|
||||
}
|
||||
|
||||
if (type instanceof PsiArrayType && superTypes.length == 0) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_LANG_COMPARABLE, null), visited, project);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_IO_SERIALIZABLE, null), visited, project);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Map<String, PsiType> getAllSuperTypes(PsiType base, final PsiElement place) {
|
||||
final Project project = place.getProject();
|
||||
return CachedValuesManager.getManager(project).getCachedValue(project, SUPER_TYPES, new CachedValueProvider<FactoryMap<PsiType, Map<String, PsiType>>>() {
|
||||
@Override
|
||||
public Result<FactoryMap<PsiType, Map<String, PsiType>>> compute() {
|
||||
final FactoryMap<PsiType, Map<String, PsiType>> map = new ConcurrentFactoryMap<PsiType, Map<String, PsiType>>() {
|
||||
final Map<String, Map<String, PsiType>> cache =
|
||||
CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider<Map<String, Map<String, PsiType>>>() {
|
||||
@Override
|
||||
public Result<Map<String, Map<String, PsiType>>> compute() {
|
||||
final Map<String, Map<String, PsiType>> result = new ConcurrentHashMap<String, Map<String, PsiType>>();
|
||||
return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(project));
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
protected Map<PsiType, Map<String, PsiType>> createMap() {
|
||||
return new ConcurrentHashMap<PsiType, Map<String, PsiType>>(RAW_TYPE_HASHING_STRATEGY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, PsiType> create(PsiType key) {
|
||||
final HashMap<String, PsiType> visited = new HashMap<String, PsiType>();
|
||||
collectSuperTypes(key, visited);
|
||||
if (key instanceof PsiArrayType) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_LANG_COMPARABLE, null), visited);
|
||||
collectSuperTypes(factory.createTypeFromText(CommonClassNames.JAVA_IO_SERIALIZABLE, null), visited);
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
};
|
||||
return Result.create(map, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(project));
|
||||
}
|
||||
}, false).get(base);
|
||||
final PsiClass cls = PsiUtil.resolveClassInType(base);
|
||||
//noinspection ConstantConditions
|
||||
String key = cls instanceof PsiTypeParameter ? cls.getName() + cls.getSuperClass().getName() : rawCanonicalText(base);
|
||||
Map<String, PsiType> result = cache.get(key);
|
||||
if (result == null) {
|
||||
result = new HashMap<String, PsiType>();
|
||||
collectSuperTypes(base, result, project);
|
||||
cache.put(key, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isInheritor(PsiType type, @NotNull String baseClass, PsiElement place) {
|
||||
|
||||
Reference in New Issue
Block a user