overload resolution: choose one of overload equivalent abstract methods arbitrarily (IDEA-146261)

This commit is contained in:
Anna Kozlova
2015-10-12 17:55:36 +02:00
parent 92a570e457
commit d13663483d
4 changed files with 51 additions and 0 deletions

View File

@@ -58,6 +58,11 @@ public class MethodSignatureUtil {
}
};
public static boolean areOverrideEquivalent(PsiMethod method1, PsiMethod method2) {
return method1.getTypeParameters().length == method2.getTypeParameters().length &&
areErasedParametersEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY));
}
public static boolean areErasedParametersEqual(@NotNull MethodSignature method1, @NotNull MethodSignature method2) {
PsiType[] erased1 = method1 instanceof MethodSignatureBase
? ((MethodSignatureBase)method1).getErasedParameterTypes() : calcErasedParameterTypes(method1);

View File

@@ -630,6 +630,15 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
if (abstract2 && !abstract1) {
return Specifics.FIRST;
}
if (abstract1 && abstract2 && MethodSignatureUtil.areOverrideEquivalent(method1, method2)) {
final PsiType returnType1 = method1.getReturnType();
final PsiType returnType2 = method2.getReturnType();
if (returnType1 != null && returnType2 != null && returnType1.isAssignableFrom(returnType2)) {
return Specifics.SECOND;
}
return Specifics.FIRST;
}
}
}
else if (varargsPosition) {

View File

@@ -0,0 +1,33 @@
import java.util.List;
class Test1 {
interface A {
<T extends Comparable<T>> String foo(List<T> x);
}
interface B {
<K extends Comparable<K>> CharSequence foo(List<K> x);
}
class X {
<S extends A & B> void bar(S x) {
x.foo(null);
}
}
}
class Test2 {
interface A {
void foo();
}
interface B {
void foo();
}
abstract class X implements A, B {
{
foo();
}
}
}

View File

@@ -167,6 +167,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testChooseAbstractMethodArbitrarily() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}