From 9c95fa552481821886a2d380c460f32ffeb8f8c7 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 2 Jun 2016 15:20:42 +0300 Subject: [PATCH] don't try to infer from top if overloaded flag is on (IDEA-156937) --- .../codeInsight/ExpectedTypesProvider.java | 17 ++++++----- .../InferenceSessionContainer.java | 2 +- ...ingOfResultsDuringCandidatesIteration.java | 30 +++++++++++++++++++ .../lambda/Java8ExpressionsCheckTest.java | 28 +++++++++++++++++ 4 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CachingOfResultsDuringCandidatesIteration.java diff --git a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java index 6ceaf0ed116f..857a0e60fdcf 100644 --- a/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/ExpectedTypesProvider.java @@ -558,19 +558,20 @@ public class ExpectedTypesProvider { @Override public void visitExpressionList(@NotNull PsiExpressionList list) { PsiResolveHelper helper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); - if (list.getParent() instanceof PsiMethodCallExpression) { - PsiMethodCallExpression methodCall = (PsiMethodCallExpression)list.getParent(); + PsiElement parent = list.getParent(); + if (parent instanceof PsiMethodCallExpression) { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)parent; CandidateInfo[] candidates = helper.getReferencedMethodCandidates(methodCall, false, true); Collections.addAll(myResult, getExpectedArgumentTypesForMethodCall(candidates, list, myExpr, myForCompletion)); } - else if (list.getParent() instanceof PsiEnumConstant) { - getExpectedArgumentsTypesForEnumConstant((PsiEnumConstant)list.getParent(), list); + else if (parent instanceof PsiEnumConstant) { + getExpectedArgumentsTypesForEnumConstant((PsiEnumConstant)parent, list); } - else if (list.getParent() instanceof PsiNewExpression) { - getExpectedArgumentsTypesForNewExpression((PsiNewExpression)list.getParent(), list); + else if (parent instanceof PsiNewExpression) { + getExpectedArgumentsTypesForNewExpression((PsiNewExpression)parent, list); } - else if (list.getParent() instanceof PsiAnonymousClass) { - getExpectedArgumentsTypesForNewExpression((PsiNewExpression)list.getParent().getParent(), list); + else if (parent instanceof PsiAnonymousClass) { + getExpectedArgumentsTypesForNewExpression((PsiNewExpression)parent.getParent(), list); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java index 446cf3d6a15c..db6dbe38b9f6 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSessionContainer.java @@ -69,7 +69,7 @@ public class InferenceSessionContainer { if (parent instanceof PsiCall) { final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList(); final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList); - if (properties != null && !properties.isApplicabilityCheck()) { + if (properties != null && !properties.isApplicabilityCheck() && !MethodCandidateInfo.isOverloadCheck()) { final PsiCall topLevelCall = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(parent, false, new Computable() { @Override diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CachingOfResultsDuringCandidatesIteration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CachingOfResultsDuringCandidatesIteration.java new file mode 100644 index 000000000000..211f26e19f4f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CachingOfResultsDuringCandidatesIteration.java @@ -0,0 +1,30 @@ +import java.util.Collection; +import java.util.function.Function; +import java.util.function.Supplier; + +class Foo { + + + { + bar(() -> Result.create(new Function() { + @Override + public String apply(String s) { + throw new UnsupportedOperationException(); + } + }, new Object()) + ); + } + + private static void bar(Supplier provider ){} + + static class Result { + public static Result create( T value, Collection dependencies) { + return new Result(); + } + + public static Result create( T value, Object... dependencies) { + return new Result(); + } + + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java index 0bf7155a2e65..b2fc093fa47f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.ExpectedTypesProvider; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.PsiTreeUtil; @@ -83,6 +84,33 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase { doTestAllMethodCallExpressions(); } + public void testCachingOfResultsDuringCandidatesIteration() throws Exception { + configureByFile(BASE_PATH + "/" + getTestName(false) + ".java"); + final Collection methodCallExpressions = PsiTreeUtil.findChildrenOfType(getFile(), PsiMethodCallExpression.class); + + final PsiResolveHelper helper = JavaPsiFacade.getInstance(getProject()).getResolveHelper(); + for (PsiMethodCallExpression expression : methodCallExpressions) { + CandidateInfo[] candidates = helper.getReferencedMethodCandidates(expression, false, true); + PsiExpressionList argumentList = expression.getArgumentList(); + PsiExpression[] args = argumentList.getExpressions(); + for (JavaResolveResult result : candidates) { + if (result instanceof MethodCandidateInfo) { + final MethodCandidateInfo info = (MethodCandidateInfo)result; + MethodCandidateInfo.ourOverloadGuard + .doPreventingRecursion(argumentList, false, () -> info.inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, args, true)); + } + } + + PsiMethodCallExpression parentCall = PsiTreeUtil.getParentOfType(expression, PsiMethodCallExpression.class, true); + if (parentCall != null) { + JavaResolveResult result = parentCall.getMethodExpression().advancedResolve(false); + if (result instanceof MethodCandidateInfo) { + assertNull(((MethodCandidateInfo)result).getInferenceErrorMessage()); + } + } + } + } + public void testNonCachingFolding() throws Exception { final String filePath = BASE_PATH + "/" + getTestName(false) + ".java"; configureByFile(filePath);