mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: open/close capture when method reference is resolved (IDEA-128712)
This commit is contained in:
@@ -75,20 +75,22 @@ public class PsiMethodReferenceUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isCorrectAssignment(PsiType[] signatureParameterTypes2,
|
||||
PsiType[] parameterTypes,
|
||||
public static boolean isCorrectAssignment(PsiType[] parameterTypes,
|
||||
PsiType[] argTypes,
|
||||
boolean varargs,
|
||||
int offset) {
|
||||
final int min = Math.min(signatureParameterTypes2.length, parameterTypes.length - offset);
|
||||
final int min = Math.min(parameterTypes.length, argTypes.length - offset);
|
||||
for (int i = 0; i < min; i++) {
|
||||
final PsiType type1 = parameterTypes[i + offset];
|
||||
final PsiType type2 = signatureParameterTypes2[i];
|
||||
if (varargs && i == signatureParameterTypes2.length - 1) {
|
||||
if (!TypeConversionUtil.isAssignable(type2, type1) && !TypeConversionUtil.isAssignable(((PsiArrayType)type2).getComponentType(), type1)) {
|
||||
final PsiType argType = argTypes[i + offset];
|
||||
PsiType parameterType = parameterTypes[i];
|
||||
parameterType = GenericsUtil.getVariableTypeByExpressionType(parameterType, true);
|
||||
if (varargs && i == parameterTypes.length - 1) {
|
||||
if (!TypeConversionUtil.isAssignable(parameterType, argType) &&
|
||||
!TypeConversionUtil.isAssignable(((PsiArrayType)parameterType).getComponentType(), argType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!TypeConversionUtil.isAssignable(type2, type1)) {
|
||||
else if (!TypeConversionUtil.isAssignable(parameterType, argType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.*;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -784,6 +785,7 @@ public class InferenceSession {
|
||||
PsiSubstitutor substitutor) {
|
||||
final List<PsiType> lowerBounds = variable.getBounds(boundType);
|
||||
PsiType lub = PsiType.NULL;
|
||||
List<PsiType> dTypes = new ArrayList<PsiType>();
|
||||
for (PsiType lowerBound : lowerBounds) {
|
||||
lowerBound = substituteNonProperBound(lowerBound, substitutor);
|
||||
final HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
|
||||
@@ -970,7 +972,8 @@ public class InferenceSession {
|
||||
|
||||
for (int i = 0; i < functionalMethodParameters.length; i++) {
|
||||
final PsiType pType = signature.getParameterTypes()[i];
|
||||
addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs), pType));
|
||||
addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs),
|
||||
PsiImplUtil.normalizeWildcardTypeByPosition(pType, reference)));
|
||||
}
|
||||
}
|
||||
else if (parameters.length + 1 == functionalMethodParameters.length && !varargs ||
|
||||
@@ -1004,7 +1007,8 @@ public class InferenceSession {
|
||||
|
||||
for (int i = 0; i < signature.getParameterTypes().length - 1; i++) {
|
||||
final PsiType interfaceParamType = signature.getParameterTypes()[i + 1];
|
||||
addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs), interfaceParamType));
|
||||
addConstraint(new TypeCompatibilityConstraint(getParameterType(parameters, i, PsiSubstitutor.EMPTY, varargs),
|
||||
PsiImplUtil.normalizeWildcardTypeByPosition(interfaceParamType, reference)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -231,8 +231,8 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
checkSameSignatures(conflicts);
|
||||
checkAccessStaticLevels(conflicts, true);
|
||||
|
||||
final PsiType[] parameterTypes = mySignature.getParameterTypes();
|
||||
boolean hasReceiver = PsiMethodReferenceUtil.hasReceiver(parameterTypes, myQualifierResolveResult, myReferenceExpression);
|
||||
final PsiType[] argTypes = mySignature.getParameterTypes();
|
||||
boolean hasReceiver = PsiMethodReferenceUtil.hasReceiver(argTypes, myQualifierResolveResult, myReferenceExpression);
|
||||
|
||||
final List<CandidateInfo> firstCandidates = new ArrayList<CandidateInfo>();
|
||||
final List<CandidateInfo> secondCandidates = new ArrayList<CandidateInfo>();
|
||||
@@ -242,19 +242,19 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
|
||||
final PsiMethod psiMethod = ((MethodCandidateInfo)conflict).getElement();
|
||||
|
||||
final PsiSubstitutor substitutor = conflict.getSubstitutor();
|
||||
final PsiType[] signatureParameterTypes2 = psiMethod.getSignature(substitutor).getParameterTypes();
|
||||
final PsiType[] parameterTypes = psiMethod.getSignature(substitutor).getParameterTypes();
|
||||
|
||||
final boolean varargs = ((MethodCandidateInfo)conflict).isVarargs();
|
||||
if (varargs && (!psiMethod.isVarArgs() || myFunctionalMethodVarArgs)) continue;
|
||||
|
||||
if ((varargs || parameterTypes.length == signatureParameterTypes2.length) &&
|
||||
PsiMethodReferenceUtil.isCorrectAssignment(signatureParameterTypes2, parameterTypes, varargs, 0)) {
|
||||
if ((varargs || argTypes.length == parameterTypes.length) &&
|
||||
PsiMethodReferenceUtil.isCorrectAssignment(parameterTypes, argTypes, varargs, 0)) {
|
||||
firstCandidates.add(conflict);
|
||||
}
|
||||
|
||||
if (hasReceiver &&
|
||||
(varargs || parameterTypes.length == signatureParameterTypes2.length + 1) &&
|
||||
PsiMethodReferenceUtil.isCorrectAssignment(signatureParameterTypes2, parameterTypes, varargs, 1)) {
|
||||
(varargs || argTypes.length == parameterTypes.length + 1) &&
|
||||
PsiMethodReferenceUtil.isCorrectAssignment(parameterTypes, argTypes, varargs, 1)) {
|
||||
secondCandidates.add(conflict);
|
||||
}
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class Foo {
|
||||
{
|
||||
map(Foo::bar);
|
||||
map(a -> Foo.bar(a));
|
||||
}
|
||||
|
||||
<R> Stream<R> map(Function<Class<?>, ? extends R> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static <T> Collection<T> bar(Class<T> baseClass) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+4
@@ -301,6 +301,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA128712() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user