mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 02:09:59 +07:00
anonym -> lambda, method ref: do not suggest replacement when default method is called out of functional interface context
This commit is contained in:
@@ -30,6 +30,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.controlFlow.AnalysisCanceledException;
|
||||
import com.intellij.psi.controlFlow.ControlFlow;
|
||||
import com.intellij.psi.controlFlow.ControlFlowUtil;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Function;
|
||||
@@ -304,6 +305,17 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean functionalInterfaceMethodReferenced(PsiMethod psiMethod, PsiAnonymousClass anonymClass) {
|
||||
if (psiMethod != null && !psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||
if (InheritanceUtil.isInheritorOrSelf(anonymClass, containingClass, true) &&
|
||||
!InheritanceUtil.hasEnclosingInstanceInScope(containingClass, anonymClass.getParent(), true, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class ForbiddenRefsChecker extends JavaRecursiveElementWalkingVisitor {
|
||||
private boolean myBodyContainsForbiddenRefs;
|
||||
private final Set<PsiLocalVariable> myLocals = ContainerUtilRt.newHashSet(5);
|
||||
@@ -324,6 +336,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
super.visitMethodCallExpression(methodCallExpression);
|
||||
final PsiMethod psiMethod = methodCallExpression.resolveMethod();
|
||||
if (psiMethod == myMethod ||
|
||||
functionalInterfaceMethodReferenced(psiMethod, myAnonymClass) ||
|
||||
psiMethod != null &&
|
||||
!methodCallExpression.getMethodExpression().isQualified() &&
|
||||
"getClass".equals(psiMethod.getName()) &&
|
||||
|
||||
@@ -74,16 +74,19 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
|
||||
final PsiCallExpression callExpression =
|
||||
LambdaCanBeMethodReferenceInspection
|
||||
.canBeMethodReferenceProblem(body, methods[0].getParameterList().getParameters(), baseClassType);
|
||||
if (callExpression != null && callExpression.resolveMethod() != methods[0]) {
|
||||
final PsiElement parent = aClass.getParent();
|
||||
if (parent instanceof PsiNewExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
final PsiElement lBrace = aClass.getLBrace();
|
||||
LOG.assertTrue(lBrace != null);
|
||||
final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent());
|
||||
holder.registerProblem(parent,
|
||||
"Anonymous #ref #loc can be replaced with method reference", ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithMethodRefFix());
|
||||
if (callExpression != null) {
|
||||
final PsiMethod resolveMethod = callExpression.resolveMethod();
|
||||
if (resolveMethod != methods[0] && !AnonymousCanBeLambdaInspection.functionalInterfaceMethodReferenced(resolveMethod, aClass)) {
|
||||
final PsiElement parent = aClass.getParent();
|
||||
if (parent instanceof PsiNewExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
final PsiElement lBrace = aClass.getLBrace();
|
||||
LOG.assertTrue(lBrace != null);
|
||||
final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent());
|
||||
holder.registerProblem(parent,
|
||||
"Anonymous #ref #loc can be replaced with method reference", ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithMethodRefFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// "Replace with lambda" "true"
|
||||
class Test {
|
||||
interface InOut {
|
||||
void run() throws IOException;
|
||||
default void foo(){}
|
||||
}
|
||||
|
||||
interface InOutEx extends InOut {
|
||||
InOut bind() {
|
||||
return () -> {
|
||||
foo();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// "Replace with lambda" "true"
|
||||
class Test {
|
||||
interface InOut {
|
||||
void run() throws IOException;
|
||||
static void foo(){}
|
||||
}
|
||||
|
||||
InOut bind() {
|
||||
return () -> {
|
||||
InOut.foo();
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Replace with lambda" "false"
|
||||
class Test {
|
||||
interface InOut {
|
||||
void run() throws IOException;
|
||||
default void foo(){}
|
||||
}
|
||||
|
||||
InOut bind() {
|
||||
return new In<caret>Out() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
foo();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// "Replace with lambda" "true"
|
||||
class Test {
|
||||
interface InOut {
|
||||
void run() throws IOException;
|
||||
default void foo(){}
|
||||
}
|
||||
|
||||
interface InOutEx extends InOut {
|
||||
InOut bind() {
|
||||
return new In<caret>Out() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
foo();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Replace with lambda" "true"
|
||||
class Test {
|
||||
interface InOut {
|
||||
void run() throws IOException;
|
||||
static void foo(){}
|
||||
}
|
||||
|
||||
InOut bind() {
|
||||
return new In<caret>Out() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
foo();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Replace with method reference" "false"
|
||||
class Test {
|
||||
interface InOut {
|
||||
void run() throws IOException;
|
||||
default void foo(){}
|
||||
}
|
||||
|
||||
InOut bind() {
|
||||
return new In<caret>Out() {
|
||||
@Override
|
||||
public void run() throws IOException {
|
||||
foo();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user