reifiable types: skip anonymous types through the tree hierarchy as they can't be generic (IDEA-166840)

This commit is contained in:
Anna Kozlova
2017-01-20 15:51:24 +03:00
parent d857a18335
commit 0fe652059e
2 changed files with 43 additions and 2 deletions
@@ -59,16 +59,25 @@ public class JavaGenericsUtil {
}
assert parameters.length == 0;
final PsiClassType.ClassResolveResult resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolveGenerics();
final PsiClassType.ClassResolveResult resolved = classType.resolveGenerics();
final PsiClass aClass = resolved.getElement();
if (aClass instanceof PsiTypeParameter) {
return false;
}
if (aClass != null && !aClass.hasModifierProperty(PsiModifier.STATIC)) {
PsiModifierListOwner enclosingStaticElement = PsiUtil.getEnclosingStaticElement(aClass, aClass.getContainingClass());
//local class (inner inside inside anonymous) should skip anonymous as it can't be static itself
final PsiClass stopClassLevel = PsiUtil.isLocalClass(aClass) ? null : aClass.getContainingClass();
PsiModifierListOwner enclosingStaticElement = PsiUtil.getEnclosingStaticElement(aClass, stopClassLevel);
PsiClass containingClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
if (containingClass != null && (enclosingStaticElement == null || PsiTreeUtil.isAncestor(enclosingStaticElement, containingClass, false))) {
//anonymous classes are not generic
while (containingClass instanceof PsiAnonymousClass) {
containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class, true);
}
if (containingClass == null || enclosingStaticElement != null && !PsiTreeUtil.isAncestor(enclosingStaticElement, containingClass, false)) {
return true;
}
return isReifiableType(JavaPsiFacade.getElementFactory(aClass.getProject()).createType(containingClass, resolved.getSubstitutor()));
}
}
@@ -21,4 +21,36 @@ class B<T> {
return new C();
}
static interface I<T> {}
void anonymousClassWithLocal() {
I<Object> i = new I<Object>() {
class InsideAnno {}
{
InsideAnno[] array = <error descr="Generic array creation">new InsideAnno[1]</error>;
}
};
}
static void staticAnonymousClassWithLocal() {
I<Object> i = new I<Object>() {
class InsideAnno {}
{
InsideAnno[] array = new InsideAnno[1];
}
};
}
static void staticAnonymousClassWithGenericLocal() {
I<Object> i = new I<Object>() {
class InsideAnno<J> {
class O {}
{
O[] array = <error descr="Generic array creation">new O[1]</error>;
}
}
};
}
}