From a46f4cef5229fe8e9c327b588592756110f3adb7 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 21 Jul 2014 15:23:47 +0200 Subject: [PATCH] anonym -> lambda: disable in case when inferred type differs from type of anonymous class and parameter of param type is used inside (IDEA-127603); BTW param.toString would be also rejected --- .../AnonymousCanBeLambdaInspection.java | 35 ++++++++++--------- ...onymousCanBeMethodReferenceInspection.java | 2 +- .../beforeObjectInferredButIntExpected.java | 16 +++++++++ 3 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeObjectInferredButIntExpected.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java index 96066c34eefe..c1f127d3a1df 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java @@ -32,10 +32,7 @@ import com.intellij.psi.controlFlow.ControlFlow; import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.psi.infos.MethodCandidateInfo; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiTypesUtil; -import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.*; import com.intellij.util.ArrayUtilRt; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtilRt; @@ -91,16 +88,12 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection final PsiMethod[] methods = aClass.getMethods(); if (methods.length == 1 && aClass.getFields().length == 0) { final PsiCodeBlock body = methods[0].getBody(); - if (body != null) { - final ForbiddenRefsChecker checker = new ForbiddenRefsChecker(methods[0], aClass); - body.accept(checker); - if (!checker.hasForbiddenRefs()) { - final PsiElement lBrace = aClass.getLBrace(); - LOG.assertTrue(lBrace != null); - final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); - holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with lambda", - ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaFix()); - } + if (body != null && !hasForbiddenRefsInsideBody(methods[0], aClass)) { + final PsiElement lBrace = aClass.getLBrace(); + LOG.assertTrue(lBrace != null); + final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); + holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with lambda", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaFix()); } } } @@ -110,6 +103,14 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection }; } + public static boolean hasForbiddenRefsInsideBody(PsiMethod method, PsiAnonymousClass aClass) { + final ForbiddenRefsChecker checker = new ForbiddenRefsChecker(method, aClass); + final PsiCodeBlock body = method.getBody(); + LOG.assertTrue(body != null); + body.accept(checker); + return checker.hasForbiddenRefs(); + } + private static PsiType getInferredType(PsiAnonymousClass aClass) { final PsiExpression expression = (PsiExpression)aClass.getParent(); final PsiType psiType = PsiTypesUtil.getExpectedTypeByParent(expression); @@ -369,14 +370,14 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection private final PsiMethod myMethod; private final PsiAnonymousClass myAnonymClass; - private final boolean myRawType; + private final boolean myEqualInference; public ForbiddenRefsChecker(PsiMethod method, PsiAnonymousClass aClass) { myMethod = method; myAnonymClass = aClass; final PsiType inferredType = getInferredType(aClass); - myRawType = inferredType instanceof PsiClassType && ((PsiClassType)inferredType).isRaw(); + myEqualInference = !aClass.getBaseClassType().equals(inferredType); } @Override @@ -467,7 +468,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection } } - if (myRawType) { + if (myEqualInference) { final PsiElement resolved = expression.resolve(); if (resolved instanceof PsiParameter && ((PsiParameter)resolved).getDeclarationScope() == myMethod) { final int parameterIndex = myMethod.getParameterList().getParameterIndex((PsiParameter)resolved); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index d6a884c8917c..c3363ec7eb12 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -69,7 +69,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI final PsiClassType baseClassType = aClass.getBaseClassType(); if (LambdaUtil.isFunctionalType(baseClassType)) { final PsiMethod[] methods = aClass.getMethods(); - if (methods.length == 1 && aClass.getFields().length == 0) { + if (methods.length == 1 && aClass.getFields().length == 0 && !AnonymousCanBeLambdaInspection.hasForbiddenRefsInsideBody(methods[0], aClass)) { final PsiCodeBlock body = methods[0].getBody(); final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeObjectInferredButIntExpected.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeObjectInferredButIntExpected.java new file mode 100644 index 000000000000..3a82478ec678 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeObjectInferredButIntExpected.java @@ -0,0 +1,16 @@ +// "Replace with lambda" "false" +import java.util.function.Function; + +class Test { + void ab() { + comparing(new Function() { + public String apply(Integer pObj) { + return Integer.toString(pObj); + } + }); + + } + + static void comparing(Function keyExtractor){} + +}