inference: ensure foreign variables do not participate in inference process, e.g. variables from method reference overload resolution (IDEA-154622)

This commit is contained in:
Anna.Kozlova
2016-04-13 21:11:02 +02:00
parent 3b46b4c3bf
commit d780e31bdf
5 changed files with 43 additions and 15 deletions
@@ -625,8 +625,10 @@ public class InferenceSession {
return mySiteSubstitutor;
}
public InitialInferenceState createInitialState(InferenceSessionContainer container, PsiSubstitutor topInferenceSubstitutor) {
return new InitialInferenceState(myInferenceVariables,
public InitialInferenceState createInitialState(InferenceSessionContainer container,
Collection<InferenceVariable> variables,
PsiSubstitutor topInferenceSubstitutor) {
return new InitialInferenceState(variables,
topInferenceSubstitutor,
myContext,
myInferenceSubstitution,
@@ -652,6 +654,7 @@ public class InferenceSession {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(parameter.getProject());
myInferenceSubstitution = myInferenceSubstitution.put(parameter, elementFactory.createType(variable));
myRestoreNameSubstitution = myRestoreNameSubstitution.put(variable, elementFactory.createType(parameter));
myInferenceVariables.add(variable);
}
for (InferenceVariable variable : result) {
PsiTypeParameter parameter = variable.getParameter();
@@ -669,7 +672,6 @@ public class InferenceSession {
InferenceBound.UPPER, null);
}
}
myInferenceVariables.addAll(result);
return result.toArray(new InferenceVariable[result.size()]);
}
@@ -893,10 +895,7 @@ public class InferenceSession {
public InferenceVariable getInferenceVariable(PsiType psiType) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(psiType);
if (psiClass instanceof InferenceVariable) {
return (InferenceVariable)psiClass;
}
return null;
return psiClass instanceof InferenceVariable ? getInferenceVariable((PsiTypeParameter)psiClass) : null;
}
public boolean isProperType(@Nullable PsiType type) {
@@ -1875,9 +1874,9 @@ public class InferenceSession {
return myContext;
}
public void propagateVariables(Collection<InferenceVariable> variables, PsiSubstitutor substitution) {
public void propagateVariables(Collection<InferenceVariable> variables, PsiSubstitutor restoreNamesSubstitution) {
myInferenceVariables.addAll(variables);
myRestoreNameSubstitution = myRestoreNameSubstitution.putAll(substitution);
myRestoreNameSubstitution = myRestoreNameSubstitution.putAll(restoreNamesSubstitution);
}
public PsiType substituteWithInferenceVariables(PsiType type) {
@@ -54,6 +54,7 @@ public class InferenceSessionContainer {
ExpressionCompatibilityConstraint.reduceExpressionCompatibilityConstraint(session, returnExpression, returnType);
if (inferenceSession != null && inferenceSession != session) {
registerNestedSession(inferenceSession);
session.propagateVariables(inferenceSession.getInferenceVariables(), inferenceSession.getRestoreNameSubstitution());
}
}
}
@@ -159,7 +160,7 @@ public class InferenceSessionContainer {
};
final Map<PsiElement, InferenceSession> nestedSessions = topLevelSession.getInferenceSessionContainer().myNestedSessions;
for (Map.Entry<PsiElement, InferenceSession> entry : nestedSessions.entrySet()) {
nestedStates.put(entry.getKey(), entry.getValue().createInitialState(copy, topInferenceSubstitutor));
nestedStates.put(entry.getKey(), entry.getValue().createInitialState(copy, topLevelSession.getInferenceVariables(), topInferenceSubstitutor));
}
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
@@ -19,10 +19,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
class InitialInferenceState {
private final Set<InferenceVariable> myInferenceVariables;
@@ -34,7 +31,7 @@ class InitialInferenceState {
private final InferenceSessionContainer myInferenceSessionContainer;
private final boolean myErased;
InitialInferenceState(Set<InferenceVariable> inferenceVariables,
InitialInferenceState(Collection<InferenceVariable> inferenceVariables,
PsiSubstitutor topInferenceSubstitutor,
PsiElement context,
PsiSubstitutor inferenceSubstitutor,
@@ -0,0 +1,27 @@
import java.util.function.Function;
class SomeClass<K, V> {
SomeClass(Function<K, V> transformer) {}
static <M, N> SomeClass<M, N> create(Function<M, N> t) {
return null;
}
static void someMethod() {
final SomeClass<MyBean, String> instance = create(MyBean::overloadedMethod);
final SomeClass<MyBean, String> instance1 = new SomeClass<>(MyBean::overloadedMethod);
}
}
class MyBean {
private String overloadedMethod(String param) {
return param;
}
public String overloadedMethod() {
return overloadedMethod(null);
}
}
@@ -510,6 +510,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testIgnoreForeignVariables() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}