lambda: ensure static factory is used when diamonds

This commit is contained in:
Anna Kozlova
2017-05-04 20:29:52 +03:00
parent 5516110b50
commit 1d36b86e0c
9 changed files with 34 additions and 49 deletions
@@ -431,7 +431,7 @@ public class LambdaUtil {
return properties.getSubstitutor().substitute(getNormalizedType(parameters[finalLambdaIdx]));
}
}
final JavaResolveResult resolveResult = properties != null ? properties.getInfo() : contextCall.resolveMethodGenerics();
JavaResolveResult resolveResult = properties != null ? properties.getInfo() : PsiDiamondType.getDiamondsAwareResolveResult(contextCall);
return getSubstitutedType(expression, tryToSubstitute, lambdaIdx, resolveResult);
}
}
@@ -181,6 +181,17 @@ public abstract class PsiDiamondType extends PsiType {
return null;
}
public static JavaResolveResult getDiamondsAwareResolveResult(PsiCall expression) {
if (expression instanceof PsiNewExpression) {
PsiDiamondType diamondType = getDiamondType((PsiNewExpression)expression);
if (diamondType != null) {
return diamondType.getStaticFactory();
}
}
return expression.resolveMethodGenerics();
}
@Nullable
public abstract JavaResolveResult getStaticFactory();
}
@@ -506,15 +506,7 @@ public class MethodCandidateInfo extends CandidateInfo{
return elseErrorMessage;
}
else if (expression instanceof PsiCallExpression) {
final JavaResolveResult result;
if (expression instanceof PsiNewExpression) {
PsiDiamondType diamondType = PsiDiamondType.getDiamondType((PsiNewExpression)expression);
result = diamondType != null ? diamondType.getStaticFactory()
: ((PsiCallExpression)expression).resolveMethodGenerics();
}
else {
result = ((PsiCallExpression)expression).resolveMethodGenerics();
}
final JavaResolveResult result = PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)expression);
if (result instanceof MethodCandidateInfo) {
final String message = ((MethodCandidateInfo)result).getInferenceErrorMessage();
((MethodCandidateInfo)result).setInferenceError(null);
@@ -21,7 +21,6 @@ import com.intellij.psi.*;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.impl.PsiClassImplUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.scope.MethodProcessorSetupFailedException;
import com.intellij.psi.scope.processor.MethodResolverProcessor;
@@ -458,7 +457,7 @@ public class ExceptionUtil {
return Collections.emptyList();
}
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(methodCall.getArgumentList());
final JavaResolveResult result = properties != null ? properties.getInfo() : InferenceSession.getResolveResult(methodCall);
final JavaResolveResult result = properties != null ? properties.getInfo() : PsiDiamondType.getDiamondsAwareResolveResult(methodCall);
final PsiElement element = result.getElement();
final PsiMethod method = element instanceof PsiMethod ? (PsiMethod)element : null;
if (method == null) {
@@ -314,13 +314,7 @@ public class PsiDiamondTypeUtil {
private static boolean checkParentApplicability(PsiExpression exprCopy) {
while (exprCopy != null){
JavaResolveResult resolveResult = exprCopy instanceof PsiCallExpression ? ((PsiCallExpression)exprCopy).resolveMethodGenerics() : null;
if (exprCopy instanceof PsiNewExpression) {
PsiDiamondType diamondType = PsiDiamondType.getDiamondType((PsiNewExpression)exprCopy);
if (diamondType != null) {
resolveResult = diamondType.getStaticFactory();
}
}
JavaResolveResult resolveResult = exprCopy instanceof PsiCallExpression ? PsiDiamondType.getDiamondsAwareResolveResult((PsiCall)exprCopy) : null;
if (resolveResult instanceof MethodCandidateInfo && !((MethodCandidateInfo)resolveResult).isApplicable()) {
return false;
}
@@ -527,7 +527,7 @@ public class InferenceSession {
if (properties != null) {
return properties.getMethod();
}
final JavaResolveResult resolveResult = getResolveResult(arg);
final JavaResolveResult resolveResult = PsiDiamondType.getDiamondsAwareResolveResult(arg);
if (resolveResult instanceof MethodCandidateInfo) {
return (PsiMethod)resolveResult.getElement();
}
@@ -587,7 +587,7 @@ public class InferenceSession {
PsiExpressionList argumentList = callExpression.getArgumentList();
if (argumentList != null) {
MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList);
final JavaResolveResult result = properties != null ? null : getResolveResult(callExpression);
final JavaResolveResult result = properties != null ? null : PsiDiamondType.getDiamondsAwareResolveResult(callExpression);
final PsiMethod method = properties != null ? properties.getMethod() : result instanceof MethodCandidateInfo ? ((MethodCandidateInfo)result).getElement() : null;
if (method != null) {
final PsiExpression[] newArgs = argumentList.getExpressions();
@@ -600,33 +600,6 @@ public class InferenceSession {
}
}
public static JavaResolveResult getResolveResult(final PsiCall callExpression) {
if (callExpression instanceof PsiNewExpression && PsiDiamondType.hasDiamond((PsiNewExpression)callExpression)) {
PsiUtilCore.ensureValid(callExpression);
return CachedValuesManager.getCachedValue(callExpression, () -> {
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)callExpression).getClassOrAnonymousClassReference();
JavaResolveResult constructor = JavaResolveResult.EMPTY;
JavaResolveResult resolveResult = null;
if (classReference != null) {
resolveResult = classReference.advancedResolve(false);
final PsiElement psiClass = resolveResult.getElement();
if (psiClass != null) {
final JavaPsiFacade facade = JavaPsiFacade.getInstance(callExpression.getProject());
final PsiExpressionList argumentList = callExpression.getArgumentList();
if (argumentList != null) {
constructor = facade.getResolveHelper().resolveConstructor(facade.getElementFactory().createType((PsiClass)psiClass).rawType(),
argumentList,
callExpression);
}
}
}
return new CachedValueProvider.Result<>(constructor.getElement() == null && resolveResult != null ? resolveResult : constructor,
PsiModificationTracker.MODIFICATION_COUNT);
});
}
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
@@ -137,7 +137,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argumentList);
PsiType returnType = null;
PsiTypeParameter[] typeParams = null;
final JavaResolveResult resolveResult = candidateProperties != null ? null : InferenceSession.getResolveResult((PsiCall)expression);
final JavaResolveResult resolveResult = candidateProperties != null ? null : PsiDiamondType
.getDiamondsAwareResolveResult((PsiCall)expression);
final PsiMethod method = InferenceSession.getCalledMethod((PsiCall)expression);
if (method != null && !method.isConstructor()) {
@@ -0,0 +1,11 @@
import java.util.List;
import java.util.function.Function;
class E<In> {
E(List<In> l, Function<In, Integer> f, List<In> ff) {}
void m(List<String> l, List ff){
E<String> e = new E<>(l, o -> o.length(), ff);
}
}
@@ -85,6 +85,10 @@ public class Diamond8HighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testRawTypePassedToDiamond() throws Exception {
doTest();
}
public void testDiamondInsideOverloadedThisReference() throws Exception {
doTest();
}