diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java index 5ff1ade5b9e0..eb1ca8032980 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/CollectClassMembersUtil.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.lang.resolve; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Trinity; import com.intellij.psi.*; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.util.*; @@ -37,28 +36,56 @@ import java.util.Set; * @author ven */ public class CollectClassMembersUtil { - private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.lang.resolve.CollectClassMembersUtil"); - private static final Key, Map>, Map>>> CACHED_MEMBERS = Key.create("CACHED_CLASS_MEMBERS"); + private static class ClassMembers { + private final Map myFields; + private final Map> myMethods; + private final Map myInnerClasses; - private static final Key, Map>, Map>>> CACHED_MEMBERS_INCLUDING_SYNTHETIC = Key.create("CACHED_MEMBERS_INCLUDING_SYNTHETIC"); + private ClassMembers(@NotNull Map fields, + @NotNull Map> methods, + @NotNull Map innerClasses) { + myFields = fields; + myMethods = methods; + myInnerClasses = innerClasses; + } + + public static ClassMembers create(@NotNull Map first, + @NotNull Map> second, + @NotNull Map third) { + return new ClassMembers(first, second, third); + } + + private Map getFields() { + return myFields; + } + + private Map> getMethods() { + return myMethods; + } + + private Map getInnerClasses() { + return myInnerClasses; + } + } + + private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.lang.resolve.CollectClassMembersUtil"); + private static final Key> CACHED_MEMBERS = Key.create("CACHED_CLASS_MEMBERS"); + + private static final Key> CACHED_MEMBERS_INCLUDING_SYNTHETIC = Key.create("CACHED_MEMBERS_INCLUDING_SYNTHETIC"); private CollectClassMembersUtil() { } public static Map> getAllMethods(final PsiClass aClass, boolean includeSynthetic) { - return getCachedMembers(aClass, includeSynthetic).getSecond(); + return getCachedMembers(aClass, includeSynthetic).getMethods(); } @NotNull - private static Trinity, Map>, Map> getCachedMembers( - PsiClass aClass, - boolean includeSynthetic) { + private static ClassMembers getCachedMembers(@NotNull PsiClass aClass, boolean includeSynthetic) { LOG.assertTrue(aClass.isValid()); - Key, Map>, Map>>> key = - includeSynthetic ? CACHED_MEMBERS_INCLUDING_SYNTHETIC : CACHED_MEMBERS; - CachedValue, Map>, Map>> cachedValue = - aClass.getUserData(key); + Key> key = includeSynthetic ? CACHED_MEMBERS_INCLUDING_SYNTHETIC : CACHED_MEMBERS; + CachedValue cachedValue = aClass.getUserData(key); if (cachedValue == null) { cachedValue = buildCache(aClass, includeSynthetic); aClass.putUserData(key, cachedValue); @@ -66,37 +93,38 @@ public class CollectClassMembersUtil { return cachedValue.getValue(); } - public static Map getAllInnerClasses(final PsiClass aClass, boolean includeSynthetic) { - return getCachedMembers(aClass, includeSynthetic).getThird(); + public static Map getAllInnerClasses(@NotNull final PsiClass aClass, boolean includeSynthetic) { + return getCachedMembers(aClass, includeSynthetic).getInnerClasses(); } - public static Map getAllFields(final PsiClass aClass, boolean includeSynthetic) { - return getCachedMembers(aClass, includeSynthetic).getFirst(); + public static Map getAllFields(@NotNull final PsiClass aClass, boolean includeSynthetic) { + return getCachedMembers(aClass, includeSynthetic).getFields(); } - public static Map getAllFields(final PsiClass aClass) { + public static Map getAllFields(@NotNull final PsiClass aClass) { return getAllFields(aClass, true); } - private static CachedValue, Map>, Map>> buildCache(final PsiClass aClass, final boolean includeSynthetic) { - return CachedValuesManager.getManager(aClass.getProject()).createCachedValue(new CachedValueProvider, Map>, Map>>() { - public Result, Map>, Map>> compute() { + private static CachedValue buildCache(@NotNull final PsiClass aClass, final boolean includeSynthetic) { + return CachedValuesManager.getManager(aClass.getProject()).createCachedValue(new CachedValueProvider() { + public Result compute() { Map allFields = new HashMap(); Map> allMethods = new HashMap>(); Map allInnerClasses = new HashMap(); processClass(aClass, allFields, allMethods, allInnerClasses, new HashSet(), PsiSubstitutor.EMPTY, includeSynthetic); - return Result.create(Trinity.create(allFields, allMethods, allInnerClasses), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + return Result.create(ClassMembers.create(allFields, allMethods, allInnerClasses), + PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } }, false); } - private static void processClass(PsiClass aClass, - Map allFields, - Map> allMethods, - Map allInnerClasses, - Set visitedClasses, - PsiSubstitutor substitutor, + private static void processClass(@NotNull PsiClass aClass, + @NotNull Map allFields, + @NotNull Map> allMethods, + @NotNull Map allInnerClasses, + @NotNull Set visitedClasses, + @NotNull PsiSubstitutor substitutor, boolean includeSynthetic) { LOG.assertTrue(aClass.isValid()); @@ -110,11 +138,12 @@ public class CollectClassMembersUtil { else if (hasExplicitVisibilityModifiers(field)) { final CandidateInfo candidateInfo = allFields.get(name); final PsiElement element = candidateInfo.getElement(); - if (element instanceof GrField && (((GrField)element).getModifierList() == null || - !(((GrField)element).getModifierList()).hasExplicitVisibilityModifiers()) && - aClass == ((GrField)element).getContainingClass()) { - //replace property-field with field with explicit visibilityModifier - allFields.put(name, new CandidateInfo(field, substitutor)); + if (element instanceof GrField) { + final GrModifierList modifierList = ((GrField)element).getModifierList(); + if ((modifierList == null || !modifierList.hasExplicitVisibilityModifiers()) && aClass == ((GrField)element).getContainingClass()) { + //replace property-field with field with explicit visibilityModifier + allFields.put(name, new CandidateInfo(field, substitutor)); + } } } } @@ -139,15 +168,15 @@ public class CollectClassMembersUtil { } } - public static PsiField[] getFields(PsiClass aClass, boolean includeSynthetic) { + public static PsiField[] getFields(@NotNull PsiClass aClass, boolean includeSynthetic) { return includeSynthetic || !(aClass instanceof GrTypeDefinition) ? aClass.getFields() : ((GrTypeDefinition)aClass).getCodeFields(); } - public static PsiMethod[] getMethods(PsiClass aClass, boolean includeSynthetic) { + public static PsiMethod[] getMethods(@NotNull PsiClass aClass, boolean includeSynthetic) { return includeSynthetic || !(aClass instanceof GrTypeDefinition) ? aClass.getMethods() : ((GrTypeDefinition)aClass).getCodeMethods(); } - private static boolean hasExplicitVisibilityModifiers(PsiField field) { + private static boolean hasExplicitVisibilityModifiers(@NotNull PsiField field) { if (field instanceof GrField) { final GrModifierList list = (GrModifierList)field.getModifierList(); return list == null || list.hasExplicitVisibilityModifiers(); @@ -157,7 +186,9 @@ public class CollectClassMembersUtil { } } - private static void addMethod(Map> allMethods, PsiMethod method, PsiSubstitutor substitutor) { + private static void addMethod(@NotNull Map> allMethods, + @NotNull PsiMethod method, + @NotNull PsiSubstitutor substitutor) { String name = method.getName(); List methods = allMethods.get(name); if (methods == null) {