@NotNull private static List<PsiClass> getInnerClassesForResolve( @NotNull final GrTypeDefinition grType, @Nullable final PsiElement lastParent, @NotNull final PsiElement place) { if (lastParent instanceof GrReferenceList || PsiTreeUtil.getParentOfType(place, GrReferenceList.class) != null) { return Arrays.asList(grType.getInnerClasses()); } List<PsiClass> classes = RecursionManager.doPreventingRecursion( grType, true, new Computable<List<PsiClass>>() { @Override public List<PsiClass> compute() { List<PsiClass> result = new ArrayList<PsiClass>(); for (CandidateInfo info : CollectClassMembersUtil.getAllInnerClasses(grType, false).values()) { final PsiClass inner = (PsiClass) info.getElement(); final PsiClass containingClass = inner.getContainingClass(); assert containingClass != null; if (lastParent == null || !containingClass.isInterface() || PsiTreeUtil.isAncestor(containingClass, place, false)) { ContainerUtil.addIfNotNull(result, inner); } } return result; } }); if (classes == null) { return Arrays.asList(grType.getInnerClasses()); } return classes; }
public static boolean processDeclarations( @NotNull GrTypeDefinition grType, @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, @Nullable PsiElement lastParent, @NotNull PsiElement place) { if (place instanceof GrCodeReferenceElement && lastParent instanceof GrModifierList) { final PsiElement possibleAnnotation = PsiTreeUtil.skipParentsOfType(place, GrCodeReferenceElement.class); if (possibleAnnotation instanceof GrAnnotation && possibleAnnotation.getParent() == lastParent) { return true; // don't process class members while resolving annotation which annotates // current class } } for (final PsiTypeParameter typeParameter : grType.getTypeParameters()) { if (!processElement(processor, typeParameter, state)) return false; } NameHint nameHint = processor.getHint(NameHint.KEY); String name = nameHint == null ? null : nameHint.getName(state); ClassHint classHint = processor.getHint(ClassHint.KEY); final PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY); final PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject()); boolean processInstanceMethods = (shouldProcessMethods(classHint) || shouldProcessProperties(classHint)) && shouldProcessInstanceMembers(grType, lastParent); LanguageLevel level = PsiUtil.getLanguageLevel(place); if (shouldProcessProperties(classHint)) { Map<String, CandidateInfo> fieldsMap = CollectClassMembersUtil.getAllFields(grType); if (name != null) { CandidateInfo fieldInfo = fieldsMap.get(name); if (fieldInfo != null) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, fieldInfo)) { return false; } } else if (grType.isTrait() && lastParent != null) { PsiField field = findFieldByName(grType, name, false, true); if (field != null && field.hasModifierProperty(PsiModifier.PUBLIC)) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, new CandidateInfo(field, PsiSubstitutor.EMPTY))) { return false; } } } } else { for (CandidateInfo info : fieldsMap.values()) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, info)) { return false; } } if (grType.isTrait() && lastParent != null) { for (PsiField field : CollectClassMembersUtil.getFields(grType, true)) { if (field.hasModifierProperty(PsiModifier.PUBLIC)) { if (!processField( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, new CandidateInfo(field, PsiSubstitutor.EMPTY))) { return false; } } } } } } if (shouldProcessMethods(classHint)) { Map<String, List<CandidateInfo>> methodsMap = CollectClassMembersUtil.getAllMethods(grType, true); boolean isPlaceGroovy = place.getLanguage() == GroovyFileType.GROOVY_LANGUAGE; if (name == null) { for (List<CandidateInfo> list : methodsMap.values()) { for (CandidateInfo info : list) { if (!processMethod( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, isPlaceGroovy, info)) { return false; } } } } else { List<CandidateInfo> byName = methodsMap.get(name); if (byName != null) { for (CandidateInfo info : byName) { if (!processMethod( grType, processor, state, place, processInstanceMethods, substitutor, factory, level, isPlaceGroovy, info)) { return false; } } } } } final GrTypeDefinitionBody body = grType.getBody(); if (body != null) { if (shouldProcessClasses(classHint)) { for (PsiClass innerClass : getInnerClassesForResolve(grType, lastParent, place)) { final String innerClassName = innerClass.getName(); if (nameHint != null && !innerClassName.equals(nameHint.getName(state))) { continue; } if (!processor.execute(innerClass, state)) { return false; } } } } return true; }