mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
lambda: correct inference for vararg place > params.len (IDEA-101169)
This commit is contained in:
@@ -130,6 +130,13 @@ public class LambdaUtil {
|
||||
if (type instanceof PsiClassType && ((PsiClassType)type).isRaw()) {
|
||||
return true;
|
||||
}
|
||||
final PsiMethod method = ((PsiMethodCallExpression)gParent).resolveMethod();
|
||||
if (method != null) {
|
||||
int lambdaIdx = getLambdaIdx((PsiExpressionList)parent, expression);
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiType normalizedType = getNormalizedType(parameters[adjustLambdaIdx(lambdaIdx, method, parameters)]);
|
||||
if (normalizedType instanceof PsiClassType && ((PsiClassType)normalizedType).isRaw()) return true;
|
||||
}
|
||||
}
|
||||
if (functionalInterfaceType instanceof PsiClassType && ((PsiClassType)functionalInterfaceType).isRaw()){
|
||||
return false;
|
||||
@@ -440,7 +447,7 @@ public class LambdaUtil {
|
||||
final Pair<PsiMethod, PsiSubstitutor> method = currentMethodCandidates != null ? currentMethodCandidates.get(parent) : null;
|
||||
if (method != null) {
|
||||
final PsiParameter[] parameters = method.first.getParameterList().getParameters();
|
||||
cachedType = lambdaIdx < parameters.length ? method.second.substitute(parameters[lambdaIdx].getType()) : null;
|
||||
cachedType = lambdaIdx < parameters.length ? method.second.substitute(getNormalizedType(parameters[adjustLambdaIdx(lambdaIdx, method.first, parameters)])) : null;
|
||||
if (!tryToSubstitute) return cachedType;
|
||||
}
|
||||
|
||||
@@ -451,8 +458,9 @@ public class LambdaUtil {
|
||||
final PsiElement resolve = resolveResult.getElement();
|
||||
if (resolve instanceof PsiMethod) {
|
||||
final PsiParameter[] parameters = ((PsiMethod)resolve).getParameterList().getParameters();
|
||||
if (lambdaIdx < parameters.length) {
|
||||
if (!tryToSubstitute) return parameters[lambdaIdx].getType();
|
||||
final int finalLambdaIdx = adjustLambdaIdx(lambdaIdx, (PsiMethod)resolve, parameters);
|
||||
if (finalLambdaIdx < parameters.length) {
|
||||
if (!tryToSubstitute) return getNormalizedType(parameters[finalLambdaIdx]);
|
||||
if (cachedType != null && paramIdx > -1) {
|
||||
final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(cachedType);
|
||||
if (interfaceMethod != null) {
|
||||
@@ -466,7 +474,7 @@ public class LambdaUtil {
|
||||
return PsiResolveHelper.ourGuard.doPreventingRecursion(expression, true, new Computable<PsiType>() {
|
||||
@Override
|
||||
public PsiType compute() {
|
||||
return resolveResult.getSubstitutor().substitute(parameters[lambdaIdx].getType());
|
||||
return resolveResult.getSubstitutor().substitute(getNormalizedType(parameters[finalLambdaIdx]));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -490,6 +498,24 @@ public class LambdaUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int adjustLambdaIdx(int lambdaIdx, PsiMethod resolve, PsiParameter[] parameters) {
|
||||
final int finalLambdaIdx;
|
||||
if (((PsiMethod)resolve).isVarArgs() && lambdaIdx >= parameters.length) {
|
||||
finalLambdaIdx = parameters.length - 1;
|
||||
} else {
|
||||
finalLambdaIdx = lambdaIdx;
|
||||
}
|
||||
return finalLambdaIdx;
|
||||
}
|
||||
|
||||
private static PsiType getNormalizedType(PsiParameter parameter) {
|
||||
final PsiType type = parameter.getType();
|
||||
if (type instanceof PsiEllipsisType) {
|
||||
return ((PsiEllipsisType)type).getComponentType();
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static PsiType getLambdaParameterType(PsiParameter param) {
|
||||
final PsiElement paramParent = param.getParent();
|
||||
if (paramParent instanceof PsiParameterList) {
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import java.util.*;
|
||||
|
||||
class IDEA101169 {
|
||||
{
|
||||
List<List<UnaryOperator<String>>> intPermutationOfFunctions = perm(asList( s -> s.substring(0), s -> s.substring(0), s -> s.substring(0)));
|
||||
|
||||
List<UnaryOperator<String>> p = asList( s -> s.substring(0), s -> s.substring(0), s -> s.substring(0));
|
||||
}
|
||||
|
||||
public static <T> List<List<T>> perm(List<T> l) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> List<T> asList(T... a) {
|
||||
return null;
|
||||
}
|
||||
|
||||
interface UnaryOperator<T> extends Function<T, T> {}
|
||||
|
||||
interface Function<T, R> {
|
||||
public R apply(T t);
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -104,7 +104,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testLambdaOnVarargPlace() throws Exception {
|
||||
public void testLambdaOnVarargsPlace() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -208,6 +208,10 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testLambdaOnVarargsPlace1() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user