caching for categories initial

This commit is contained in:
Maxim Medvedev
2010-08-03 21:03:32 +04:00
parent e37f30cd79
commit 4a96205dc1
4 changed files with 70 additions and 6 deletions
@@ -8,6 +8,7 @@ import org.jetbrains.plugins.groovy.dsl.psi.PsiEnhancerCategory
import org.jetbrains.plugins.groovy.dsl.toplevel.CompositeContextFilter
import org.jetbrains.plugins.groovy.dsl.toplevel.ContextFilter
import org.jetbrains.plugins.groovy.dsl.toplevel.GdslMetaClassProperties
import com.intellij.openapi.project.Project
/**
* @author ilyas
@@ -16,13 +17,15 @@ import org.jetbrains.plugins.groovy.dsl.toplevel.GdslMetaClassProperties
public class GroovyDslExecutor {
static final def cats = PsiEnhancerCategory.EP_NAME.extensions.collect { it.class }
final List<Pair<ContextFilter, Closure>> enhancers = []
final List<Pair<Closure>> categoryEnhancers = []
private final String myFileName;
static final String ideaVersion
static {
def major = ApplicationInfo.instance.majorVersion
def minor = ApplicationInfo.instance.minorVersion
def full = major + (minor ? ".$minor" : "")
def minor = ApplicationInfo.instance.minorVersion
def full = major + (minor ? ".$minor" : "")
ideaVersion = full
}
@@ -56,6 +59,10 @@ public class GroovyDslExecutor {
enhancers << Pair.create(CompositeContextFilter.compose(cts, false), toDo)
}
def addCategoryEnhancer(Closure toDo) {
categoryEnhancers << toDo
}
def processVariants(GroovyClassDescriptor descriptor, consumer, ProcessingContext ctx) {
for (pair in enhancers) {
if (pair.first.isApplicable(descriptor, ctx)) {
@@ -70,6 +77,18 @@ public class GroovyDslExecutor {
}
}
def processCategoryVariants(Project project, consumer) {
for (enhancer in categoryEnhancers) {
Closure f = enhancer.clone()
f.delegate = consumer
f.resolveStrategy = Closure.DELEGATE_FIRST
use(cats) {
f.call()
}
}
}
def String toString() {
return "${super.toString()}; file = $myFileName";
}
@@ -42,6 +42,10 @@ class GdslMetaClassProperties {
}
}
Closure staticContributor = { Closure toDo ->
myExecutor.addCategoryEnhancer toDo
}
/**
* Auxiliary methods for context definition
*/
@@ -57,7 +57,7 @@ public class GDKSuperMethodSearcher implements QueryExecutor<MethodSignatureBack
final String name = method.getName();
final MethodResolverProcessor processor = new MethodResolverProcessor(name, ((GrMethod)method), false, null, null, PsiType.EMPTY_ARRAY);
ResolveUtil.processNonCodeMethods(JavaPsiFacade.getElementFactory(project).createType(psiClass), processor, method, false);
ResolveUtil.processNonCodeMethods(JavaPsiFacade.getElementFactory(project).createType(psiClass), processor, method);
final GroovyResolveResult[] candidates = processor.getCandidates();
@@ -34,15 +34,19 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.dsl.GroovyDslExecutor;
import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.stubs.GroovyShortNamesCache;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* @author ven
@@ -50,10 +54,12 @@ import java.util.Map;
public class GroovyPsiManager {
private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager");
private final Project myProject;
private Map<String, List<PsiMethod>> myDefaultMethods;
private GrTypeDefinition myArrayClass;
private final ConcurrentWeakHashMap<GroovyPsiElement, PsiType> myCalculatedTypes = new ConcurrentWeakHashMap<GroovyPsiElement, PsiType>();
private volatile boolean myRebuildGdkPending = true;
private final GroovyShortNamesCache myCache;
private final TypeInferenceHelper myTypeInferenceHelper;
@@ -78,6 +84,7 @@ public class GroovyPsiManager {
public void rootsChanged(ModuleRootEvent event) {
dropTypesCache();
myRebuildGdkPending = true;
}
});
}
@@ -90,6 +97,40 @@ public class GroovyPsiManager {
myCalculatedTypes.clear();
}
public List<PsiMethod> getDefaultMethods(String qName) {
if (myRebuildGdkPending) {
final Map<String, List<PsiMethod>> gdk = buildGDK();
if (myRebuildGdkPending) {
myDefaultMethods = gdk;
myRebuildGdkPending = false;
}
}
List<PsiMethod> methods = myDefaultMethods.get(qName);
if (methods == null) return Collections.emptyList();
return methods;
}
private Map<String, List<PsiMethod>> buildGDK() {
return null; //To change body of created methods use File | Settings | File Templates.
}
public List<PsiMethod> getDefaultMethods(PsiClass psiClass) {
List<PsiMethod> list = new ArrayList<PsiMethod>();
getDefaultMethodsInner(psiClass, new HashSet<PsiClass>(), list);
return list;
}
public void getDefaultMethodsInner(PsiClass psiClass, Set<PsiClass> watched, List<PsiMethod> methods) {
if (watched.contains(psiClass)) return;
watched.add(psiClass);
methods.addAll(getDefaultMethods(psiClass.getQualifiedName()));
for (PsiClass aClass : psiClass.getSupers()) {
getDefaultMethodsInner(aClass, watched, methods);
}
}
public void addCategoryMethods(String fromClass, Map<String, List<PsiMethod>> toMap, NotNullFunction<PsiMethod, PsiMethod> converter) {
PsiClass categoryClass = JavaPsiFacade.getInstance(myProject).findClass(fromClass, GlobalSearchScope.allScope(myProject));
if (categoryClass != null) {