mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
lambda -> method ref: allow conversion with any qualifier, show warning only for trivial qualifiers; same for anonymous -> method ref (IDEA-CR-16052)
This commit is contained in:
+12
-6
@@ -83,10 +83,10 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
|
||||
if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(aClass, true, reportNotAnnotatedInterfaces, Collections.emptySet())) {
|
||||
final PsiMethod method = aClass.getMethods()[0];
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
LambdaCanBeMethodReferenceInspection methodReferenceInspection = new LambdaCanBeMethodReferenceInspection();
|
||||
PsiExpression lambdaBodyCandidate = methodReferenceInspection.extractMethodReferenceCandidateExpression(body, false);
|
||||
final PsiExpression methodRefCandidate =
|
||||
new LambdaCanBeMethodReferenceInspection()
|
||||
.canBeMethodReferenceProblem(body, method.getParameterList().getParameters(), aClass.getBaseClassType(),
|
||||
aClass.getParent());
|
||||
methodReferenceInspection.canBeMethodReferenceProblem(method.getParameterList().getParameters(), aClass.getBaseClassType(), aClass.getParent(), lambdaBodyCandidate);
|
||||
if (methodRefCandidate instanceof PsiCallExpression) {
|
||||
final PsiCallExpression callExpression = (PsiCallExpression)methodRefCandidate;
|
||||
final PsiMethod resolveMethod = callExpression.resolveMethod();
|
||||
@@ -99,9 +99,11 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
|
||||
final PsiElement lBrace = aClass.getLBrace();
|
||||
LOG.assertTrue(lBrace != null);
|
||||
final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent());
|
||||
ProblemHighlightType highlightType = LambdaCanBeMethodReferenceInspection.checkQualifier(lambdaBodyCandidate) ? ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
||||
: ProblemHighlightType.INFORMATION;
|
||||
holder.registerProblem(parent,
|
||||
"Anonymous #ref #loc can be replaced with method reference",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithMethodRefFix());
|
||||
highlightType, rangeInElement, new ReplaceWithMethodRefFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,8 +131,12 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
|
||||
if (methods.length != 1) return;
|
||||
|
||||
final PsiParameter[] parameters = methods[0].getParameterList().getParameters();
|
||||
final String methodRefText = LambdaCanBeMethodReferenceInspection
|
||||
.convertToMethodReference(methods[0].getBody(), parameters, anonymousClass.getBaseClassType(), anonymousClass.getParent());
|
||||
final PsiType functionalInterfaceType = anonymousClass.getBaseClassType();
|
||||
LambdaCanBeMethodReferenceInspection methodReferenceInspection = new LambdaCanBeMethodReferenceInspection();
|
||||
PsiExpression methodRefCandidate = methodReferenceInspection.extractMethodReferenceCandidateExpression(methods[0].getBody(), false);
|
||||
final PsiExpression candidate = methodReferenceInspection.canBeMethodReferenceProblem(parameters, functionalInterfaceType, anonymousClass.getParent(), methodRefCandidate);
|
||||
|
||||
final String methodRefText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(candidate, functionalInterfaceType, parameters);
|
||||
|
||||
replaceWithMethodReference(project, methodRefText, anonymousClass.getBaseClassType(), anonymousClass.getParent());
|
||||
}
|
||||
|
||||
+19
-26
@@ -17,7 +17,6 @@ package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -101,36 +100,36 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
final PsiElement body = expression.getBody();
|
||||
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
|
||||
if (functionalInterfaceType != null) {
|
||||
PsiExpression methodRefCandidate = extractMethodReferenceCandidateExpression(body, false);
|
||||
final PsiExpression candidate =
|
||||
canBeMethodReferenceProblem(body, expression.getParameterList().getParameters(), functionalInterfaceType, null);
|
||||
canBeMethodReferenceProblem(expression.getParameterList().getParameters(), functionalInterfaceType, null, methodRefCandidate);
|
||||
if (candidate != null) {
|
||||
ProblemHighlightType errorOrWarning = checkQualifier(methodRefCandidate) ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING
|
||||
: ProblemHighlightType.INFORMATION;
|
||||
holder.registerProblem(InspectionProjectProfileManager.isInformationLevel(getShortName(), expression) ? expression : candidate,
|
||||
"Can be replaced with method reference",
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithMethodRefFix());
|
||||
errorOrWarning, new ReplaceWithMethodRefFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String convertToMethodReference(@Nullable final PsiElement body,
|
||||
final PsiVariable[] parameters,
|
||||
final PsiType functionalInterfaceType,
|
||||
@Nullable PsiElement context) {
|
||||
final PsiExpression candidate = new LambdaCanBeMethodReferenceInspection()
|
||||
.canBeMethodReferenceProblem(body, parameters, functionalInterfaceType, context);
|
||||
return createMethodReferenceText(candidate, functionalInterfaceType, parameters);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiExpression canBeMethodReferenceProblem(@Nullable final PsiElement body,
|
||||
final PsiVariable[] parameters,
|
||||
PsiType functionalInterfaceType,
|
||||
@Nullable PsiElement context) {
|
||||
final PsiExpression methodRefCandidate = extractMethodReferenceCandidateExpression(body);
|
||||
PsiExpression methodRefCandidate = extractMethodReferenceCandidateExpression(body, true);
|
||||
return canBeMethodReferenceProblem(parameters, functionalInterfaceType, context, methodRefCandidate);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiExpression canBeMethodReferenceProblem(final PsiVariable[] parameters,
|
||||
PsiType functionalInterfaceType,
|
||||
@Nullable PsiElement context,
|
||||
final PsiExpression methodRefCandidate) {
|
||||
if (methodRefCandidate instanceof PsiNewExpression) {
|
||||
final PsiNewExpression newExpression = (PsiNewExpression)methodRefCandidate;
|
||||
if (newExpression.getAnonymousClass() != null || newExpression.getArrayInitializer() != null) {
|
||||
@@ -264,18 +263,18 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiExpression extractMethodReferenceCandidateExpression(PsiElement body) {
|
||||
public PsiExpression extractMethodReferenceCandidateExpression(PsiElement body, boolean checkSideEffectPureQualifier) {
|
||||
final PsiExpression expression = LambdaUtil.extractSingleExpressionFromBody(body);
|
||||
if (expression == null) {
|
||||
return null;
|
||||
}
|
||||
if (expression instanceof PsiNewExpression) {
|
||||
if (checkQualifier(((PsiNewExpression)expression).getQualifier())) {
|
||||
if (!checkSideEffectPureQualifier || checkQualifier(((PsiNewExpression)expression).getQualifier())) {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
else if (expression instanceof PsiMethodCallExpression) {
|
||||
if (checkQualifier(((PsiMethodCallExpression)expression).getMethodExpression().getQualifier())) {
|
||||
if (!checkSideEffectPureQualifier || checkQualifier(((PsiMethodCallExpression)expression).getMethodExpression().getQualifier())) {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
@@ -323,17 +322,11 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
return tryConvertToMethodReference(lambda, candidate);
|
||||
}
|
||||
|
||||
private static boolean checkQualifier(PsiElement qualifier) {
|
||||
public static boolean checkQualifier(PsiElement qualifier) {
|
||||
if (qualifier == null) {
|
||||
return true;
|
||||
}
|
||||
final Condition<PsiElement> callExpressionCondition = element -> {
|
||||
if (element instanceof PsiCallExpression) {
|
||||
PsiMethod method = ((PsiCallExpression)element).resolveMethod();
|
||||
return !(method != null && ControlFlowAnalyzer.isPure(method));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
final Condition<PsiElement> callExpressionCondition = Conditions.instanceOf(PsiCallExpression.class);
|
||||
final Condition<PsiElement> nonFinalFieldRefCondition = expression -> {
|
||||
if (expression instanceof PsiReferenceExpression) {
|
||||
PsiElement element = ((PsiReferenceExpression)expression).resolve();
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Replace lambda with method reference" "true"
|
||||
class Example {
|
||||
public void m() {
|
||||
}
|
||||
|
||||
{
|
||||
Runnable r = ex()::m;
|
||||
}
|
||||
|
||||
Example ex() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Replace lambda with method reference" "false"
|
||||
// "Replace lambda with method reference" "true"
|
||||
class Example {
|
||||
public void m() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user