diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java index e265644d9191..53e05009bcfc 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dgm/DGMMemberContributor.java @@ -17,17 +17,19 @@ package org.jetbrains.plugins.groovy.dgm; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Couple; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiType; -import com.intellij.psi.ResolveState; +import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor; import java.util.List; +import java.util.concurrent.ConcurrentMap; /** * Provides members from extension classes referenced in {@code META-INF/services/org.codehaus.groovy.runtime.ExtensionModule}. @@ -40,34 +42,49 @@ public class DGMMemberContributor extends NonCodeMembersContributor { @NotNull PsiScopeProcessor processor, @NotNull PsiElement place, @NotNull ResolveState state) { - Project project = place.getProject(); - GlobalSearchScope resolveScope = place.getResolveScope(); - GroovyPsiManager groovyPsiManager = GroovyPsiManager.getInstance(project); + final Project project = place.getProject(); - Couple> extensions = GroovyExtensionProvider.getInstance(project).collectExtensions(resolveScope); - - List instanceCategories = extensions.getFirst(); - List staticCategories = extensions.getSecond(); - - if (!processCategories(qualifierType, processor, state, project, resolveScope, groovyPsiManager, instanceCategories, false)) return; - if (!processCategories(qualifierType, processor, state, project, resolveScope, groovyPsiManager, staticCategories, true)) return; - } - - private static boolean processCategories(PsiType qualifierType, - PsiScopeProcessor processor, - @NotNull ResolveState state, - Project project, - GlobalSearchScope resolveScope, - GroovyPsiManager groovyPsiManager, List instanceCategories, - boolean isStatic) { - for (String category : instanceCategories) { - PsiClass clazz = groovyPsiManager.findClassWithCache(category, resolveScope); - if (clazz != null) { - if (!GdkMethodHolder.getHolderForClass(clazz, isStatic, resolveScope).processMethods(processor, state, qualifierType, project)) { - return false; + ConcurrentMap> map = CachedValuesManager.getManager(project).getCachedValue( + project, new CachedValueProvider>>() { + @Nullable + @Override + public Result>> compute() { + ConcurrentMap> value = ContainerUtil.createConcurrentSoftValueMap(); + return Result.create(value, PsiModificationTracker.MODIFICATION_COUNT); } + }); + + GlobalSearchScope scope = place.getResolveScope(); + List gdkMethods = map.get(scope); + if (gdkMethods == null) { + map.put(scope, gdkMethods = calcGdkMethods(project, scope)); + } + + for (GdkMethodHolder holder : gdkMethods) { + if (!holder.processMethods(processor, state, qualifierType, project)) { + return; } } - return true; + } + + @NotNull + private static List calcGdkMethods(Project project, GlobalSearchScope resolveScope) { + List gdkMethods = ContainerUtil.newArrayList(); + + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + Couple> extensions = GroovyExtensionProvider.getInstance(project).collectExtensions(resolveScope); + for (String category : extensions.getFirst()) { + PsiClass clazz = facade.findClass(category, resolveScope); + if (clazz != null) { + gdkMethods.add(GdkMethodHolder.getHolderForClass(clazz, false, resolveScope)); + } + } + for (String category : extensions.getSecond()) { + PsiClass clazz = facade.findClass(category, resolveScope); + if (clazz != null) { + gdkMethods.add(GdkMethodHolder.getHolderForClass(clazz, true, resolveScope)); + } + } + return gdkMethods; } }