From 3e398c62cb824287f46d8891b4aaf6fcebcd0caf Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 6 Jul 2010 23:07:46 +0100 Subject: [PATCH] faster supertypes caching --- .../groovy/lang/resolve/ResolveUtil.java | 83 +++++++------------ 1 file changed, 29 insertions(+), 54 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index b1308def84aa..d00e738353e6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -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>>> SUPER_TYPES = Key.create("SUPER_TYPES"); - - private static final TObjectHashingStrategy RAW_TYPE_HASHING_STRATEGY = new TObjectHashingStrategy() { - @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 visited) { + private static void collectSuperTypes(PsiType type, Map 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 getAllSuperTypes(PsiType base, final PsiElement place) { final Project project = place.getProject(); - return CachedValuesManager.getManager(project).getCachedValue(project, SUPER_TYPES, new CachedValueProvider>>() { - @Override - public Result>> compute() { - final FactoryMap> map = new ConcurrentFactoryMap>() { + final Map> cache = + CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider>>() { + @Override + public Result>> compute() { + final Map> result = new ConcurrentHashMap>(); + return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(project)); + } + }); - @Override - protected Map> createMap() { - return new ConcurrentHashMap>(RAW_TYPE_HASHING_STRATEGY); - } - - @Override - protected Map create(PsiType key) { - final HashMap visited = new HashMap(); - 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 result = cache.get(key); + if (result == null) { + result = new HashMap(); + collectSuperTypes(base, result, project); + cache.put(key, result); + } + return result; } public static boolean isInheritor(PsiType type, @NotNull String baseClass, PsiElement place) {