Java: correctly check if class is inner class according to the JLS (IDEA-336426)

and clarify error message

GitOrigin-RevId: 4614ced685521a06fee1bb681001e1484f9dca7d
This commit is contained in:
Bas Leijdekkers
2024-01-05 10:35:46 +01:00
committed by intellij-monorepo-bot
parent 5dc633a1ab
commit e7ee84d0ca
3 changed files with 33 additions and 4 deletions

View File

@@ -1021,7 +1021,7 @@ public final class HighlightClassUtil {
if (targetClass == null) return null;
PsiExpression qualifier = superCall.getMethodExpression().getQualifierExpression();
if (qualifier != null) {
if (PsiUtil.isInnerClass(targetClass)) {
if (isRealInnerClass(targetClass)) {
PsiClass outerClass = targetClass.getContainingClass();
if (outerClass != null) {
PsiClassType outerType = JavaPsiFacade.getElementFactory(project).createType(outerClass);
@@ -1035,6 +1035,15 @@ public final class HighlightClassUtil {
return null;
}
/** JLS 8.1.3. Inner Classes and Enclosing Instances */
private static boolean isRealInnerClass(PsiClass aClass) {
if (PsiUtil.isInnerClass(aClass)) return true;
if (!PsiUtil.isLocalOrAnonymousClass(aClass)) return false;
if (aClass.hasModifierProperty(PsiModifier.STATIC)) return false; // check for implicit staticness
PsiMember member = PsiTreeUtil.getParentOfType(aClass, PsiMember.class, true);
return member != null && !member.hasModifierProperty(PsiModifier.STATIC);
}
static HighlightInfo.Builder checkIllegalEnclosingUsage(@NotNull PsiElement place,
@Nullable PsiClass aClass,
@NotNull PsiClass outerClass,

View File

@@ -544,7 +544,7 @@ class.cannot.be.inherited.with.different.arguments={0} cannot be inherited with
bad.type.in.switch.expression=Bad type in switch expression: {0} cannot be converted to {1}
switch.expression.cannot.be.void=Target type for switch expression cannot be void
annotation.on.static.member.qualifying.type.family.name=Move type annotation
not.inner.class=''{0}'' is not an inner class
not.inner.class=Qualifier is not allowed because superclass ''{0}'' is not a non-static inner class
anonymous.class.implements.interface.cannot.have.qualifier=Anonymous class implements interface; cannot have qualifier for new
qualified.class.reference.not.allowed.in.qualified.new=Qualified class reference is not allowed in qualified new
actual.type.argument.contradict.inferred.type=Actual type argument and inferred type contradict each other

View File

@@ -19,16 +19,36 @@ class A1 {
class C extends S {
C(A1 c) {
<error descr="'A1.S' is not an inner class">c</error>.super();
<error descr="Qualifier is not allowed because superclass 'A1.S' is not a non-static inner class">c</error>.super();
}
}
}
class C2 {
C2(String c){
<error descr="'java.lang.Object' is not an inner class">c</error>.super();
<error descr="Qualifier is not allowed because superclass 'java.lang.Object' is not a non-static inner class">c</error>.super();
}
}
class Scratch {
void method() {
class A {}
class B extends A {
B() {
new Scratch().super();
}
}
}
static void method2() {
class A {}
class B extends A {
B() {
<error descr="Qualifier is not allowed because superclass 'A' is not a non-static inner class">new Scratch()</error>.super();
}
}
}
}
class A3 {
class S {