PsiMember () { final PsiElement element = getReferenceNameElement(); final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(this); final PsiClass containingClass = qualifierResolveResult.getContainingClass(); if (containingClass == null) return null; //If the method reference expression has the form ReferenceType::[TypeArguments]Identifier or ClassType::[TypeArguments]new, //then ReferenceType does not denote a raw type. final PsiElement qualifier = getQualifier(); if (qualifier instanceof PsiReferenceExpression) { PsiElement resolve = ((PsiReferenceExpression)qualifier).resolve(); if (resolve instanceof PsiClass && ((PsiClass)resolve).hasTypeParameters()) { return null; } } PsiMethod[] methods = null; if (element instanceof PsiIdentifier) { final String identifierName = element.getText(); // findMethodsByName is supposed to be faster than getVisibleSignatures methods = containingClass.findMethodsByName(identifierName, true); if (methods.length == 0) return null; if (methods.length > 1) { final List<PsiMethod> result = new ArrayList<>(); for (HierarchicalMethodSignature signature : containingClass.getVisibleSignatures()) { if (identifierName.equals(signature.getName())) { result.add(signature.getMethod()); } } if (result.isEmpty()) { return null; } methods = result.toArray(PsiMethod.EMPTY_ARRAY); } } else if (isConstructor()) { final PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject()); if (factory.isArrayClass(containingClass)) { final PsiTypeParameter[] typeParameters = containingClass.getTypeParameters(); if (typeParameters.length != 1) return null; final PsiType componentType = qualifierResolveResult.getSubstitutor().substitute(typeParameters[0]); LOG.assertTrue(componentType != null, qualifierResolveResult.getSubstitutor()); //15.13.1 A method reference expression of the form ArrayType :: new is always exact. return factory.createMethodFromText("public " + componentType.createArrayType().getCanonicalText() + " __array__(int i) {return null;}", this); } else { methods = containingClass.getConstructors(); } } if (methods != null) { PsiMethod psiMethod = null; if (methods.length > 0) { //The type to search has exactly one member method with the name Identifier/constructor that is accessible to the class or interface // in which the method reference expression appears for (PsiMethod method : methods) { if (PsiUtil.isAccessible(method, this, null)) { if (psiMethod != null) return null; psiMethod = method; } } if (psiMethod == null) return null; // not variable arity if (psiMethod.isVarArgs()) return null; //If this method/constructor is generic (p8.4.4), then the method reference expression provides TypeArguments. if (psiMethod.getTypeParameters().length > 0) { final PsiReferenceParameterList parameterList = getParameterList(); return parameterList != null && parameterList.getTypeParameterElements().length > 0 ? psiMethod : null; } } return psiMethod == null ? containingClass : psiMethod; } return null; }