resolve: ensure visibility won't change if method from anonymous class replaces method from base one (IDEA-137276)

(cherry picked from commit 0a6fdd997a8931a67406e9e9094864e90dfa11ec)
This commit is contained in:
Anna Kozlova
2015-03-09 13:27:56 +01:00
parent 85f685de9e
commit baad11327a
3 changed files with 30 additions and 2 deletions

View File

@@ -322,7 +322,7 @@ public class PsiScopesUtil {
final PsiMethod[] refMethods = anonymousClass.findMethodsByName(methodCall.getMethodExpression().getReferenceName(), false);
if (refMethods.length > 0) {
final PsiClass baseClass = PsiUtil.resolveClassInType(type);
if (baseClass != null && !hasCovariantOverriding(baseClass, refMethods)) {
if (baseClass != null && !hasCovariantOverridingOrNotPublic(baseClass, refMethods)) {
for (PsiMethod method : refMethods) {
if (method.findSuperMethods(baseClass).length > 0) {
type = initializer.getType();
@@ -393,13 +393,17 @@ public class PsiScopesUtil {
}
}
private static boolean hasCovariantOverriding(PsiClass baseClass, PsiMethod[] refMethods) {
private static boolean hasCovariantOverridingOrNotPublic(PsiClass baseClass, PsiMethod[] refMethods) {
for (PsiMethod method : refMethods) {
final PsiType methodReturnType = method.getReturnType();
for (PsiMethod superMethod : method.findSuperMethods(baseClass)) {
if (!Comparing.equal(methodReturnType, superMethod.getReturnType())) {
return true;
}
if (!superMethod.hasModifierProperty(PsiModifier.PUBLIC)) {
return true;
}
}
}
return false;

View File

@@ -0,0 +1,14 @@
class A {
protected void foo() {}
}
class C {
final A a = new A() {
@Override
public void foo() {}
};
{
a.f<ref>oo();
}
}

View File

@@ -150,6 +150,16 @@ public class ResolveMethod15Test extends Resolve15TestCase {
assertTrue(containingClass != null ? containingClass.getName() : null, !(containingClass instanceof PsiAnonymousClass));
}
public void testNonPublicAnonymous() throws Exception {
final PsiReference ref = configureByFile();
assertThat(ref, instanceOf(PsiReferenceExpression.class));
final PsiReferenceExpression refExpr = (PsiReferenceExpression)ref;
final PsiElement resolve = refExpr.resolve();
assertTrue(resolve != null ? resolve.toString() : null, resolve instanceof PsiMethod);
final PsiClass containingClass = ((PsiMethod)resolve).getContainingClass();
assertTrue(containingClass != null ? containingClass.getName() : null, !(containingClass instanceof PsiAnonymousClass));
}
public void testFilterFixedVsVarargs1() throws Exception {
final PsiReference ref = configureByFile();
assertThat(ref, instanceOf(PsiReferenceExpression.class));