Java: fix bad code is green problem (IDEA-366474)

"cannot reference super before superclass constructor is called"

(cherry picked from commit a2eeb5211fed697bc99ec9620bca4493c5a7adae)

GitOrigin-RevId: 6c404d216a804825e70d5c37866e3055dc8c5443
This commit is contained in:
Bas Leijdekkers
2025-01-27 16:02:19 +01:00
committed by intellij-monorepo-bot
parent 2f1f604a68
commit b5a53393ed
6 changed files with 40 additions and 32 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.*;
@@ -51,8 +51,8 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.refactoring.util.RefactoringChangeUtil;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.NewUI;
@@ -69,8 +69,8 @@ import one.util.streamex.StreamEx;
import org.jetbrains.annotations.*;
import java.awt.*;
import java.util.List;
import java.util.*;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -2764,7 +2764,6 @@ public final class HighlightUtil {
PsiClass referencedClass;
String resolvedName;
PsiType type;
PsiElement parent = expression.getParent();
if (expression instanceof PsiJavaCodeReferenceElement) {
// redirected ctr
@@ -2774,16 +2773,14 @@ public final class HighlightUtil {
return null;
}
PsiElement qualifier = ((PsiJavaCodeReferenceElement)expression).getQualifier();
type = qualifier instanceof PsiExpression ? ((PsiExpression)qualifier).getType() : null;
referencedClass = PsiUtil.resolveClassInType(type);
referencedClass = PsiUtil.resolveClassInType(qualifier instanceof PsiExpression psiExpression ? psiExpression.getType() : null);
boolean isSuperCall = JavaPsiConstructorUtil.isSuperConstructorCall(parent);
if (resolved == null && isSuperCall) {
if (qualifier instanceof PsiReferenceExpression) {
resolved = ((PsiReferenceExpression)qualifier).resolve();
if (qualifier instanceof PsiReferenceExpression referenceExpression) {
resolved = referenceExpression.resolve();
expression = qualifier;
type = ((PsiReferenceExpression)qualifier).getType();
referencedClass = PsiUtil.resolveClassInType(type);
referencedClass = PsiUtil.resolveClassInType(referenceExpression.getType());
}
else if (qualifier == null) {
resolved = PsiTreeUtil.getParentOfType(expression, PsiMethod.class, true, PsiMember.class);
@@ -2841,8 +2838,8 @@ public final class HighlightUtil {
resolvedName = PsiKeyword.THIS;
}
else {
resolvedName = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_CONTAINING_CLASS |
PsiFormatUtilBase.SHOW_NAME, 0);
resolvedName = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY,
PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_NAME, 0);
if (referencedClass == null) referencedClass = method.getContainingClass();
}
}
@@ -2857,17 +2854,14 @@ public final class HighlightUtil {
return null;
}
}
else if (expression instanceof PsiThisExpression thisExpression) {
type = thisExpression.getType();
referencedClass = PsiUtil.resolveClassInType(type);
if (thisExpression.getQualifier() != null) {
resolvedName = referencedClass == null
? null
: PsiFormatUtil.formatClass(referencedClass, PsiFormatUtilBase.SHOW_NAME) + "." + PsiKeyword.THIS;
}
else {
resolvedName = PsiKeyword.THIS;
}
else if (expression instanceof PsiThisExpression || expression instanceof PsiSuperExpression) {
PsiQualifiedExpression qualifiedExpression = (PsiQualifiedExpression)expression;
referencedClass = PsiUtil.resolveClassInType(qualifiedExpression.getType());
String keyword = expression instanceof PsiThisExpression ? PsiKeyword.THIS : PsiKeyword.SUPER;
PsiJavaCodeReferenceElement qualifier = qualifiedExpression.getQualifier();
resolvedName = qualifier != null && qualifier.resolve() instanceof PsiClass aClass
? PsiFormatUtil.formatClass(aClass, PsiFormatUtilBase.SHOW_NAME) + "." + keyword
: keyword;
}
else {
return null;
@@ -2901,9 +2895,7 @@ public final class HighlightUtil {
}
}
if (expression instanceof PsiThisExpression || expression instanceof PsiSuperExpression) {
if (referencedClass != parentClass) return null;
}
if (expression instanceof PsiThisExpression && referencedClass != parentClass) return null;
if (expression instanceof PsiJavaCodeReferenceElement) {
if (!parentClass.equals(PsiTreeUtil.getParentOfType(expression, PsiClass.class)) &&

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.UnhandledExceptions;
@@ -1672,6 +1672,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
@Override
public void visitSuperExpression(@NotNull PsiSuperExpression expr) {
add(HighlightUtil.checkThisOrSuperExpressionInIllegalContext(expr, expr.getQualifier(), myLanguageLevel));
if (!hasErrorResults()) add(HighlightUtil.checkMemberReferencedBeforeConstructorCalled(expr, null, mySurroundingConstructor));
if (!hasErrorResults()) visitExpression(expr);
}
@@ -1723,6 +1724,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
}
@Override
public void visitThrowStatement(@NotNull PsiThrowStatement statement) {
add(HighlightUtil.checkUnhandledExceptions(statement));

View File

@@ -47,7 +47,7 @@ class B extends A {
}
}
B(boolean b, int i) {
<error descr="Cannot reference 'A.i' before superclass constructor is called">super.i</error> = i;
<error descr="Cannot reference 'super' before superclass constructor is called">super</error>.i = i;
<error descr="Cannot reference 'this' before superclass constructor is called">this</error>.i = i;
if (false) <error descr="return not allowed before 'super()' call">return;</error>
super(i);
@@ -68,7 +68,7 @@ class D {
class E extends D {
E() {
<error descr="Cannot reference 'D.i' before superclass constructor is called">super.i</error>++; // Error
<error descr="Cannot reference 'super' before superclass constructor is called">super</error>.i++; // Error
super();
}

View File

@@ -45,4 +45,18 @@ class Ext extends Outer2 {
super();
}
}
}
class C {
C(int i) {
}
int x() {
return 1;
}
}
class D extends C {
D() {
super(<error descr="Cannot reference 'D.super' before superclass constructor is called">D.super</error>.x());
}
}

View File

@@ -27,7 +27,7 @@ class B extends A {
super(<error descr="Cannot call 'A.f()' before superclass constructor is called">f</error>());
}
B(int i, int j, int k) {
super(<error descr="Cannot call 'A.f()' before superclass constructor is called">super.f</error>());
super(<error descr="Cannot reference 'super' before superclass constructor is called">super</error>.f());
}
B(String s, int i) {
@@ -35,7 +35,7 @@ class B extends A {
}
B(int s, int i, char j) {
super(<error descr="Cannot reference 'A.fi' before superclass constructor is called">super.fi</error> );
super(<error descr="Cannot reference 'super' before superclass constructor is called">super</error>.fi );
}
B(double d) {

View File

@@ -58,7 +58,7 @@ class D {
class E extends D {
E() {
<error descr="Cannot reference 'D.i' before superclass constructor is called">super.i</error>++; // Error
<error descr="Cannot reference 'super' before superclass constructor is called">super</error>.i++; // Error
super();
}