new inference: incorporation with capture: treat type param's extends bounds as one...
authorAnna Kozlova <anna.kozlova@jetbrains.com>
Wed, 2 Sep 2015 13:30:09 +0000 (16:30 +0300)
committerAnna Kozlova <anna.kozlova@jetbrains.com>
Wed, 2 Sep 2015 14:04:31 +0000 (17:04 +0300)
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncorporationWithCaptureCalcGlbToGetOneTypeParameterBound.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java

index 4641403367e931a0769d7a3bdf601d6dc923b9ba..b1b47a60ddd13cf53175f8db726a4a5aff22d840 100644 (file)
@@ -113,15 +113,23 @@ public class InferenceIncorporationPhase {
             if (mySession.getInferenceVariable(eqBound) == null) return false;
           }
 
-          final PsiClassType[] paramBounds = parameters[i].getExtendsListTypes();
+          final PsiClassType[] paramBounds = inferenceVariable.getParameter().getExtendsListTypes();
+
+          PsiType glb = null;
+          for (PsiClassType paramBound : paramBounds) {
+            if (glb == null) {
+              glb = paramBound;
+            }
+            else {
+              glb = GenericsUtil.getGreatestLowerBound(glb, paramBound);
+            }
+          }
 
           if (!((PsiWildcardType)aType).isBounded()) {
 
             for (PsiType upperBound : upperBounds) {
-              if (mySession.getInferenceVariable(upperBound) == null) {
-                for (PsiClassType paramBound : paramBounds) {
-                  addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(paramBound)));
-                }
+              if (glb != null && mySession.getInferenceVariable(upperBound) == null) {
+                addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(glb)));
               }
             }
 
@@ -137,10 +145,9 @@ public class InferenceIncorporationPhase {
               if (mySession.getInferenceVariable(upperBound) == null) {
                 if (paramBounds.length == 1 && paramBounds[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || paramBounds.length == 0) {
                   addConstraint(new StrictSubtypingConstraint(upperBound, extendsBound));
-                } else if (extendsBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
-                  for (PsiClassType paramBound : paramBounds) {
-                    addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(paramBound)));
-                  }
+                }
+                else if (extendsBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) && glb != null) {
+                  addConstraint(new StrictSubtypingConstraint(upperBound, mySession.substituteWithInferenceVariables(glb)));
                 }
               }
             }
@@ -154,10 +161,8 @@ public class InferenceIncorporationPhase {
             final PsiType superBound = ((PsiWildcardType)aType).getSuperBound();
 
             for (PsiType upperBound : upperBounds) {
-              if (mySession.getInferenceVariable(upperBound) == null) {
-                for (PsiClassType paramBound : paramBounds) {
-                  addConstraint(new StrictSubtypingConstraint(mySession.substituteWithInferenceVariables(paramBound), upperBound));
-                }
+              if (glb != null && mySession.getInferenceVariable(upperBound) == null) {
+                addConstraint(new StrictSubtypingConstraint(mySession.substituteWithInferenceVariables(glb), upperBound));
               }
             }
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncorporationWithCaptureCalcGlbToGetOneTypeParameterBound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncorporationWithCaptureCalcGlbToGetOneTypeParameterBound.java
new file mode 100644 (file)
index 0000000..0d41628
--- /dev/null
@@ -0,0 +1,14 @@
+import java.util.List;
+
+class Test {
+
+  public <E> EntityContainer<?, E, ?> findNestedContainer(Class<E> entityClass) {
+    return null;
+  }
+
+  public <E2 > EntityContainer<?, E2, ?> readNestedEntity(Class<E2> entityClass) {
+    return findNestedContainer(entityClass);
+  }
+
+  private interface EntityContainer<K extends List<E>, E, M extends Test & List<E>> {}
+}
\ No newline at end of file
index 0992e353fe649fb7d9e44cfa0cd583f651e80964..b225b829f6a1e5e09cf0f3079a353dc23c9639b5 100644 (file)
@@ -295,6 +295,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
     doTest();
   }
 
+  public void testIncorporationWithCaptureCalcGlbToGetOneTypeParameterBound() throws Exception {
+    doTest();
+  }
+
   private void doTest() throws Exception {
     doTest(false);
   }