less PsiType<->String conversions when processing groovy gdsl

This commit is contained in:
peter
2016-05-24 18:58:07 +02:00
parent d0b5f7690a
commit 1d217f7904
7 changed files with 32 additions and 68 deletions
@@ -21,7 +21,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.dsl.toplevel.ClassContextFilter;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.ClassUtil;
import java.util.*;
@@ -147,7 +146,7 @@ public abstract class DslPointcut<T,V> {
@Override
List<GdslType> matches(GroovyClassDescriptor src, ProcessingContext context) {
final GdslType currentType = new GdslType(ClassUtil.findPsiType(src, context));
final GdslType currentType = new GdslType(src.getPsiType());
if (inner.matches(currentType, context) != null) {
return Arrays.asList(currentType);
}
@@ -16,8 +16,8 @@
package org.jetbrains.plugins.groovy.dsl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.psi.PsiElement;
@@ -38,6 +38,7 @@ import java.util.Map;
*/
public class FactorTree extends UserDataHolderBase {
private static final Key<CachedValue<Map>> GDSL_MEMBER_CACHE = Key.create("GDSL_MEMBER_CACHE");
private static final Key<Boolean> CONTAINS_TYPE = Key.create("CONTAINS_TYPE");
private final CachedValueProvider<Map> myProvider;
private final CachedValue<Map> myTopLevelCache;
private final GroovyDslExecutor myExecutor;
@@ -48,8 +49,7 @@ public class FactorTree extends UserDataHolderBase {
@Nullable
@Override
public Result<Map> compute() {
return new Result<Map>(ContainerUtil.newConcurrentMap(), PsiModificationTracker.MODIFICATION_COUNT,
ProjectRootManager.getInstance(project));
return new Result<Map>(ContainerUtil.newConcurrentMap(), PsiModificationTracker.MODIFICATION_COUNT);
}
};
myTopLevelCache = CachedValuesManager.getManager(project).createCachedValue(myProvider, false);
@@ -62,7 +62,7 @@ public class FactorTree extends UserDataHolderBase {
switch (factor) {
case placeElement: key = descriptor.getPlace(); break;
case placeFile: key = descriptor.getPlaceFile(); break;
case qualifierType: key = descriptor.getTypeText(); break;
case qualifierType: key = descriptor.getPsiType().getCanonicalText(false); break;
default: throw new IllegalStateException("Unknown variant: "+ factor);
}
if (current == null) {
@@ -78,6 +78,10 @@ public class FactorTree extends UserDataHolderBase {
if (next == null) {
//noinspection unchecked
current.put(key, next = ContainerUtil.newConcurrentMap());
if (key instanceof String) { // type
//noinspection unchecked
current.put(CONTAINS_TYPE, true);
}
}
current = next;
}
@@ -88,13 +92,12 @@ public class FactorTree extends UserDataHolderBase {
}
@Nullable
public CustomMembersHolder retrieve(PsiElement place, PsiFile placeFile, String qualifierType) {
public CustomMembersHolder retrieve(PsiElement place, PsiFile placeFile, NotNullLazyValue<String> qualifierType) {
return retrieveImpl(place, placeFile, qualifierType, myTopLevelCache.getValue(), true);
}
@Nullable
private CustomMembersHolder retrieveImpl(@NotNull PsiElement place, @NotNull PsiFile placeFile, @NotNull String qualifierType, @Nullable Map current, boolean topLevel) {
private CustomMembersHolder retrieveImpl(@NotNull PsiElement place, @NotNull PsiFile placeFile, @NotNull NotNullLazyValue<String> qualifierType, @Nullable Map current, boolean topLevel) {
if (current == null) return null;
CustomMembersHolder result;
@@ -102,8 +105,10 @@ public class FactorTree extends UserDataHolderBase {
result = (CustomMembersHolder)current.get(myExecutor);
if (result != null) return result;
result = retrieveImpl(place, placeFile, qualifierType, (Map)current.get(qualifierType), false);
if (result != null) return result;
if (current.containsKey(CONTAINS_TYPE)) {
result = retrieveImpl(place, placeFile, qualifierType, (Map)current.get(qualifierType.getValue()), false);
if (result != null) return result;
}
result = retrieveImpl(place, placeFile, qualifierType, getFromMapOrUserData(placeFile, current, topLevel), false);
if (result != null) return result;
@@ -20,14 +20,11 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import org.codehaus.groovy.runtime.GroovyCategorySupport;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author peter
@@ -35,7 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class GroovyClassDescriptor {
static {
try {
final AtomicInteger integer = GroovyCategorySupport.getCategoryNameUsage("aaa");
GroovyCategorySupport.getCategoryNameUsage("aaa");
}
catch (NoSuchMethodError e) {
throw new RuntimeException("Incompatible Groovy JAR in classpath: " + GroovyCategorySupport.class.getResource("/") + ", please remove it");
@@ -45,7 +42,6 @@ public class GroovyClassDescriptor {
private final PsiType myPsiType;
private final PsiElement myPlace;
private final PsiFile myFile;
private final String myTypeText;
@SuppressWarnings({"SetReplaceableByEnumSet"}) //order is important
final Set<Factor> affectingFactors = new LinkedHashSet<Factor>();
@@ -54,7 +50,6 @@ public class GroovyClassDescriptor {
myPsiType = psiType;
myPlace = place;
myFile = placeFile;
myTypeText = myPsiType.getCanonicalText();
}
public Project getProject() {
@@ -66,16 +61,6 @@ public class GroovyClassDescriptor {
return myPlace.getResolveScope();
}
@Nullable
public String getTypeText() {
affectingFactors.add(Factor.qualifierType);
return myTypeText;
}
public boolean isInheritor(String qname) {
return InheritanceUtil.isInheritor(getPsiType(), qname);
}
public PsiElement getPlace() {
affectingFactors.add(Factor.placeElement);
return myPlace;
@@ -259,8 +259,6 @@ public class GroovyDslFileIndex extends ScalarIndexExtension<String> {
return true;
}
final String qname = psiType.getCanonicalText();
final PsiFile placeFile = place.getContainingFile().getOriginalFile();
final DelegatingScopeProcessor nameChecker = new DelegatingScopeProcessor(processor) {
@@ -279,7 +277,7 @@ public class GroovyDslFileIndex extends ScalarIndexExtension<String> {
};
for (GroovyDslScript script : getDslScripts(place.getProject())) {
if (!script.processExecutor(nameChecker, psiType, place, placeFile, qname, state)) {
if (!script.processExecutor(nameChecker, psiType, place, placeFile, state)) {
return false;
}
}
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
@@ -34,7 +35,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.dsl.holders.CustomMembersHolder;
import org.jetbrains.plugins.groovy.dsl.toplevel.ContextFilter;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.ClassUtil;
import java.util.List;
@@ -62,13 +62,18 @@ public class GroovyDslScript {
final PsiType psiType,
final PsiElement place,
final PsiFile placeFile,
final String qname,
ResolveState state) {
CustomMembersHolder holder = myFactorTree.retrieve(place, placeFile, qname);
CustomMembersHolder holder = myFactorTree.retrieve(place, placeFile, new NotNullLazyValue<String>() {
@NotNull
@Override
protected String compute() {
return psiType.getCanonicalText(false);
}
});
GroovyClassDescriptor descriptor = new GroovyClassDescriptor(psiType, place, placeFile);
try {
if (holder == null) {
holder = addGdslMembers(descriptor, qname, psiType);
holder = addGdslMembers(descriptor, psiType);
myFactorTree.cache(descriptor, holder);
}
@@ -83,9 +88,8 @@ public class GroovyDslScript {
}
}
private CustomMembersHolder addGdslMembers(GroovyClassDescriptor descriptor, String qname, final PsiType psiType) {
private CustomMembersHolder addGdslMembers(GroovyClassDescriptor descriptor, final PsiType psiType) {
final ProcessingContext ctx = new ProcessingContext();
ctx.put(ClassUtil.getClassKey(qname), psiType);
ctx.put(GdslUtil.INITIAL_CONTEXT, descriptor);
try {
if (!isApplicable(executor, descriptor, ctx)) {
@@ -40,27 +40,18 @@ public class ClassContextFilter implements ContextFilter {
@Override
public boolean isApplicable(GroovyClassDescriptor descriptor, ProcessingContext ctx) {
final PsiFile place = descriptor.getPlaceFile();
return myPattern.value(Pair.create(ClassUtil.findPsiType(descriptor, ctx), place));
return myPattern.value(Pair.create(descriptor.getPsiType(), descriptor.getPlaceFile()));
}
public static ClassContextFilter fromClassPattern(final ElementPattern pattern) {
return new ClassContextFilter(new Condition<Pair<PsiType, PsiFile>>() {
@Override
public boolean value(Pair<PsiType, PsiFile> pair) {
final PsiType type = pair.first;
return type instanceof PsiClassType ? pattern.accepts(((PsiClassType)type).resolve()) : false;
}
return new ClassContextFilter(pair -> {
final PsiType type = pair.first;
return type instanceof PsiClassType && pattern.accepts(((PsiClassType)type).resolve());
});
}
public static ClassContextFilter subtypeOf(final String typeText) {
return new ClassContextFilter(new Condition<Pair<PsiType, PsiFile>>() {
@Override
public boolean value(Pair<PsiType, PsiFile> p) {
return isSubtype(p.first, p.second, typeText);
}
});
return new ClassContextFilter(p -> isSubtype(p.first, p.second, typeText));
}
public static boolean isSubtype(PsiType checked, PsiFile placeFile, String typeText) {
@@ -15,14 +15,10 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.ProcessingContext;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.dsl.GroovyClassDescriptor;
import org.jetbrains.plugins.groovy.util.LightCacheKey;
import java.util.LinkedHashMap;
@@ -50,20 +46,6 @@ public class ClassUtil {
return superClassNames;
}
@NotNull
public static PsiType findPsiType(GroovyClassDescriptor descriptor, ProcessingContext ctx) {
String typeText = descriptor.getTypeText();
final String key = getClassKey(typeText);
final Object cached = ctx.get(key);
if (cached instanceof PsiType) {
return (PsiType)cached;
}
final PsiType found = JavaPsiFacade.getElementFactory(descriptor.getProject()).createTypeFromText(typeText, descriptor.getPlaceFile());
ctx.put(key, found);
return found;
}
public static String getClassKey(String fqName) {
return "Class: " + fqName;
}