mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: use available in stack methods, do not cache if this info was used (IDEA-122406)
This commit is contained in:
@@ -180,7 +180,10 @@ public class MethodCandidateInfo extends CandidateInfo{
|
||||
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeArguments(DefaultParameterTypeInferencePolicy.INSTANCE, includeReturnConstraint);
|
||||
|
||||
if (!stackStamp.mayCacheNow() || !ourOverloadGuard.currentStack().isEmpty() || !includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
if (!stackStamp.mayCacheNow() ||
|
||||
!ourOverloadGuard.currentStack().isEmpty() ||
|
||||
!includeReturnConstraint && myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) ||
|
||||
getMarkerList() != null && PsiResolveHelper.ourGraphGuard.currentStack().contains(getMarkerList().getParent())) {
|
||||
return inferredSubstitutor;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi.impl.source.resolve.graphInference;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -58,7 +59,8 @@ public class PsiPolyExpressionUtil {
|
||||
}
|
||||
}
|
||||
} else if (expression instanceof PsiMethodCallExpression) {
|
||||
return isMethodCallPolyExpression(expression, ((PsiMethodCallExpression)expression).resolveMethod());
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(((PsiMethodCallExpression)expression).getArgumentList());
|
||||
return isMethodCallPolyExpression(expression, candidateProperties != null ? candidateProperties.getMethod() : ((PsiMethodCallExpression)expression).resolveMethod());
|
||||
}
|
||||
else if (expression instanceof PsiConditionalExpression) {
|
||||
final ConditionalKind conditionalKind = isBooleanOrNumeric(expression);
|
||||
|
||||
+14
-5
@@ -80,8 +80,9 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
if (myExpression instanceof PsiCallExpression) {
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final JavaResolveResult resolveResult = ((PsiCallExpression)myExpression).resolveMethodGenerics();
|
||||
final PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(((PsiCallExpression)myExpression).getArgumentList());
|
||||
final JavaResolveResult resolveResult = candidateProperties != null ? null : ((PsiCallExpression)myExpression).resolveMethodGenerics();
|
||||
final PsiMethod method = candidateProperties != null ? candidateProperties.getMethod() : (PsiMethod)resolveResult.getElement();
|
||||
PsiType returnType = null;
|
||||
PsiTypeParameter[] typeParams = null;
|
||||
if (method != null && !method.isConstructor()) {
|
||||
@@ -117,8 +118,15 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
params[i] = typeParams[i];
|
||||
}
|
||||
}
|
||||
final PsiSubstitutor siteSubstitutor = resolveResult instanceof MethodCandidateInfo && method != null && !method.isConstructor()
|
||||
? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor() : PsiSubstitutor.EMPTY;
|
||||
PsiSubstitutor siteSubstitutor = PsiSubstitutor.EMPTY;
|
||||
if (method != null && !method.isConstructor()) {
|
||||
if (resolveResult instanceof MethodCandidateInfo) {
|
||||
siteSubstitutor = ((MethodCandidateInfo)resolveResult).getSiteSubstitutor();
|
||||
}
|
||||
else if (candidateProperties != null) {
|
||||
siteSubstitutor = candidateProperties.getSubstitutor();
|
||||
}
|
||||
}
|
||||
for (PsiTypeParameter typeParameter : siteSubstitutor.getSubstitutionMap().keySet()) {
|
||||
substitutor = substitutor.put(typeParameter, substitutor.substitute(siteSubstitutor.substitute(typeParameter)));
|
||||
}
|
||||
@@ -129,7 +137,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
if (method != null) {
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
callSession.initExpressionConstraints(parameters, args, myExpression, method, resolveResult instanceof MethodCandidateInfo && ((MethodCandidateInfo)resolveResult).isVarargs());
|
||||
callSession.initExpressionConstraints(parameters, args, myExpression, method, resolveResult instanceof MethodCandidateInfo && ((MethodCandidateInfo)resolveResult).isVarargs() ||
|
||||
candidateProperties != null && candidateProperties.isVarargs());
|
||||
}
|
||||
final boolean accepted = callSession.repeatInferencePhases(true);
|
||||
if (!accepted) {
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package com.intellij.psi.scope.conflictResolvers;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.PsiConflictResolver;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
@@ -47,7 +48,7 @@ public class DuplicateConflictResolver implements PsiConflictResolver{
|
||||
final PsiElement element = info.getElement();
|
||||
Object key;
|
||||
if (element instanceof PsiMethod) {
|
||||
key = ((PsiMethod)element).getSignature(info.getSubstitutor());
|
||||
key = ((PsiMethod)element).getSignature(((MethodCandidateInfo)info).getSubstitutor(false));
|
||||
}
|
||||
else {
|
||||
key = PsiUtilCore.getName(element);
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
abstract class Test {
|
||||
public long countTweetsLongerThan(int numberOfChars, final List<String> tweetList) {
|
||||
//numberOfChars = 100; //TODO uncomment to show it must be effectively final
|
||||
|
||||
long totalByFor = 0;
|
||||
for (String tweet : tweetList) {
|
||||
if (tweet.length() > numberOfChars) {
|
||||
totalByFor++;
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayList<String> guavaList = newArrayList(filter(tweetList, new Predicate<String>() {
|
||||
@Override
|
||||
public boolean test(String tweet) {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
final long totalFromGuava = guavaList.size();
|
||||
|
||||
|
||||
final long totalFromLambda = tweetList.stream()
|
||||
.filter(t -> t.length() > numberOfChars)
|
||||
.count();
|
||||
|
||||
if (totalByFor != totalFromLambda | totalByFor != totalFromGuava) {
|
||||
throw new RuntimeException("");
|
||||
}
|
||||
return totalFromLambda;
|
||||
}
|
||||
|
||||
abstract <E> ArrayList<E> newArrayList(Iterable<? extends E> elements);
|
||||
abstract <E> ArrayList<E> newArrayList();
|
||||
abstract <E> ArrayList<E> newArrayList(E... elements);
|
||||
|
||||
abstract <T> Iterable<T> filter(Iterable<T> unfiltered, Predicate<? super T> predicate);
|
||||
abstract <T> Iterable<T> filter(Iterable<?> unfiltered, Class<T> type);
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
abstract class Test {
|
||||
public long countTweetsLongerThan(int numberOfChars, final List<String> tweetList) {
|
||||
//numberOfChars = 100; //TODO uncomment to show it must be effectively final
|
||||
|
||||
long totalByFor = 0;
|
||||
for (String tweet : tweetList) {
|
||||
if (tweet.length() > numberOfChars) {
|
||||
totalByFor++;
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayList<String> guavaList = newArrayList(fil<ref>ter(tweetList, new Predicate<String>() {
|
||||
@Override
|
||||
public boolean test(String tweet) {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
final long totalFromGuava = guavaList.size();
|
||||
|
||||
|
||||
final long totalFromLambda = tweetList.stream()
|
||||
.filter(t -> t.length() > numberOfChars)
|
||||
.count();
|
||||
|
||||
if (totalByFor != totalFromLambda | totalByFor != totalFromGuava) {
|
||||
throw new RuntimeException("");
|
||||
}
|
||||
return totalFromLambda;
|
||||
}
|
||||
|
||||
abstract <E> ArrayList<E> newArrayList(Iterable<? extends E> elements);
|
||||
abstract <E> ArrayList<E> newArrayList();
|
||||
abstract <E> ArrayList<E> newArrayList(E... elements);
|
||||
|
||||
abstract <T> Iterable<T> filter(Iterable<T> unfiltered, Predicate<? super T> predicate);
|
||||
abstract <T> Iterable<T> filter(Iterable<?> unfiltered, Class<T> type);
|
||||
|
||||
}
|
||||
+4
@@ -178,6 +178,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA122406() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.JavaTestUtil;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.ResolveTestCase;
|
||||
|
||||
public class TypeInference18Test extends ResolveTestCase {
|
||||
|
||||
public void testIDEA122406() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private LanguageLevel myOldLanguageLevel;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myOldLanguageLevel = LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).getLanguageLevel();
|
||||
LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_8);
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).setLanguageLevel(myOldLanguageLevel);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
PsiReference ref = configureByFile("/codeInsight/daemonCodeAnalyzer/lambda/resolve/" + getTestName(false) + ".java");
|
||||
assertNotNull(ref);
|
||||
assertNotNull(ref.resolve());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getTestProjectJdk() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user