IDEA-117082 Anonymous class assigned to final field

This commit is contained in:
anna
2013-11-26 18:51:18 +01:00
parent cbcc0e87dc
commit 02cabc4e84
3 changed files with 50 additions and 2 deletions
@@ -25,6 +25,7 @@ package com.intellij.psi.scope.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.util.Comparing;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
@@ -318,7 +319,13 @@ public class PsiScopesUtil {
if (initializer instanceof PsiNewExpression) {
final PsiAnonymousClass anonymousClass = ((PsiNewExpression)initializer).getAnonymousClass();
if (anonymousClass != null && type.equals(anonymousClass.getBaseClassType())) {
type = initializer.getType();
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)) {
type = initializer.getType();
}
}
}
}
}
@@ -381,6 +388,18 @@ public class PsiScopesUtil {
}
}
private static boolean hasCovariantOverriding(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;
}
}
}
return false;
}
private static boolean processQualifierType(@NotNull final PsiType type,
final MethodsProcessor processor,
PsiManager manager,
@@ -0,0 +1,20 @@
interface X {
A[] foo();
}
class A {}
class B extends A {}
class C {
final X x = new X() {
@Override
public B[] foo() {
return new B[0];
}
};
B[] bar() {
return x.f<ref>oo();
}
}
@@ -7,7 +7,6 @@ import com.intellij.navigation.NavigationItem;
import org.jetbrains.annotations.NonNls;
import static org.junit.Assert.assertThat;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.assertTrue;
/**
* @author dsl
@@ -129,6 +128,16 @@ public class ResolveMethod15Test extends Resolve15TestCase {
assertTrue(containingClass != null ? containingClass.getName() : null, containingClass instanceof PsiAnonymousClass);
}
public void testCovariantReturnTypeAnonymous() 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));