diamonds: don't infer raw type when inference of a staticFactory failed

avoid blinking tests on overload resolution: make outer method call not applicable by inferring incomplete results like it's done for method calls
This commit is contained in:
Anna.Kozlova
2017-03-13 14:16:44 +01:00
parent 2d7375a526
commit bb7868f450
4 changed files with 20 additions and 20 deletions
@@ -110,8 +110,7 @@ public class MethodCandidateInfo extends CandidateInfo{
@ApplicabilityLevelConstant
public int getPertinentApplicabilityLevel() {
if (myPertinentApplicabilityLevel == 0) {
myPertinentApplicabilityLevel = getPertinentApplicabilityLevelInner();
myPertinentApplicabilityLevel = pullInferenceErrorMessagesFromSubexpressions();
myPertinentApplicabilityLevel = pullInferenceErrorMessagesFromSubexpressions(getPertinentApplicabilityLevelInner());
}
return myPertinentApplicabilityLevel;
}
@@ -119,6 +118,7 @@ public class MethodCandidateInfo extends CandidateInfo{
/**
* 15.12.2.2 Identify Matching Arity Methods Applicable by Strict Invocation
*/
@ApplicabilityLevelConstant
public int getPertinentApplicabilityLevelInner() {
if (myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
return getApplicabilityLevel();
@@ -474,9 +474,9 @@ public class MethodCandidateInfo extends CandidateInfo{
return errorMessage;
}
private int pullInferenceErrorMessagesFromSubexpressions() {
if (myArgumentList instanceof PsiExpressionList &&
(myPertinentApplicabilityLevel == ApplicabilityLevel.NOT_APPLICABLE || !isToInferApplicability())) {
@ApplicabilityLevelConstant
private int pullInferenceErrorMessagesFromSubexpressions(@ApplicabilityLevelConstant int level) {
if (myArgumentList instanceof PsiExpressionList && level == ApplicabilityLevel.NOT_APPLICABLE) {
String errorMessage = null;
for (PsiExpression expression : ((PsiExpressionList)myArgumentList).getExpressions()) {
final String message = clearErrorMessageInSubexpressions(expression);
@@ -486,10 +486,9 @@ public class MethodCandidateInfo extends CandidateInfo{
}
if (errorMessage != null) {
setInferenceError(errorMessage);
return ApplicabilityLevel.NOT_APPLICABLE;
}
}
return myPertinentApplicabilityLevel;
return level;
}
private static String clearErrorMessageInSubexpressions(PsiExpression expression) {
@@ -19,7 +19,6 @@ import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
@@ -168,12 +167,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
if (staticFactoryCandidateInfo == null) {
return DiamondInferenceResult.NULL_RESULT;
}
final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(context, false, () -> {
PsiSubstitutor substitutor = staticFactoryCandidateInfo.getSubstitutor();
return staticFactoryCandidateInfo instanceof MethodCandidateInfo &&
((MethodCandidateInfo)staticFactoryCandidateInfo).getInferenceErrorMessage() != null
? null : substitutor;
});
final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(context, false, () -> staticFactoryCandidateInfo.getSubstitutor());
if (inferredSubstitutor == null) {
return DiamondInferenceResult.NULL_RESULT;
}
@@ -182,9 +176,11 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
return DiamondInferenceResult.UNRESOLVED_CONSTRUCTOR;
}
final String errorMessage = ((MethodCandidateInfo)staticFactoryCandidateInfo).getInferenceErrorMessage();
//15.9.3 Choosing the Constructor and its Arguments
//The return type and throws clause of cj are the same as the return type and throws clause determined for mj (§15.12.2.6)
if (InferenceSession.wasUncheckedConversionPerformed(context)) {
if (errorMessage == null && InferenceSession.wasUncheckedConversionPerformed(context)) {
return DiamondInferenceResult.RAW_RESULT;
}
@@ -199,9 +195,14 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
final PsiTypeParameter[] classParameters = psiClass.getTypeParameters();
final PsiJavaCodeReferenceElement classOrAnonymousClassReference = newExpression.getClassOrAnonymousClassReference();
LOG.assertTrue(classOrAnonymousClassReference != null);
final DiamondInferenceResult result = new DiamondInferenceResult(classOrAnonymousClassReference.getReferenceName() + "<>");
final DiamondInferenceResult result = new DiamondInferenceResult(classOrAnonymousClassReference.getReferenceName() + "<>") {
@Override
public String getErrorMessage() {
return errorMessage != null ? DiamondInferenceResult.NULL_RESULT.getErrorMessage() : super.getErrorMessage();
}
};
if (PsiUtil.isRawSubstitutor(staticFactory, inferredSubstitutor)) {
if (errorMessage == null && PsiUtil.isRawSubstitutor(staticFactory, inferredSubstitutor)) {
//http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html#A999198 REF 7144506
if (!PsiUtil.isLanguageLevel8OrHigher(newExpression) && PsiUtil.skipParenthesizedExprUp(newExpression.getParent()) instanceof PsiExpressionList) {
for (PsiTypeParameter ignored : parameters) {
@@ -5,10 +5,10 @@ class Test {
Result<String> r2 = Result.create<error descr="'create(K)' in 'Result' cannot be applied to '(Holder)'">(h)</error>;
Holder dataHolder = null;
Result<String> r3 = new Result<error descr="Cannot infer arguments"><></error>(new Holder<>(dataHolder));
Result<String> r3 = new Result<error descr="Cannot infer arguments"><></error>(new Holder<error descr="Cannot infer arguments"><></error>(dataHolder));
Result<String> r4 = Result.create(new Holder<error descr="Cannot infer arguments"><></error>(dataHolder));
Result<String> r5 = new Result<error descr="Cannot infer arguments"><></error>(Holder.create(dataHolder));
Result<String> r5 = new Result<error descr="Cannot infer arguments"><></error>(Holder.create<error descr="'create(Holder<M>)' in 'Holder' cannot be applied to '(Holder)'">(dataHolder)</error>);
Result<String> r6 = Result.create(Holder.create<error descr="'create(Holder<M>)' in 'Holder' cannot be applied to '(Holder)'">(dataHolder)</error>);
}
@@ -29,7 +29,7 @@ public class ConcurrentCollectors {
static <T, K, D, M1 extends Map<K, D>> C<T, M1> groupingBy(F<M1> f,
C<T, D> c,
BiConsumer<M1, T> consumer) {
return new CImpl<error descr="Cannot infer arguments"><></error>(f, consumer, arg(c.getOp()));
return new CImpl<error descr="Cannot infer arguments"><></error>(f, consumer, arg<error descr="'arg(ConcurrentCollectors.BiOp<V>)' in 'ConcurrentCollectors.Test3' cannot be applied to '(ConcurrentCollectors.BiOp<D>)'">(c.getOp())</error>);
}
static <K, V, M2 extends ConcurrentMap<K, V>> BiOp<M2> arg(BiOp<V> op) {