From ab46d8b8ce943b075543b72cf46f7ac499c61133 Mon Sep 17 00:00:00 2001 From: Peter Gromov Date: Tue, 17 Dec 2019 22:18:32 +0100 Subject: [PATCH] PsiClassImplUtil: don't calculate substitutors when searching for members by name, e.g. static classes (IDEA-228814) GitOrigin-RevId: 63f32377d8a4475ece1f97a1ab383f04da842801 --- .../intellij/psi/impl/PsiClassImplUtil.java | 112 ++++++------------ .../openapi/util/RecursionManager.java | 1 - 2 files changed, 39 insertions(+), 74 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java index f3b26378b8fc..c6b19e4c5c68 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java @@ -15,12 +15,9 @@ import com.intellij.psi.*; import com.intellij.psi.impl.java.stubs.PsiClassReferenceListStub; import com.intellij.psi.impl.source.ClassInnerStuffCache; import com.intellij.psi.impl.source.PsiImmediateClassType; -import com.intellij.psi.infos.MethodCandidateInfo; -import com.intellij.psi.scope.ElementClassFilter; import com.intellij.psi.scope.ElementClassHint; import com.intellij.psi.scope.NameHint; import com.intellij.psi.scope.PsiScopeProcessor; -import com.intellij.psi.scope.processor.FilterScopeProcessor; import com.intellij.psi.scope.processor.MethodResolverProcessor; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; @@ -34,6 +31,7 @@ import com.intellij.ui.icons.RowIcon; import com.intellij.util.*; import com.intellij.util.containers.ConcurrentFactoryMap; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.JBTreeTraverser; import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; @@ -354,35 +352,20 @@ public class PsiClassImplUtil { final List allMembers = new ArrayList<>(); map.put(ALL, allMembers); - ElementClassFilter filter = key == MemberType.CLASS ? ElementClassFilter.CLASS : - key == MemberType.METHOD ? ElementClassFilter.METHOD : - ElementClassFilter.FIELD; - final ElementClassHint classHint = kind -> key == MemberType.CLASS && kind == ElementClassHint.DeclarationKind.CLASS || - key == MemberType.FIELD && (kind == ElementClassHint.DeclarationKind.FIELD || kind == ElementClassHint.DeclarationKind.ENUM_CONST) || - key == MemberType.METHOD && kind == ElementClassHint.DeclarationKind.METHOD; - FilterScopeProcessor processor = new FilterScopeProcessor(filter) { - @Override - protected void add(@NotNull PsiElement element, @NotNull PsiSubstitutor substitutor) { - if (key == MemberType.CLASS && element instanceof PsiClass || - key == MemberType.METHOD && element instanceof PsiMethod || - key == MemberType.FIELD && element instanceof PsiField) { - PsiUtilCore.ensureValid(element); - allMembers.add((PsiMember)element); - String currentName = ((PsiMember)element).getName(); - List listByName = map.computeIfAbsent(currentName, __ -> new SmartList<>()); - listByName.add((PsiMember)element); - } + JBTreeTraverser allSupers = JBTreeTraverser + .from((PsiClass c) -> ContainerUtil.mapNotNull(c.getSupers(), s -> PsiSuperMethodUtil.correctClassByScope(s, scope))) + .unique() + .withRoot(psiClass); + for (PsiClass eachSuper : allSupers) { + PsiMember[] members = key == MemberType.CLASS ? eachSuper.getInnerClasses() : + key == MemberType.METHOD ? eachSuper.getMethods() : + eachSuper.getFields(); + for (PsiMember element : members) { + PsiUtilCore.ensureValid(element); + allMembers.add(element); + map.computeIfAbsent(element.getName(), __ -> new SmartList<>()).add(element); } - - @Override - public K getHint(@NotNull Key hintKey) { - //noinspection unchecked - return ElementClassHint.KEY == hintKey ? (K)classHint : super.getHint(hintKey); - } - }; - - processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), null, null, psiClass, false, - PsiUtil.getLanguageLevel(psiClass), scope); + } Map result = new THashMap<>(); for (Map.Entry> entry : map.entrySet()) { result.put(entry.getKey(), entry.getValue().toArray(PsiMember.EMPTY_ARRAY)); @@ -397,7 +380,7 @@ public class PsiClassImplUtil { @Override public CachedValueProvider.Result> compute(@NotNull final PsiClass myClass) { Map map = ConcurrentFactoryMap.createMap(scope -> new MembersMap(myClass, scope)); - return CachedValueProvider.Result.create(map, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + return CachedValueProvider.Result.create(map, PsiModificationTracker.MODIFICATION_COUNT); } } @@ -454,7 +437,7 @@ public class PsiClassImplUtil { return processCachedMembersByName(aClass, processor, state, visited, last, place, isRaw, substitutor, getValues(aClass).getValue(aClass).get(resolveScope), name, languageLevel, resolveScope); } - return processDeclarationsInClassNotCached(aClass, processor, state, visited, last, place, isRaw, languageLevel, resolveScope); + return processClassMembersWithAllNames(aClass, processor, state, visited, last, place, isRaw, languageLevel, resolveScope); } private static boolean processCachedMembersByName(@NotNull final PsiClass aClass, @@ -474,13 +457,16 @@ public class PsiClassImplUtil { final PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject()); @Override public PsiSubstitutor fun(PsiMember member) { - PsiClass containingClass = ObjectUtils.assertNotNull(member.getContainingClass()); - PsiSubstitutor superSubstitutor = hierarchy.getSuperMembersSubstitutor(containingClass, languageLevel); - PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, - superSubstitutor == null ? PsiSubstitutor.EMPTY : superSubstitutor, - aClass, substitutor, factory, languageLevel); + PsiSubstitutor finalSubstitutor = member.hasModifierProperty(PsiModifier.STATIC) ? substitutor : obtainSubstitutor(member); return member instanceof PsiMethod ? checkRaw(isRaw, factory, (PsiMethod)member, finalSubstitutor) : finalSubstitutor; } + + private PsiSubstitutor obtainSubstitutor(PsiMember member) { + PsiClass containingClass = ObjectUtils.assertNotNull(member.getContainingClass()); + PsiSubstitutor superSubstitutor = ObjectUtils.notNull(hierarchy.getSuperMembersSubstitutor(containingClass, languageLevel), + PsiSubstitutor.EMPTY); + return obtainFinalSubstitutor(containingClass, superSubstitutor, aClass, substitutor, factory, languageLevel); + } }; final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY); @@ -632,33 +618,24 @@ public class PsiClassImplUtil { return ((PsiClassType)type).resolveGenerics().getSubstitutor(); } - private static boolean processDeclarationsInClassNotCached(@NotNull PsiClass aClass, - @NotNull final PsiScopeProcessor processor, - @NotNull final ResolveState state, - @Nullable Set visited, - final PsiElement last, - @NotNull final PsiElement place, - final boolean isRaw, - @NotNull final LanguageLevel languageLevel, - @NotNull final GlobalSearchScope resolveScope) { + private static boolean processClassMembersWithAllNames(@NotNull PsiClass aClass, + @NotNull final PsiScopeProcessor processor, + @NotNull final ResolveState state, + @Nullable Set visited, + final PsiElement last, + @NotNull final PsiElement place, + final boolean isRaw, + @NotNull final LanguageLevel languageLevel, + @NotNull final GlobalSearchScope resolveScope) { ProgressManager.checkCanceled(); if (visited == null) visited = new THashSet<>(); if (!visited.add(aClass)) return true; processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass); final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY); - final NameHint nameHint = processor.getHint(NameHint.KEY); - if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) { - if (nameHint != null) { - final PsiField fieldByName = aClass.findFieldByName(nameHint.getName(state), false); - if (fieldByName != null && !processor.execute(fieldByName, state)) return false; - } - else { - final PsiField[] fields = aClass.getFields(); - for (final PsiField field : fields) { - if (!processor.execute(field, state)) return false; - } + for (PsiField field : aClass.getFields()) { + if (!processor.execute(field, state)) return false; } } @@ -666,8 +643,7 @@ public class PsiClassImplUtil { if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) { PsiSubstitutor baseSubstitutor = state.get(PsiSubstitutor.KEY); - final PsiMethod[] methods = nameHint != null ? aClass.findMethodsByName(nameHint.getName(state), false) : aClass.getMethods(); - for (final PsiMethod method : methods) { + for (PsiMethod method : aClass.getMethods()) { PsiSubstitutor finalSubstitutor = checkRaw(isRaw, factory, method, baseSubstitutor); ResolveState methodState = finalSubstitutor == baseSubstitutor ? state : state.put(PsiSubstitutor.KEY, finalSubstitutor); if (!processor.execute(method, methodState)) return false; @@ -682,18 +658,8 @@ public class PsiClassImplUtil { } if (!(last instanceof PsiReferenceList) && !(last instanceof PsiModifierList)) { - // Inners - if (nameHint != null) { - final PsiClass inner = aClass.findInnerClassByName(nameHint.getName(state), false); - if (inner != null) { - if (!processor.execute(inner, state)) return false; - } - } - else { - final PsiClass[] inners = aClass.getInnerClasses(); - for (final PsiClass inner : inners) { - if (!processor.execute(inner, state)) return false; - } + for (PsiClass inner : aClass.getInnerClasses()) { + if (!processor.execute(inner, state)) return false; } } } @@ -1056,7 +1022,7 @@ public class PsiClassImplUtil { @NotNull PsiManager manager) { if (list == null) return false; if (list instanceof StubBasedPsiElement) { - StubElement stub = ((StubBasedPsiElement)list).getStub(); + StubElement stub = ((StubBasedPsiElement)list).getStub(); if (stub instanceof PsiClassReferenceListStub && baseName != null) { // classStub.getReferencedNames() is cheaper than getReferencedTypes() PsiClassReferenceListStub classStub = (PsiClassReferenceListStub)stub; diff --git a/platform/util/src/com/intellij/openapi/util/RecursionManager.java b/platform/util/src/com/intellij/openapi/util/RecursionManager.java index 812a8c3f33c0..3b5835c2f6fd 100644 --- a/platform/util/src/com/intellij/openapi/util/RecursionManager.java +++ b/platform/util/src/com/intellij/openapi/util/RecursionManager.java @@ -389,7 +389,6 @@ public class RecursionManager { "com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil.isPolyExpression(", // inner class imports "com.intellij.psi.impl.source.PsiJavaFileBaseImpl.processDeclarations(", - "com.intellij.psi.impl.PsiClassImplUtil.getScopeCorrectedSuperTypes(", // IDEA-212671 "com.intellij.xml.impl.schema.XmlNSDescriptorImpl.getRedefinedElementDescriptor(",