mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: reject partial computation
This commit is contained in:
@@ -376,14 +376,6 @@ public class LambdaUtil {
|
||||
final int lambdaIdx = getLambdaIdx(expressionList, expression);
|
||||
if (lambdaIdx > -1) {
|
||||
|
||||
PsiType cachedType = null;
|
||||
final Pair<PsiMethod, PsiSubstitutor> method = MethodCandidateInfo.getCurrentMethod(parent);
|
||||
if (method != null) {
|
||||
final PsiParameter[] parameters = method.first.getParameterList().getParameters();
|
||||
cachedType = lambdaIdx < parameters.length ? method.second.substitute(getNormalizedType(parameters[adjustLambdaIdx(lambdaIdx, method.first, parameters)])) : null;
|
||||
if (!tryToSubstitute) return cachedType;
|
||||
}
|
||||
|
||||
PsiElement gParent = expressionList.getParent();
|
||||
|
||||
if (gParent instanceof PsiAnonymousClass) {
|
||||
@@ -399,22 +391,6 @@ public class LambdaUtil {
|
||||
final int finalLambdaIdx = adjustLambdaIdx(lambdaIdx, (PsiMethod)resolve, parameters);
|
||||
if (finalLambdaIdx < parameters.length) {
|
||||
if (!tryToSubstitute) return getNormalizedType(parameters[finalLambdaIdx]);
|
||||
if (cachedType != null) {
|
||||
final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(cachedType);
|
||||
if (interfaceMethod != null) {
|
||||
final PsiClassType.ClassResolveResult cachedResult = PsiUtil.resolveGenericsClassInType(cachedType);
|
||||
if (paramIdx == -1) {
|
||||
if (!dependsOnTypeParams(cachedType, cachedType, expression) && !dependsOnTypeParams(getFunctionalInterfaceReturnType(cachedType), cachedType, expression)) {
|
||||
return cachedType;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!dependsOnTypeParams(cachedResult.getSubstitutor().substitute(interfaceMethod.getParameterList().getParameters()[paramIdx].getType()), cachedType, expression)) {
|
||||
return cachedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PsiResolveHelper.ourGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
|
||||
+13
-18
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve.graphInference.constraints;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable;
|
||||
@@ -78,9 +77,8 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
if (myExpression instanceof PsiCallExpression) {
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)myExpression).getArgumentList();
|
||||
if (argumentList != null) {
|
||||
final Pair<PsiMethod,PsiSubstitutor> pair = MethodCandidateInfo.getCurrentMethod(argumentList);
|
||||
final JavaResolveResult resolveResult = pair == null ? ((PsiCallExpression)myExpression).resolveMethodGenerics() : null;
|
||||
final PsiMethod method = pair != null ? pair.first : (PsiMethod)resolveResult.getElement();
|
||||
final JavaResolveResult resolveResult = ((PsiCallExpression)myExpression).resolveMethodGenerics();
|
||||
final PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
PsiType returnType = null;
|
||||
PsiTypeParameter[] typeParams = null;
|
||||
if (method != null && !method.isConstructor()) {
|
||||
@@ -105,21 +103,18 @@ public class ExpressionCompatibilityConstraint extends InputOutputConstraintForm
|
||||
session.addCapturedVariable(typeParam);
|
||||
}
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
if (pair == null) {
|
||||
if (method != null) {
|
||||
//typeParams are already included
|
||||
final Collection<PsiTypeParameter> params = session.getTypeParams();
|
||||
InferenceSession callSession = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), ((MethodCandidateInfo)resolveResult).getSiteSubstitutor(), myExpression.getManager(), myExpression);
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
callSession.initExpressionConstraints(parameters, args, myExpression, method);
|
||||
callSession.registerConstraints(returnType, myT);
|
||||
if (callSession.repeatInferencePhases(true)) {
|
||||
session.liftBounds(callSession.getInferenceVariables());
|
||||
}
|
||||
if (method != null) {
|
||||
//typeParams are already included
|
||||
final Collection<PsiTypeParameter> params = session.getTypeParams();
|
||||
InferenceSession callSession = new InferenceSession(params.toArray(new PsiTypeParameter[params.size()]), resolveResult instanceof MethodCandidateInfo ? ((MethodCandidateInfo)resolveResult).getSiteSubstitutor()
|
||||
: PsiSubstitutor.EMPTY, myExpression.getManager(), myExpression);
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
callSession.initExpressionConstraints(parameters, args, myExpression, method);
|
||||
callSession.registerConstraints(returnType, myT);
|
||||
if (callSession.repeatInferencePhases(true)) {
|
||||
session.liftBounds(callSession.getInferenceVariables());
|
||||
}
|
||||
} else {
|
||||
substitutor = pair.second;
|
||||
}
|
||||
final PsiType capturedReturnType = myExpression instanceof PsiMethodCallExpression
|
||||
? PsiMethodCallExpressionImpl.captureReturnType((PsiMethodCallExpression)myExpression, method, returnType, substitutor)
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
class IntStream {
|
||||
private void foo(IntStream s) {
|
||||
s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> 1 << i)</error>;
|
||||
s.map(i -> <error descr="Operator '<<' cannot be applied to 'int', '<lambda parameter>'">1 << i</error>);
|
||||
s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> 1)</error>;
|
||||
s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<Integer>)' match">(i -> i)</error>;
|
||||
s.map<error descr="Ambiguous method call: both 'IntStream.map(IntUnaryOperator)' and 'IntStream.map(ObjIntFunction<T>)' match">(i -> i)</error>;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ class ReturnTypeIncompatibility {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<Integer>)' and 'ReturnTypeIncompatibility.call(I2<P>)' match">(i-> {return i;})</error>;
|
||||
call<error descr="Ambiguous method call: both 'ReturnTypeIncompatibility.call(I1<P>)' and 'ReturnTypeIncompatibility.call(I2<P>)' match">(i-> {return i;})</error>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collector;
|
||||
|
||||
class Stuff {
|
||||
public enum Type { A }
|
||||
private final int value;
|
||||
private final Type type;
|
||||
public Stuff(int value, Type type) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeErrors {
|
||||
{
|
||||
|
||||
Collector<Stuff, ?, Map<Stuff.Type, Optional<Stuff>>> collector =
|
||||
groupingBy(Stuff::getType,
|
||||
reducing((d1, d2) -> {
|
||||
boolean b = d1.getValue() > d2.getValue();
|
||||
return d1;
|
||||
}));
|
||||
}
|
||||
|
||||
public static <T> Collector<T, ?, Optional<Stuff>> reducing(BinaryOperator<T> op) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T, K, A, D>
|
||||
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
|
||||
Collector<? super T, A, D> downstream) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+4
@@ -126,6 +126,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA119535() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user