new inference: do not resolve method calls in lambda return expressions to check isPolyExpression when arguments do not contain potential constrains

This commit is contained in:
Anna Kozlova
2014-09-16 10:25:03 +04:00
parent c5d44ea9c2
commit dc988e848d
6 changed files with 131 additions and 19 deletions
@@ -278,7 +278,7 @@ public class InferenceSession {
//If the expression is a poly class instance creation expression (15.9) or a poly method invocation expression (15.12),
//the set contains all constraint formulas that would appear in the set C when determining the poly expression's invocation type.
final PsiMethod calledMethod = getCalledMethod((PsiCallExpression)arg);
if (PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) {
if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) {
collectAdditionalConstraints(additionalConstraints, (PsiCallExpression)arg);
}
} else if (arg instanceof PsiLambdaExpression) {
@@ -294,12 +294,32 @@ public class InferenceSession {
return null;
}
boolean found = false;
for (PsiExpression expression : argumentList.getExpressions()) {
expression = PsiUtil.skipParenthesizedExprDown(expression);
if (expression instanceof PsiConditionalExpression ||
expression instanceof PsiCallExpression ||
expression instanceof PsiLambdaExpression ||
expression instanceof PsiMethodReferenceExpression) {
found = true;
break;
}
}
if (!found) {
return null;
}
MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
if (properties != null) {
return properties.getMethod();
}
final JavaResolveResult resolveResult = getMethodResult(arg);
return resolveResult instanceof MethodCandidateInfo ? (PsiMethod)resolveResult.getElement() : null;
if (resolveResult instanceof MethodCandidateInfo) {
return (PsiMethod)resolveResult.getElement();
}
else {
return null;
}
}
private void collectLambdaReturnExpression(Set<ConstraintFormula> additionalConstraints,
@@ -319,7 +339,7 @@ public class InferenceSession {
PsiType functionalType) {
if (returnExpression instanceof PsiCallExpression) {
final PsiMethod calledMethod = getCalledMethod((PsiCallExpression)returnExpression);
if (PsiPolyExpressionUtil.isMethodCallPolyExpression(returnExpression, calledMethod)) {
if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(returnExpression, calledMethod)) {
collectAdditionalConstraints(additionalConstraints, (PsiCallExpression)returnExpression);
}
}
@@ -365,7 +385,7 @@ public class InferenceSession {
};
MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
return properties != null ? null :
expression == null
expression == null || !PsiResolveHelper.ourGraphGuard.currentStack().contains(expression)
? computableResolve.compute()
: PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, false, computableResolve);
}
@@ -0,0 +1,24 @@
import java.util.List;
class Test {
interface A<T> {
T m(T t);
}
interface B<K> {
List<K> l(K k);
}
<F> F foo(A<F> a) {return null;}
<Bar> Bar bar(B<Bar> b) { return null;}
{
Integer i = foo(a -> bar(b -> asList(1, b)));
Integer i1 = foo(a -> bar(b -> asList(1, 1)));
}
<L> List<L> asList(L l, L l1) {
return null;
}
}
@@ -16,14 +16,11 @@
package com.intellij.codeInsight.daemon.lambda;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.idea.Bombed;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NonNls;
import java.util.Calendar;
public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase {
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/graphInference";
@@ -47,12 +44,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
@Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testInferenceFromSiblings() throws Exception {
doTest();
}
@Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testChainedInferenceTypeParamsOrderIndependent() throws Exception {
doTest();
}
@@ -15,10 +15,8 @@
*/
package com.intellij.codeInsight.daemon.lambda;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiType;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
@@ -44,6 +42,39 @@ public class InferredTypeTest extends LightCodeInsightFixtureTestCase {
Assert.assertTrue(type.getCanonicalText(), type.equalsToText("java.util.List<java.lang.String>"));
}
public void testCashedTypes() throws Exception {
myFixture.configureByText("a.java", "import java.util.*;\n" +
"abstract class Main {\n" +
" void test(List<Integer> li) {\n" +
" foo(li, s -> <caret>s.substr(0), Collections.emptyList());\n" +
" }\n" +
" abstract <T, U> Collection<U> foo(Collection<T> coll, Fun<Stream<T>, U> f, List<U> it);" +
" interface Stream<T> {\n" +
" T substr(long startingOffset);\n" +
" }\n" +
" interface Fun<T, R> {\n" +
" R _(T t);\n" +
" }\n" +
"}\n");
final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
Assert.assertTrue(elementAtCaret instanceof PsiIdentifier);
final PsiElement refExpr = elementAtCaret.getParent();
Assert.assertTrue(refExpr.toString(), refExpr instanceof PsiExpression);
final PsiType type = ((PsiExpression)refExpr).getType();
Assert.assertNotNull(refExpr.toString(), type);
Assert.assertTrue(type.getCanonicalText(), type.equalsToText("Stream<java.lang.Integer>"));
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(refExpr, PsiExpressionList.class);
assertNotNull(expressionList);
final PsiExpression[] expressions = expressionList.getExpressions();
assertEquals(3, expressions.length);
final PsiType ensureNotCached = expressions[2].getType();
assertNotNull(ensureNotCached);
assertTrue(ensureNotCached.getCanonicalText(), ensureNotCached.equalsToText("java.util.List<java.lang.Integer>"));
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.lambda;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class NewInferenceCollectingAdditionalConstraintsTest extends LightDaemonAnalyzerTestCase {
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/additionalConstraints";
public void testInferenceFromNestedIn2LambdasCall() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}
private void doTest(boolean warnings) {
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false);
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk18();
}
}
@@ -73,23 +73,20 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA121315() { doTest(); }
public void testIDEA118965comment() { doTest(); }
public void testIDEA122074() { doTest(); }
@Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testIDEA122084() { doTest(); }
public void testAdditionalConstraintDependsOnNonMentionedVars() { doTest(); }
public void testIDEA122616() { doTest(); }
public void testIDEA122700() { doTest(); }
public void testIDEA122406() { doTest(); }
public void testNestedCallsInsideLambdaReturnExpression() { doTest(); }
@Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testIDEA123731() { doTest(); }
public void testIDEA123869() { doTest(); }
@Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testIDEA123848() { doTest(); }
public void testOnlyLambdaAtTypeParameterPlace() { doTest(); }
public void testLiftedIntersectionType() { doTest(); }
public void testInferenceFromReturnStatements() { doTest(); }
public void testDownUpThroughLambdaReturnStatements() { doTest(); }
@Bombed(day = 30, month = Calendar.SEPTEMBER)
@Bombed(day = 30, month = Calendar.OCTOBER)
public void testIDEA124547() { doTest(); }
public void testIDEA118362() { doTest(); }
public void testIDEA126056() { doTest(); }
@@ -100,7 +97,6 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA124424() { doTest(); }
public void testNestedLambdaExpressions1() { doTest(); }
public void testNestedLambdaExpressionsNoFormalParams() { doTest(); }
@Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testNestedLambdaExpressionsNoFormalParams1() { doTest(); }
public void testDeepNestedLambdaExpressionsNoFormalParams() { doTest(); }
public void testNestedLambdaExpressionsNoFormalParamsStopAtStandalone() { doTest(); }
@@ -128,7 +124,6 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
@Bombed(day = 30, month = Calendar.SEPTEMBER)
public void testIDEA126778() throws Exception {
doTest();
}