diamonds: ensure new expression with diamond is treated as poly expression; ensure that site substitutions for constructor refs are ignored as they always contain raw substitutions

This commit is contained in:
Anna Kozlova
2015-09-30 17:19:03 +02:00
parent bae5c15335
commit e5979eaa35
5 changed files with 56 additions and 10 deletions

View File

@@ -418,8 +418,7 @@ public class InferenceSession {
final PsiExpression[] newArgs = argumentList.getExpressions();
final PsiParameter[] newParams = method.getParameterList().getParameters();
if (newParams.length > 0) {
collectAdditionalConstraints(newParams, newArgs, method, result != null ? ((MethodCandidateInfo)result).getSiteSubstitutor() : properties.getSubstitutor(),
additionalConstraints, result != null ? ((MethodCandidateInfo)result).isVarargs() : properties.isVarargs());
collectAdditionalConstraints(newParams, newArgs, method, chooseSiteSubstitutor(properties, result, method), additionalConstraints, chooseVarargsMode(properties, result));
}
}
}
@@ -468,6 +467,20 @@ public class InferenceSession {
return callExpression.resolveMethodGenerics();
}
public static PsiSubstitutor chooseSiteSubstitutor(MethodCandidateInfo.CurrentCandidateProperties candidateProperties,
JavaResolveResult resolveResult, PsiMethod method) {
return resolveResult instanceof MethodCandidateInfo && method != null && !method.isConstructor() //constructor reference was erased
? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor()
: candidateProperties != null ? candidateProperties.getSubstitutor() : PsiSubstitutor.EMPTY;
}
public static boolean chooseVarargsMode(MethodCandidateInfo.CurrentCandidateProperties candidateProperties,
JavaResolveResult resolveResult) {
return resolveResult instanceof MethodCandidateInfo && ((MethodCandidateInfo)resolveResult).isVarargs() ||
candidateProperties != null && candidateProperties.isVarargs();
}
public PsiSubstitutor retrieveNonPrimitiveEqualsBounds(Collection<InferenceVariable> variables) {
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
for (InferenceVariable variable : variables) {
@@ -664,7 +677,7 @@ public class InferenceSession {
return getTypeByMethod(context, argumentList, properties.getMethod(), properties.isVarargs(), properties.getSubstitutor());
}
final JavaResolveResult result = properties != null ? properties.getInfo() : ((PsiCall)gParent).resolveMethodGenerics();
final boolean varargs = properties != null && properties.isVarargs() || result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isVarargs();
final boolean varargs = chooseVarargsMode(properties, result);
PsiSubstitutor substitutor = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(context, false,
new Computable<PsiSubstitutor>() {
@Override

View File

@@ -80,6 +80,18 @@ public class PsiPolyExpressionUtil {
return mentionsTypeParameters(returnType, typeParameters);
}
}
else if (method.isConstructor() && expression instanceof PsiNewExpression) {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)expression).getClassOrAnonymousClassReference();
if (classReference != null) {
final PsiReferenceParameterList parameterList = classReference.getParameterList();
if (parameterList != null) {
final PsiTypeElement[] parameterElements = parameterList.getTypeParameterElements();
if (parameterElements.length == 1 && parameterElements[0].getType() instanceof PsiDiamondType) {
return true;
}
}
}
}
} else {
return true;
}

View File

@@ -16,16 +16,13 @@
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -117,15 +114,14 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
}
if (typeParams != null) {
PsiSubstitutor siteSubstitutor =
resolveResult instanceof MethodCandidateInfo && method != null && !method.isConstructor() ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor() : candidateProperties != null ? candidateProperties.getSubstitutor() : PsiSubstitutor.EMPTY;
PsiSubstitutor siteSubstitutor = InferenceSession.chooseSiteSubstitutor(candidateProperties, resolveResult, method);
final InferenceSession callSession = new InferenceSession(typeParams, siteSubstitutor, myExpression.getManager(), myExpression);
callSession.propagateVariables(session.getInferenceVariables());
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() ||
candidateProperties != null && candidateProperties.isVarargs());
callSession.initExpressionConstraints(parameters, args, myExpression, method, InferenceSession
.chooseVarargsMode(candidateProperties, resolveResult));
}
final boolean accepted = callSession.repeatInferencePhases(true);
if (!accepted) {

View File

@@ -0,0 +1,21 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Function;
class Test {
<TValue> void iterateColumn (CollectionSerializer<TValue> valueSerializer, Consumer<TValue> consumer) {}
private void put(Collection<String> tags){}
void f() {
iterateColumn(new CollectionSerializer<>(ArrayList::new), this::put);
// iterateColumn(CollectionSerializer.create(ArrayList::new), this::put);
}
}
class CollectionSerializer<TCollection>{
public CollectionSerializer(final Function<Integer, TCollection> factory) {}
static <K> CollectionSerializer<K> create(Function<Integer, K> f) { return new CollectionSerializer<>(f);}
}

View File

@@ -43,6 +43,10 @@ public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testWithConstructorRefInside() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
}