new inference: array creation notional method; testdata

(cherry picked from commit dc1b25b74db12a5282332b5bae1d10da1aed99e8)
This commit is contained in:
anna
2013-11-25 16:47:46 +01:00
parent 3c3f917c1e
commit b3d9ff9874
3 changed files with 38 additions and 10 deletions
@@ -94,15 +94,9 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
}
if (myExpression.isConstructor()) {
applicableMethodReturnType = qualifierType;
}
if (!(qualifierType instanceof PsiArrayType && myExpression.isConstructor())) {
constraints.add(new SubtypingConstraint(qualifierType, GenericsUtil.eliminateWildcards(substitutor.substitute(targetParameters[0].getType())), true));
for (int i = 1; i < targetParameters.length; i++) {
constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i - 1].getType()), GenericsUtil.eliminateWildcards(substitutor.substitute(targetParameters[i].getType()))));
}
constraints.add(new SubtypingConstraint(qualifierType, GenericsUtil.eliminateWildcards(substitutor.substitute(targetParameters[0].getType())), true));
for (int i = 1; i < targetParameters.length; i++) {
constraints.add(new TypeCompatibilityConstraint(psiSubstitutor.substitute(parameters[i - 1].getType()), GenericsUtil.eliminateWildcards(substitutor.substitute(targetParameters[i].getType()))));
}
} else {
for (int i = 0; i < targetParameters.length; i++) {
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.light.LightMethod;
import com.intellij.psi.impl.source.resolve.ParameterTypeInferencePolicy;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.impl.source.tree.ChildRole;
@@ -74,6 +75,17 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
public PsiMember getPotentiallyApplicableMember() {
return CachedValuesManager.getCachedValue(this, new CachedValueProvider<PsiMember>() {
@Nullable
@Override
public Result<PsiMember> compute() {
return Result.createSingleDependency(getPotentiallyApplicableMemberInternal(),
PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
}
});
}
private PsiMember getPotentiallyApplicableMemberInternal() {
final PsiElement element = getReferenceNameElement();
final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(this);
final PsiClass containingClass = qualifierResolveResult.getContainingClass();
@@ -83,7 +95,15 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
methods = containingClass.findMethodsByName(element.getText(), false);
}
else if (isConstructor()) {
methods = containingClass.getConstructors();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject());
final PsiClass arrayClass = factory.getArrayClass(PsiUtil.getLanguageLevel(this));
if (arrayClass == containingClass) {
final PsiType componentType = qualifierResolveResult.getSubstitutor().substitute(arrayClass.getTypeParameters()[0]);
LOG.assertTrue(componentType != null, qualifierResolveResult.getSubstitutor());
methods = new PsiMethod[] {factory.createMethodFromText("public " + componentType.createArrayType().getCanonicalText() + " __array__(int i) {return null;}", this)};
} else {
methods = containingClass.getConstructors();
}
}
if (methods != null) {
PsiMethod psiMethod = null;
@@ -0,0 +1,14 @@
class Test {
void test(Helper<Integer> helper) {
staticFactory(helper, Integer[]::new);
}
<P_OUT> void staticFactory(Helper<P_OUT> helper,
IntFunction<P_OUT[]> generator){}
class Helper<K> {}
interface IntFunction<R> {
R apply(int value);
}
}