overload resolution: grab lambda from nested parenthesis as well as conditional expressions

This commit is contained in:
Anna Kozlova
2014-03-06 11:05:10 +01:00
parent 0c7adaaacb
commit 5412fbc960
3 changed files with 57 additions and 15 deletions

View File

@@ -121,21 +121,40 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
expression = argType instanceof PsiLambdaExpressionType ? ((PsiLambdaExpressionType)argType).getExpression() : null;
}
if (expression instanceof PsiLambdaExpression) {
final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)expression;
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
ProgressManager.checkCanceled();
final CandidateInfo conflict = iterator.next();
final PsiMethod method = (PsiMethod)conflict.getElement();
if (method != null) {
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
if (methodParameters.length == 0) continue;
final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
final PsiType paramType = param.getType();
if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
iterator.remove();
}
}
final PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(expression);
if (lambdaExpression != null) {
checkLambdaApplicable(conflicts, i, lambdaExpression);
}
}
}
private static PsiLambdaExpression findNestedLambdaExpression(PsiExpression expression) {
if (expression instanceof PsiLambdaExpression) {
return (PsiLambdaExpression)expression;
} else if (expression instanceof PsiParenthesizedExpression) {
return findNestedLambdaExpression(((PsiParenthesizedExpression)expression).getExpression());
} else if (expression instanceof PsiConditionalExpression) {
PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(((PsiConditionalExpression)expression).getThenExpression());
if (lambdaExpression != null) {
return lambdaExpression;
}
return findNestedLambdaExpression(((PsiConditionalExpression)expression).getElseExpression());
}
return null;
}
private static void checkLambdaApplicable(List<CandidateInfo> conflicts, int i, PsiLambdaExpression lambdaExpression) {
for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
ProgressManager.checkCanceled();
final CandidateInfo conflict = iterator.next();
final PsiMethod method = (PsiMethod)conflict.getElement();
if (method != null) {
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
if (methodParameters.length == 0) continue;
final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
final PsiType paramType = param.getType();
if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
iterator.remove();
}
}
}

View File

@@ -0,0 +1,19 @@
class Test {
interface A<T> {
T a();
}
interface B<T> {
T b();
}
private void m(A<Integer> <warning descr="Parameter 'a' is never used">a</warning>) { }
private void <warning descr="Private method 'm(Test.B<java.lang.String>)' is never used">m</warning>(B<String> <warning descr="Parameter 'b' is never used">b</warning>) { }
{
m((() -> 42));
m(true ? () -> 42 : () -> 42);
m(true ? null : (() -> 42));
}
}

View File

@@ -39,6 +39,10 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testNestedLambdaSpecifics() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}