ambiguous method calls: multiple inheritance (IDEA-89314)

This commit is contained in:
Anna Kozlova
2012-08-03 13:19:49 +02:00
parent dd5a9764ce
commit 4cb6d673b8
3 changed files with 54 additions and 1 deletions

View File

@@ -163,7 +163,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
}
}
private static void checkSameSignatures(final List<CandidateInfo> conflicts) {
private void checkSameSignatures(final List<CandidateInfo> conflicts) {
// candidates should go in order of class hierarchy traversal
// in order for this to work
Map<MethodSignature, CandidateInfo> signatures = new HashMap<MethodSignature, CandidateInfo>();
@@ -253,6 +253,27 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
// prefer derived class
signatures.put(signature, info);
} else {
final PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(myArgumentsList, PsiMethodCallExpression.class);
if (methodCallExpression != null) {
final PsiReferenceExpression expression = methodCallExpression.getMethodExpression();
final PsiExpression qualifierExpression = expression.getQualifierExpression();
PsiClass currentClass;
if (qualifierExpression != null) {
currentClass = PsiUtil.resolveClassInClassTypeOnly(qualifierExpression.getType());
} else {
currentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
}
if (currentClass != null && InheritanceUtil.isInheritorOrSelf(currentClass, class1, true) && InheritanceUtil.isInheritorOrSelf(currentClass, existingClass, true)) {
if (MethodSignatureUtil.areSignaturesEqual(existingMethod.getSignature(TypeConversionUtil.getSuperClassSubstitutor(existingClass, currentClass, PsiSubstitutor.EMPTY)),
method.getSignature(TypeConversionUtil.getSuperClassSubstitutor(class1, currentClass, PsiSubstitutor.EMPTY)))) {
conflicts.remove(i);
i--;
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,28 @@
class A<T>{}
interface I<Q extends I<Q>> {
Q from(A<?>... paths);
}
interface II extends I<II> {}
class C<Q extends C<Q>> {
public Q from(A<?>... args) {return null;}
}
class AC<Q extends AC<Q>> extends C<Q> {}
class CC extends AC<CC> implements II {
void bar() {
from(null);
}
static void barStatic() {
<error descr="Non-static method 'from(A<?>...)' cannot be referenced from a static context">from</error>(null);
}
}
class Test {
void foo(CC a){
a.from(null);
}
}

View File

@@ -53,4 +53,8 @@ public class AmbiguousMethodCallTest extends LightDaemonAnalyzerTestCase {
public void testBoxingAndStaticMethods() throws Exception {
doTest(false, false);
}
public void testMultipleInheritance() throws Exception {
doTest(false, false);
}
}