new inference: caching resolve result during getTargetType inference (IDEA-142733...
authorAnna Kozlova <anna.kozlova@jetbrains.com>
Wed, 2 Sep 2015 10:30:05 +0000 (13:30 +0300)
committerAnna Kozlova <anna.kozlova@jetbrains.com>
Wed, 2 Sep 2015 14:04:29 +0000 (17:04 +0300)
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods2.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CachedUnresolvedMethods.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Java8ExpressionsCheckTest.java

index fbfe8c1160d657d80ef1b7fd9968ec4486d38ab1..924224e3e92c45fc31cf402d9809aef39985966d 100644 (file)
@@ -667,17 +667,18 @@ public class InferenceSession {
           }
           final JavaResolveResult result = properties != null ? properties.getInfo() : ((PsiCallExpression)gParent).resolveMethodGenerics();
           final boolean varargs = properties != null && properties.isVarargs() || result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isVarargs();
-          return getTypeByMethod(context, argumentList, result.getElement(),
-                                 varargs,
-                                 PsiResolveHelper.ourGraphGuard.doPreventingRecursion(argumentList.getParent(), false,
-                                                                                      new Computable<PsiSubstitutor>() {
-                                                                                        @Override
-                                                                                        public PsiSubstitutor compute() {
-                                                                                          return result.getSubstitutor();
-                                                                                        }
-                                                                                      }
-                                 )
+          PsiSubstitutor substitutor = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(context, false,
+                                                                                            new Computable<PsiSubstitutor>() {
+                                                                                              @Override
+                                                                                              public PsiSubstitutor compute() {
+                                                                                                return result.getSubstitutor();
+                                                                                              }
+                                                                                            }
           );
+          if (substitutor == null && properties != null) {
+            substitutor = properties.getSubstitutor();
+          }
+          return getTypeByMethod(context, argumentList, result.getElement(), varargs, substitutor);
         }
       }
     } else if (parent instanceof PsiConditionalExpression) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CacheUnresolvedMethods2.java
new file mode 100644 (file)
index 0000000..99ce679
--- /dev/null
@@ -0,0 +1,24 @@
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+class Test {
+
+  static class A {
+    static class Row {
+      public String get(int index) {
+        return "test";
+      }
+    }
+
+    void foo(List<Row> list) {
+      list.stream().collect(Collectors.toMap(a -> String.valueOf(a.ge<caret>t(0)),
+                                             a -> String.valueOf(a.get(1))));
+    }
+
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CachedUnresolvedMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/expressions/CachedUnresolvedMethods.java
new file mode 100644 (file)
index 0000000..ed8e5b3
--- /dev/null
@@ -0,0 +1,49 @@
+import java.util.ArrayList;
+import java.util.function.Function;
+import java.util.stream.Collector;
+
+class Test {
+
+  void f() {
+    JSONObject deviceTokenJson = new ArrayList<DeviceToken>()
+      .stream()
+      .collect(JSON.toObject(
+        token -> Hex.encodeHexString(token.get<caret>Token()) ,
+        token -> new JSONObject()
+          .put("application_id", token.getAppId())
+          .put("sandbox", token.isSandbox())));
+
+  }
+  
+  static class JSONObject {
+    public JSONObject put(String var1, Object var2) {
+      return this;
+    }
+  }
+
+  static class JSON {
+    static <T, R> Collector<T, ?, R> toObject(Function<DeviceToken, String> f, Function<T, R> ff) {
+      return null;
+    }
+  }
+
+  static private class Hex {
+    static String encodeHexString(byte[] t) {
+      return new String(t);
+    }
+
+  }
+
+  private static class DeviceToken {
+    public byte[] getToken() {
+      return null;
+    }
+    public String getAppId() {
+      return "";
+    }
+
+    public boolean isSandbox() {
+      return true;
+    }
+  }
+}
\ No newline at end of file
index d5ca6c9a910f7b8c5a1babdad5ffc690388408ea..60de9b9b87a3db8ecfee35b8dc21bda0700beb08 100644 (file)
 package com.intellij.codeInsight.daemon.lambda;
 
 import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.testFramework.IdeaTestUtil;
 import org.jetbrains.annotations.NonNls;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
 public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase {
   @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/expressions";
@@ -43,6 +47,28 @@ public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase {
     doTestAllMethodCallExpressions();
   }
 
+  public void testCachedUnresolvedMethods() throws Exception {
+    doTestCachedUnresolved();
+  }
+
+  public void testCacheUnresolvedMethods2() throws Exception {
+    doTestCachedUnresolved();
+  }
+
+  private void doTestCachedUnresolved() {
+    configureByFile(BASE_PATH + "/" + getTestName(false) + ".java");
+    PsiMethodCallExpression callExpression =
+      PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiMethodCallExpression.class);
+
+    assertNotNull(callExpression);
+    assertNotNull(callExpression.getType());
+
+    final Collection<PsiCallExpression> methodCallExpressions = PsiTreeUtil.findChildrenOfType(getFile(), PsiCallExpression.class);
+    for (PsiCallExpression expression : methodCallExpressions) {
+      assertNotNull("Failed inference for: " + expression.getText(), expression.getType());
+    }
+  }
+
   public void testIDEA140035() throws Exception {
     doTestAllMethodCallExpressions();
     final Collection<PsiParameter> parameterLists = PsiTreeUtil.findChildrenOfType(getFile(), PsiParameter.class);