/** @return were javadoc params used */ public static void collectAnnotationValues( final Map<String, Collection<String>> results, PsiMethod[] psiMethods, PsiClass... classes) { final Set<String> test = new HashSet<>(1); test.add(TEST_ANNOTATION_FQN); ContainerUtil.addAll(test, CONFIG_ANNOTATIONS_FQN); if (psiMethods != null) { for (final PsiMethod psiMethod : psiMethods) { ApplicationManager.getApplication() .runReadAction( () -> appendAnnotationAttributeValues( results, AnnotationUtil.findAnnotation(psiMethod, test), psiMethod)); } } else { for (final PsiClass psiClass : classes) { ApplicationManager.getApplication() .runReadAction( () -> { if (psiClass != null && hasTest(psiClass)) { appendAnnotationAttributeValues( results, AnnotationUtil.findAnnotation(psiClass, test), psiClass); PsiMethod[] methods = psiClass.getMethods(); for (PsiMethod method : methods) { if (method != null) { appendAnnotationAttributeValues( results, AnnotationUtil.findAnnotation(method, test), method); } } } }); } } }
private void processListenerProperties(@NotNull PsiMethod method) { if (!method.getName().startsWith("add") || method.getParameterList().getParametersCount() != 1) return; final PsiParameter parameter = method.getParameterList().getParameters()[0]; final PsiType type = parameter.getType(); if (!(type instanceof PsiClassType)) return; final PsiClassType classType = (PsiClassType) type; final PsiClass listenerClass = classType.resolve(); if (listenerClass == null) return; final PsiMethod[] listenerMethods = listenerClass.getMethods(); if (!InheritanceUtil.isInheritorOrSelf(listenerClass, myEventListener, true)) return; for (PsiMethod listenerMethod : listenerMethods) { final String name = listenerMethod.getName(); if (myPropertyNames.add(name)) { LookupElementBuilder builder = LookupElementBuilder.create( generatePropertyResolveResult(name, listenerMethod, null, null), name) .withIcon(JetgroovyIcons.Groovy.Property); myConsumer.consume(builder); } } }
private static void collectMethods( PsiClass currentClass, PsiSubstitutor currentClassSubstitutor, boolean shouldProcessDeprecated, GrTypeDefinition classToDelegateTo, Collection<PsiMethod> collector, boolean keepParameterAnnotations) { final List<PsiMethod> methods; if (currentClass instanceof GrTypeDefinition) { methods = new ArrayList<PsiMethod>(); GrClassImplUtil.collectMethodsFromBody((GrTypeDefinition) currentClass, methods); } else { methods = Arrays.asList(currentClass.getMethods()); } for (PsiMethod method : methods) { if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) continue; if (overridesObjectOrGroovyObject(method)) continue; if (!shouldProcessDeprecated && PsiImplUtil.getAnnotation(method, CommonClassNames.JAVA_LANG_DEPRECATED) != null) continue; collector.add( generateDelegateMethod( method, classToDelegateTo, currentClassSubstitutor, keepParameterAnnotations)); } }
/** * Adds all code methods of clazz add its super classes to signatures. Doesn't walk into * interfaces because all methods from them will be overloaded in any case. Besides Some of * interfaces came from delegates and they should be visited during the following processing. * * @param clazz current class * @param substitutor super class substitutor of clazz * @param signatures map to initialize * @param classes already visited classes */ private static void initializeSignatures( PsiClass clazz, PsiSubstitutor substitutor, Map<MethodSignature, PsiMethod> signatures, Set<PsiClass> classes) { if (clazz.isInterface()) return; if (classes.add(clazz)) { final List<PsiMethod> methods; if (clazz instanceof GrTypeDefinition) { methods = new ArrayList<PsiMethod>(); GrClassImplUtil.collectMethodsFromBody((GrTypeDefinition) clazz, methods); } else { methods = Arrays.asList(clazz.getMethods()); } for (PsiMethod method : methods) { addMethodChecked(signatures, method, substitutor, null); } for (PsiClassType type : getSuperTypes(clazz)) { final PsiClassType.ClassResolveResult result = type.resolveGenerics(); final PsiClass superClass = result.getElement(); if (superClass == null) continue; final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, clazz, substitutor); initializeSignatures(superClass, superClassSubstitutor, signatures, classes); } } }
/** * Filter the specified collection of classes to return only ones that contain any of the * specified values in the specified annotation parameter. For example, this method can be used to * return all classes that contain all tesng annotations that are in the groups 'foo' or 'bar'. */ public static Map<PsiClass, Collection<PsiMethod>> filterAnnotations( String parameter, Set<String> values, Collection<PsiClass> classes) { Map<PsiClass, Collection<PsiMethod>> results = new HashMap<>(); Set<String> test = new HashSet<>(1); test.add(TEST_ANNOTATION_FQN); ContainerUtil.addAll(test, CONFIG_ANNOTATIONS_FQN); for (PsiClass psiClass : classes) { if (isBrokenPsiClass(psiClass)) continue; PsiAnnotation annotation; try { annotation = AnnotationUtil.findAnnotation(psiClass, test); } catch (Exception e) { LOGGER.error( "Exception trying to findAnnotation on " + psiClass.getClass().getName() + ".\n\n" + e.getMessage()); annotation = null; } if (annotation != null) { if (isAnnotatedWithParameter(annotation, parameter, values)) { results.put(psiClass, new LinkedHashSet<>()); } } else { Collection<String> matches = extractAnnotationValuesFromJavaDoc(getTextJavaDoc(psiClass), parameter); for (String s : matches) { if (values.contains(s)) { results.put(psiClass, new LinkedHashSet<>()); break; } } } // we already have the class, no need to look through its methods PsiMethod[] methods = psiClass.getMethods(); for (PsiMethod method : methods) { if (method != null) { annotation = AnnotationUtil.findAnnotation(method, test); if (annotation != null) { if (isAnnotatedWithParameter(annotation, parameter, values)) { if (results.get(psiClass) == null) results.put(psiClass, new LinkedHashSet<>()); results.get(psiClass).add(method); } } else { Collection<String> matches = extractAnnotationValuesFromJavaDoc(getTextJavaDoc(psiClass), parameter); for (String s : matches) { if (values.contains(s)) { results.get(psiClass).add(method); } } } } } } return results; }
public static boolean containsJunitAnnotions(PsiClass psiClass) { if (psiClass != null) { for (PsiMethod method : psiClass.getMethods()) { if (containsJunitAnnotions(method)) { return true; } } } return false; }
static boolean isKotlinNamespaceClass(PsiClass psiClass) { if (JvmAbi.PACKAGE_CLASS.equals(psiClass.getName()) && !isKotlinClass(psiClass)) { for (PsiMethod method : psiClass.getMethods()) { if (hasAnnotation(method, JET_METHOD)) { return true; } } } return false; }
private static void getAllMethodsInner( PsiClass clazz, List<PsiMethod> allMethods, HashSet<PsiClass> visited) { if (visited.contains(clazz)) return; visited.add(clazz); ContainerUtil.addAll(allMethods, clazz.getMethods()); final PsiClass[] supers = clazz.getSupers(); for (PsiClass aSuper : supers) { getAllMethodsInner(aSuper, allMethods, visited); } }
private void registerNestedClosures(DfaInstructionState instructionState, PsiClass nestedClass) { DfaMemoryStateImpl closureState = createClosureState(instructionState.getMemoryState()); for (PsiMethod method : nestedClass.getMethods()) { PsiCodeBlock body = method.getBody(); if (body != null) { myNestedClosures.putValue(body, closureState); } } for (PsiClassInitializer initializer : nestedClass.getInitializers()) { myNestedClosures.putValue(initializer.getBody(), closureState); } for (PsiField field : nestedClass.getFields()) { myNestedClosures.putValue(field, closureState); } }
private List<PsiClass> calculateInterfacesSupported() { final List<PsiClass> out = new ArrayList<PsiClass>(); final PsiClass[] supers = sourceClass.getSupers(); for (PsiClass superClass : supers) { if (!superClass.isInterface()) { continue; } final PsiMethod[] superclassMethods = superClass.getMethods(); if (superclassMethods.length == 0) { continue; } boolean allMethodsCovered = true; for (PsiMethod method : superclassMethods) { boolean isCovered = false; for (PsiMethod movedMethod : methods) { if (isSuperMethod(method, movedMethod)) { isCovered = true; break; } } if (!isCovered) { allMethodsCovered = false; break; } } if (allMethodsCovered) { out.add(superClass); } } final Project project = sourceClass.getProject(); final PsiManager manager = sourceClass.getManager(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); if (usesDefaultSerialization(sourceClass)) { final PsiClass serializable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", scope); out.add(serializable); } if (usesDefaultClone(sourceClass)) { final PsiClass cloneable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Cloneable", scope); out.add(cloneable); } return out; }
@NotNull public static Map<String, PsiMethod> getAllProperties( @NotNull final PsiClass psiClass, final boolean acceptSetters, final boolean acceptGetters, final boolean includeSuperClass) { final Map<String, PsiMethod> map = new HashMap<String, PsiMethod>(); final PsiMethod[] methods = includeSuperClass ? psiClass.getAllMethods() : psiClass.getMethods(); for (PsiMethod method : methods) { if (filterMethods(method)) continue; if (acceptSetters && PropertyUtil.isSimplePropertySetter(method) || acceptGetters && PropertyUtil.isSimplePropertyGetter(method)) { map.put(PropertyUtil.getPropertyName(method), method); } } return map; }
public static String[] getReadableProperties(PsiClass aClass, boolean includeSuperClass) { List<String> result = new ArrayList<String>(); PsiMethod[] methods; if (includeSuperClass) { methods = aClass.getAllMethods(); } else { methods = aClass.getMethods(); } for (PsiMethod method : methods) { if ("java.lang.Object".equals(method.getContainingClass().getQualifiedName())) continue; if (isSimplePropertyGetter(method)) { result.add(getPropertyName(method)); } } return ArrayUtil.toStringArray(result); }
private static void addMethodsUsages( final PsiClass aClass, final Processor<UsageInfo> results, final JavaClassFindUsagesOptions options) { if (options.isIncludeInherited) { final PsiManager manager = aClass.getManager(); PsiMethod[] methods = aClass.getAllMethods(); MethodsLoop: for (int i = 0; i < methods.length; i++) { final PsiMethod method = methods[i]; // filter overriden methods MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY); for (int j = 0; j < i; j++) { if (methodSignature.equals(methods[j].getSignature(PsiSubstitutor.EMPTY))) continue MethodsLoop; } final PsiClass methodClass = method.getContainingClass(); if (methodClass != null && manager.areElementsEquivalent(methodClass, aClass)) { addElementUsages(methods[i], results, options); } else { MethodReferencesSearch.search( new MethodReferencesSearch.SearchParameters( method, options.searchScope, true, options.fastTrack)) .forEach( new PsiReferenceProcessorAdapter( new PsiReferenceProcessor() { @Override public boolean execute(PsiReference reference) { addResultFromReference( reference, methodClass, manager, aClass, results, options); return true; } })); } } } else { for (PsiMethod method : aClass.getMethods()) { addElementUsages(method, results, options); } } }
@Override public void visitAnnotationNameValuePair(GrAnnotationNameValuePair nameValuePair) { if (myExpression.equals(nameValuePair.getValue())) { final PsiClass annot = ResolveUtil.resolveAnnotation(nameValuePair.getParent()); if (annot != null) { final String name = nameValuePair.getName(); if (name != null) { final PsiMethod[] attrs = annot.findMethodsByName(name, false); if (attrs.length > 0) { PsiType type = attrs[0].getReturnType(); while (type instanceof PsiArrayType) type = ((PsiArrayType) type).getComponentType(); if (type != null && isAcceptableAnnotationValueType(type)) { myResult = createSimpleSubTypeResult(type); } } } else { final PsiMethod[] valueAttr = annot.findMethodsByName("value", false); boolean canHaveSimpleExpr = valueAttr.length > 0; final PsiMethod[] methods = annot.getMethods(); for (PsiMethod method : methods) { if (!("value".equals(method.getName()) || method instanceof PsiAnnotationMethod && ((PsiAnnotationMethod) method).getDefaultValue() != null)) { canHaveSimpleExpr = false; } } if (canHaveSimpleExpr) { PsiType type = valueAttr[0].getReturnType(); while (type instanceof PsiArrayType) type = ((PsiArrayType) type).getComponentType(); if (type != null && isAcceptableAnnotationValueType(type)) { myResult = createSimpleSubTypeResult(type); } } } } } }
@NotNull private static List<PsiMember> findByMap( @NotNull PsiClass aClass, String name, boolean checkBases, @NotNull MemberType type) { if (name == null) return Collections.emptyList(); if (checkBases) { Map<String, List<Pair<PsiMember, PsiSubstitutor>>> allMethodsMap = getMap(aClass, type); List<Pair<PsiMember, PsiSubstitutor>> list = allMethodsMap.get(name); if (list == null) return Collections.emptyList(); List<PsiMember> ret = new ArrayList<PsiMember>(list.size()); for (final Pair<PsiMember, PsiSubstitutor> info : list) { ret.add(info.getFirst()); } return ret; } else { PsiMember[] members = null; switch (type) { case METHOD: members = aClass.getMethods(); break; case CLASS: members = aClass.getInnerClasses(); break; case FIELD: members = aClass.getFields(); break; } List<PsiMember> list = new ArrayList<PsiMember>(); for (PsiMember member : members) { if (name.equals(member.getName())) { list.add(member); } } return list; } }
private static boolean containsOnlyPrivates(final PsiClass aClass) { final PsiField[] fields = aClass.getFields(); for (PsiField field : fields) { if (!field.hasModifierProperty(PsiModifier.PRIVATE)) return false; } final PsiMethod[] methods = aClass.getMethods(); for (PsiMethod method : methods) { if (!method.hasModifierProperty(PsiModifier.PRIVATE)) { if (method.isConstructor()) { // skip non-private constructors with call to super only final PsiCodeBlock body = method.getBody(); if (body != null) { final PsiStatement[] statements = body.getStatements(); if (statements.length == 0) continue; if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) { final PsiExpression expression = ((PsiExpressionStatement) statements[0]).getExpression(); if (expression instanceof PsiMethodCallExpression) { PsiReferenceExpression methodExpression = ((PsiMethodCallExpression) expression).getMethodExpression(); if (methodExpression.getText().equals(PsiKeyword.SUPER)) { continue; } } } } } return false; } } final PsiClass[] inners = aClass.getInnerClasses(); for (PsiClass inner : inners) { if (!inner.hasModifierProperty(PsiModifier.PRIVATE)) return false; } return true; }
@Nullable public static PsiMethod findPropertySetter( PsiClass aClass, String propertyName, boolean isStatic, boolean checkSuperClasses) { if (aClass == null) return null; PsiMethod[] methods; if (checkSuperClasses) { methods = aClass.getAllMethods(); } else { methods = aClass.getMethods(); } for (PsiMethod method : methods) { if (method.hasModifierProperty(PsiModifier.STATIC) != isStatic) continue; if (isSimplePropertySetter(method)) { if (getPropertyNameBySetter(method).equals(propertyName)) { return method; } } } return null; }
@Override @NotNull public PsiElement[] getSecondaryElements() { PsiElement element = getPsiElement(); if (ApplicationManager.getApplication().isUnitTestMode()) return PsiElement.EMPTY_ARRAY; if (element instanceof PsiField) { final PsiField field = (PsiField) element; PsiClass containingClass = field.getContainingClass(); if (containingClass != null) { String fieldName = field.getName(); final String propertyName = JavaCodeStyleManager.getInstance(getProject()) .variableNameToPropertyName(fieldName, VariableKind.FIELD); Set<PsiMethod> accessors = new THashSet<PsiMethod>(); boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); PsiMethod getter = PropertyUtil.findPropertyGetterWithType( propertyName, isStatic, field.getType(), ContainerUtil.iterate(containingClass.getMethods())); if (getter != null) accessors.add(getter); PsiMethod setter = PropertyUtil.findPropertySetterWithType( propertyName, isStatic, field.getType(), ContainerUtil.iterate(containingClass.getMethods())); if (setter != null) accessors.add(setter); accessors.addAll(PropertyUtil.getAccessors(containingClass, fieldName)); if (!accessors.isEmpty()) { final boolean doSearch; boolean containsPhysical = ContainerUtil.find( accessors, new Condition<PsiMethod>() { @Override public boolean value(PsiMethod psiMethod) { return psiMethod.isPhysical(); } }) != null; if (!containsPhysical) { doSearch = true; } else { doSearch = Messages.showOkCancelDialog( FindBundle.message("find.field.accessors.prompt", fieldName), FindBundle.message("find.field.accessors.title"), CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText(), Messages.getQuestionIcon()) == DialogWrapper.OK_EXIT_CODE; } if (doSearch) { final Set<PsiElement> elements = new THashSet<PsiElement>(); for (PsiMethod accessor : accessors) { ContainerUtil.addAll( elements, SuperMethodWarningUtil.checkSuperMethods(accessor, ACTION_STRING)); } return PsiUtilBase.toPsiElementArray(elements); } } } } return super.getSecondaryElements(); }
private static void completeAnnotationAttributeName( CompletionResultSet result, PsiElement insertedElement, CompletionParameters parameters) { PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class); PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList) pair.getParent(); PsiAnnotation anno = (PsiAnnotation) parameterList.getParent(); boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement); PsiClass annoClass = null; final PsiJavaCodeReferenceElement referenceElement = anno.getNameReferenceElement(); if (referenceElement != null) { final PsiElement element = referenceElement.resolve(); if (element instanceof PsiClass) { annoClass = (PsiClass) element; if (annoClass.findMethodsByName("value", false).length == 0) { showClasses = false; } } } if (showClasses && insertedElement.getParent() instanceof PsiReferenceExpression) { final Set<LookupElement> set = JavaCompletionUtil.processJavaReference( insertedElement, (PsiJavaReference) insertedElement.getParent(), new ElementExtractorFilter(createAnnotationFilter(insertedElement)), JavaCompletionProcessor.Options.DEFAULT_OPTIONS, result.getPrefixMatcher(), parameters); for (final LookupElement element : set) { result.addElement(element); } addAllClasses(parameters, result, new InheritorsHolder(insertedElement, result)); } if (annoClass != null) { final PsiNameValuePair[] existingPairs = parameterList.getAttributes(); methods: for (PsiMethod method : annoClass.getMethods()) { if (!(method instanceof PsiAnnotationMethod)) continue; final String attrName = method.getName(); for (PsiNameValuePair existingAttr : existingPairs) { if (PsiTreeUtil.isAncestor(existingAttr, insertedElement, false)) break; if (Comparing.equal(existingAttr.getName(), attrName) || PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(attrName) && existingAttr.getName() == null) continue methods; } LookupElementBuilder element = LookupElementBuilder.createWithIcon(method) .withInsertHandler( new InsertHandler<LookupElement>() { @Override public void handleInsert(InsertionContext context, LookupElement item) { final Editor editor = context.getEditor(); TailType.EQ.processTail(editor, editor.getCaretModel().getOffset()); context.setAddCompletionChar(false); context.commitDocument(); PsiAnnotationParameterList paramList = PsiTreeUtil.findElementOfClassAtOffset( context.getFile(), context.getStartOffset(), PsiAnnotationParameterList.class, false); if (paramList != null && paramList.getAttributes().length > 0 && paramList.getAttributes()[0].getName() == null) { int valueOffset = paramList.getAttributes()[0].getTextRange().getStartOffset(); context .getDocument() .insertString( valueOffset, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME); TailType.EQ.processTail( editor, valueOffset + PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.length()); } } }); PsiAnnotationMemberValue defaultValue = ((PsiAnnotationMethod) method).getDefaultValue(); if (defaultValue != null) { Object constant = JavaPsiFacade.getInstance(method.getProject()) .getConstantEvaluationHelper() .computeConstantExpression(defaultValue); if (constant != null) { element = element.withTailText( " default " + (constant instanceof String ? "\"" + constant + "\"" : constant), true); } } result.addElement(element); } } }
private static Map<MethodSignature, HierarchicalMethodSignature> buildMethodHierarchy( PsiClass aClass, PsiSubstitutor substitutor, final boolean includePrivates, final Set<PsiClass> visited, boolean isInRawContext) { Map<MethodSignature, HierarchicalMethodSignature> result = new LinkedHashMap<MethodSignature, HierarchicalMethodSignature>(); final Map<MethodSignature, List<PsiMethod>> sameParameterErasureMethods = new THashMap<MethodSignature, List<PsiMethod>>( MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY); Map<MethodSignature, HierarchicalMethodSignatureImpl> map = new THashMap<MethodSignature, HierarchicalMethodSignatureImpl>( new TObjectHashingStrategy<MethodSignature>() { @Override public int computeHashCode(MethodSignature signature) { return MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.computeHashCode( signature); } @Override public boolean equals(MethodSignature o1, MethodSignature o2) { if (!MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY.equals(o1, o2)) return false; List<PsiMethod> list = sameParameterErasureMethods.get(o1); boolean toCheckReturnType = list != null && list.size() > 1; if (!toCheckReturnType) return true; PsiType returnType1 = ((MethodSignatureBackedByPsiMethod) o1).getMethod().getReturnType(); PsiType returnType2 = ((MethodSignatureBackedByPsiMethod) o2).getMethod().getReturnType(); if (returnType1 == null && returnType2 == null) return true; if (returnType1 == null || returnType2 == null) return false; PsiType erasure1 = TypeConversionUtil.erasure(o1.getSubstitutor().substitute(returnType1)); PsiType erasure2 = TypeConversionUtil.erasure(o2.getSubstitutor().substitute(returnType2)); return erasure1.equals(erasure2); } }); for (PsiMethod method : aClass.getMethods()) { if (!method.isValid()) { throw new PsiInvalidElementAccessException( method, "class.valid=" + aClass.isValid() + "; name=" + method.getName()); } if (!includePrivates && method.hasModifierProperty(PsiModifier.PRIVATE)) continue; final MethodSignatureBackedByPsiMethod signature = MethodSignatureBackedByPsiMethod.create(method, substitutor, isInRawContext); HierarchicalMethodSignatureImpl newH = new HierarchicalMethodSignatureImpl(signature); List<PsiMethod> list = sameParameterErasureMethods.get(signature); if (list == null) { list = new SmartList<PsiMethod>(); sameParameterErasureMethods.put(signature, list); } list.add(method); LOG.assertTrue(newH.getMethod().isValid()); result.put(signature, newH); map.put(signature, newH); } for (PsiClassType superType : aClass.getSuperTypes()) { PsiClassType.ClassResolveResult superTypeResolveResult = superType.resolveGenerics(); PsiClass superClass = superTypeResolveResult.getElement(); if (superClass == null) continue; if (!visited.add(superClass)) continue; // cyclic inheritance final PsiSubstitutor superSubstitutor = superTypeResolveResult.getSubstitutor(); PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(superClass, superSubstitutor, substitutor, isInRawContext); final boolean isInRawContextSuper = (isInRawContext || PsiUtil.isRawSubstitutor(superClass, superSubstitutor)) && superClass.getTypeParameters().length != 0; Map<MethodSignature, HierarchicalMethodSignature> superResult = buildMethodHierarchy(superClass, finalSubstitutor, false, visited, isInRawContextSuper); visited.remove(superClass); List<Pair<MethodSignature, HierarchicalMethodSignature>> flattened = new ArrayList<Pair<MethodSignature, HierarchicalMethodSignature>>(); for (Map.Entry<MethodSignature, HierarchicalMethodSignature> entry : superResult.entrySet()) { HierarchicalMethodSignature hms = entry.getValue(); MethodSignature signature = entry.getKey(); PsiClass containingClass = hms.getMethod().getContainingClass(); List<HierarchicalMethodSignature> supers = new ArrayList<HierarchicalMethodSignature>(hms.getSuperSignatures()); for (HierarchicalMethodSignature aSuper : supers) { PsiClass superContainingClass = aSuper.getMethod().getContainingClass(); if (containingClass != null && superContainingClass != null && !containingClass.isInheritor(superContainingClass, true)) { // methods must be inherited from unrelated classes, so flatten hierarchy here // class C implements SAM1, SAM2 { void methodimpl() {} } // hms.getSuperSignatures().remove(aSuper); flattened.add( new Pair<MethodSignature, HierarchicalMethodSignature>(signature, aSuper)); } } putInMap(aClass, result, map, hms, signature); } for (Pair<MethodSignature, HierarchicalMethodSignature> pair : flattened) { putInMap(aClass, result, map, pair.second, pair.first); } } for (Map.Entry<MethodSignature, HierarchicalMethodSignatureImpl> entry : map.entrySet()) { HierarchicalMethodSignatureImpl hierarchicalMethodSignature = entry.getValue(); MethodSignature methodSignature = entry.getKey(); if (result.get(methodSignature) == null && PsiUtil.isAccessible( aClass.getProject(), hierarchicalMethodSignature.getMethod(), aClass, aClass)) { LOG.assertTrue(hierarchicalMethodSignature.getMethod().isValid()); result.put(methodSignature, hierarchicalMethodSignature); } } return result; }
private static boolean processDeclarationsInClassNotCached( @NotNull PsiClass aClass, @NotNull PsiScopeProcessor processor, @NotNull ResolveState state, @Nullable Set<PsiClass> visited, PsiElement last, @NotNull PsiElement place, boolean isRaw, @NotNull LanguageLevel languageLevel) { if (visited == null) visited = new THashSet<PsiClass>(); 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; } } } PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory(); 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) { PsiSubstitutor finalSubstitutor = checkRaw(isRaw, factory, method, baseSubstitutor); ResolveState methodState = finalSubstitutor == baseSubstitutor ? state : state.put(PsiSubstitutor.KEY, finalSubstitutor); if (!processor.execute(method, methodState)) return false; } } if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { if (last != null && last.getParent() == aClass) { // Parameters final PsiTypeParameterList list = aClass.getTypeParameterList(); if (list != null && !list.processDeclarations(processor, ResolveState.initial(), last, place)) return false; } 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; } } } } return last instanceof PsiReferenceList || processSuperTypes( aClass, processor, visited, last, place, state, isRaw, factory, languageLevel); }