mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
most specific check for proper functional types fixed
This commit is contained in:
@@ -741,8 +741,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
if (myArgumentsList instanceof PsiExpressionList) {
|
||||
final PsiExpression[] expressions = ((PsiExpressionList)myArgumentsList).getExpressions();
|
||||
if (argId < expressions.length) {
|
||||
final Specifics specific = isFunctionalTypeMoreSpecific(expressions[argId], right, left);
|
||||
return Specifics.FIRST.equals(specific);
|
||||
return isFunctionalTypeMoreSpecific(expressions[argId], right, left);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -826,36 +825,31 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Specifics isFunctionalTypeMoreSpecific(PsiExpression expr, PsiType sType, PsiType tType) {
|
||||
private static boolean isFunctionalTypeMoreSpecific(PsiExpression expr, PsiType sType, PsiType tType) {
|
||||
if (expr instanceof PsiParenthesizedExpression) {
|
||||
return isFunctionalTypeMoreSpecific(((PsiParenthesizedExpression)expr).getExpression(), sType, tType);
|
||||
}
|
||||
|
||||
if (expr instanceof PsiConditionalExpression) {
|
||||
final Specifics thenSpecifics = isFunctionalTypeMoreSpecific(((PsiConditionalExpression)expr).getThenExpression(), sType, tType);
|
||||
final Specifics elseSpecifics = isFunctionalTypeMoreSpecific(((PsiConditionalExpression)expr).getElseExpression(), sType, tType);
|
||||
return thenSpecifics == elseSpecifics ? thenSpecifics : Specifics.NEITHER;
|
||||
return isFunctionalTypeMoreSpecific(((PsiConditionalExpression)expr).getThenExpression(), sType, tType) &&
|
||||
isFunctionalTypeMoreSpecific(((PsiConditionalExpression)expr).getElseExpression(), sType, tType);
|
||||
}
|
||||
|
||||
if (expr instanceof PsiFunctionalExpression) {
|
||||
|
||||
if (expr instanceof PsiLambdaExpression && !((PsiLambdaExpression)expr).hasFormalParameterTypes()) {
|
||||
return Specifics.NEITHER;
|
||||
return false;
|
||||
}
|
||||
if (expr instanceof PsiMethodReferenceExpression && !((PsiMethodReferenceExpression)expr).isExact()) {
|
||||
return Specifics.NEITHER;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LambdaUtil.isFunctionalType(sType) && LambdaUtil.isFunctionalType(tType) &&
|
||||
!TypeConversionUtil.erasure(tType).isAssignableFrom(sType) &&
|
||||
!TypeConversionUtil.erasure(sType).isAssignableFrom(tType)) {
|
||||
final boolean specific12 = InferenceSession.isFunctionalTypeMoreSpecificOnExpression(sType, tType, expr);
|
||||
final boolean specific21 = InferenceSession.isFunctionalTypeMoreSpecificOnExpression(tType, sType, expr);
|
||||
if (specific12 && !specific21) return Specifics.FIRST;
|
||||
if (!specific12 && specific21) return Specifics.SECOND;
|
||||
return InferenceSession.isFunctionalTypeMoreSpecificOnExpression(sType, tType, expr);
|
||||
}
|
||||
}
|
||||
return Specifics.NEITHER;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
class Main {
|
||||
|
||||
void perform(Runnable r) {
|
||||
System.out.println(r);
|
||||
}
|
||||
|
||||
<T extends Throwable> void perform(TRunnable<T> r) {
|
||||
System.out.println(r);
|
||||
}
|
||||
|
||||
|
||||
interface TRunnable<T extends Throwable> {
|
||||
void run() throws T;
|
||||
}
|
||||
|
||||
{
|
||||
<error descr="Ambiguous method call: both 'Main.perform(Runnable)' and 'Main.perform(TRunnable<RuntimeException>)' match">perform</error>(() -> {});
|
||||
}
|
||||
}
|
||||
@@ -221,6 +221,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSpecificFunctionalInterfaces() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user