mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
lambda -> method ref: do not convert if resulted ref would be ambiguous (IDEA-116964)
This commit is contained in:
+1
-1
@@ -118,7 +118,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
|
||||
.canBeMethodReferenceProblem(methods[0].getBody(), parameters, anonymousClass.getBaseClassType());
|
||||
if (callExpression == null) return;
|
||||
final String methodRefText =
|
||||
LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType());
|
||||
LambdaCanBeMethodReferenceInspection.createMethodReferenceText(callExpression, anonymousClass.getBaseClassType(), parameters);
|
||||
|
||||
if (methodRefText != null) {
|
||||
final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText();
|
||||
|
||||
+44
-7
@@ -24,6 +24,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -114,8 +115,8 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
if (argumentList != null) {
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
|
||||
final PsiMethod psiMethod = methodCall.resolveMethod();
|
||||
final PsiClass containingClass;
|
||||
PsiMethod psiMethod = methodCall.resolveMethod();
|
||||
PsiClass containingClass;
|
||||
boolean isConstructor;
|
||||
if (psiMethod == null) {
|
||||
isConstructor = true;
|
||||
@@ -131,6 +132,12 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
}
|
||||
if (containingClass == null) return null;
|
||||
boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod);
|
||||
if (isReceiverType && psiMethod != null) {
|
||||
PsiMethod nonAmbiguousMethod = ensureNonAmbiguousMethod(parameters, psiMethod);
|
||||
if (nonAmbiguousMethod == null) return null;
|
||||
psiMethod = nonAmbiguousMethod;
|
||||
containingClass = nonAmbiguousMethod.getContainingClass();
|
||||
}
|
||||
final boolean staticOrValidConstructorRef;
|
||||
if (isConstructor) {
|
||||
staticOrValidConstructorRef =
|
||||
@@ -206,13 +213,35 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static String createMethodReferenceText(PsiElement element, PsiType functionalInterfaceType) {
|
||||
private static PsiMethod ensureNonAmbiguousMethod(PsiParameter[] parameters, @NotNull PsiMethod psiMethod) {
|
||||
String methodName = psiMethod.getName();
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (containingClass == null) return null;
|
||||
for (PsiMethod method : containingClass.findMethodsByName(methodName, false)) {
|
||||
PsiParameter[] candidateParams = method.getParameterList().getParameters();
|
||||
if (candidateParams.length == 1) {
|
||||
if (TypeConversionUtil.areTypesConvertible(candidateParams[0].getType(), parameters[0].getType())) {
|
||||
for (PsiMethod superMethod : psiMethod.findDeepestSuperMethods()) {
|
||||
PsiMethod validSuperMethod = ensureNonAmbiguousMethod(parameters, superMethod);
|
||||
if (validSuperMethod != null) return validSuperMethod;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return psiMethod;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static String createMethodReferenceText(final PsiElement element,
|
||||
final PsiType functionalInterfaceType,
|
||||
final PsiParameter[] parameters) {
|
||||
String methodRefText = null;
|
||||
if (element instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element;
|
||||
final PsiMethod psiMethod = methodCall.resolveMethod();
|
||||
if (psiMethod == null) return null;
|
||||
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||
PsiClass containingClass = psiMethod.getContainingClass();
|
||||
LOG.assertTrue(containingClass != null);
|
||||
final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
|
||||
final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
|
||||
@@ -221,8 +250,15 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
boolean isReceiverType = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, psiMethod);
|
||||
final String qualifier;
|
||||
if (isReceiverType) {
|
||||
final PsiType qualifierExpressionType = qualifierExpression.getType();
|
||||
qualifier = qualifierExpressionType != null ? qualifierExpressionType.getCanonicalText() : getClassReferenceName(containingClass);
|
||||
final PsiMethod nonAmbiguousMethod = ensureNonAmbiguousMethod(parameters, psiMethod);
|
||||
LOG.assertTrue(nonAmbiguousMethod != null);
|
||||
final PsiClass nonAmbiguousContainingClass = nonAmbiguousMethod.getContainingClass();
|
||||
if (!containingClass.equals(nonAmbiguousContainingClass)) {
|
||||
qualifier = getClassReferenceName(nonAmbiguousContainingClass);
|
||||
} else {
|
||||
final PsiType qualifierExpressionType = qualifierExpression.getType();
|
||||
qualifier = qualifierExpressionType != null ? qualifierExpressionType.getCanonicalText() : getClassReferenceName(nonAmbiguousContainingClass);
|
||||
}
|
||||
}
|
||||
else {
|
||||
qualifier = qualifierExpression.getText();
|
||||
@@ -298,7 +334,8 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
|
||||
if (lambdaExpression == null) return;
|
||||
final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
|
||||
final String methodRefText = createMethodReferenceText(element, functionalInterfaceType);
|
||||
final String methodRefText = createMethodReferenceText(element, functionalInterfaceType,
|
||||
lambdaExpression.getParameterList().getParameters());
|
||||
|
||||
if (methodRefText != null) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
class Example {
|
||||
interface I {
|
||||
String foo(Integer i);
|
||||
}
|
||||
|
||||
{
|
||||
I i = Object::toString;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
class Example {
|
||||
interface I {
|
||||
String foo(Integer i);
|
||||
}
|
||||
|
||||
{
|
||||
I i = (i1) -> i1.<caret>toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user