mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 11:50:54 +07:00
IDEA-242390 - fixed illegal forward reference error inside enums
GitOrigin-RevId: e322e6c1daa46bf5df6314177c8be06ca54377df
This commit is contained in:
committed by
intellij-monorepo-bot
parent
29a49ce121
commit
d9a6306659
@@ -62,6 +62,7 @@ import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -2242,7 +2243,7 @@ public final class HighlightUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* See JLS 8.3.2.3.
|
||||
* See JLS 8.3.3.
|
||||
*/
|
||||
static HighlightInfo checkIllegalForwardReferenceToField(@NotNull PsiReferenceExpression expression, @NotNull PsiField referencedField) {
|
||||
Boolean isIllegalForwardReference = isIllegalForwardReferenceToField(expression, referencedField, false);
|
||||
@@ -2259,8 +2260,13 @@ public final class HighlightUtil {
|
||||
if (expression.getContainingFile() != referencedField.getContainingFile()) return null;
|
||||
TextRange fieldRange = referencedField.getTextRange();
|
||||
if (fieldRange == null || expression.getTextRange().getStartOffset() >= fieldRange.getEndOffset()) return null;
|
||||
// only simple reference can be illegal
|
||||
if (!acceptQualified && expression.getQualifierExpression() != null) return null;
|
||||
if (!acceptQualified) {
|
||||
if (containingClass.isEnum()) {
|
||||
if (isLegalForwardReferenceInEnum(expression, referencedField, containingClass)) return null;
|
||||
}
|
||||
// simple reference can be illegal (JLS 8.3.3)
|
||||
else if (expression.getQualifierExpression() != null) return null;
|
||||
}
|
||||
PsiField initField = findEnclosingFieldInitializer(expression);
|
||||
PsiClassInitializer classInitializer = findParentClassInitializer(expression);
|
||||
if (initField == null && classInitializer == null) return null;
|
||||
@@ -2276,6 +2282,25 @@ public final class HighlightUtil {
|
||||
return initField != referencedField;
|
||||
}
|
||||
|
||||
private static boolean isLegalForwardReferenceInEnum(@NotNull PsiReferenceExpression expression,
|
||||
@NotNull PsiField referencedField,
|
||||
@NotNull PsiClass containingClass) {
|
||||
PsiExpression qualifierExpr = expression.getQualifierExpression();
|
||||
// simple reference can be illegal (JLS 8.3.3)
|
||||
if (qualifierExpr == null) return false;
|
||||
if (Objects.equals(qualifierExpr.getText(), containingClass.getName())) {
|
||||
PsiClassType enumType = TypeUtils.getType(CommonClassNames.JAVA_LANG_ENUM, referencedField);
|
||||
// static fields that are constant variables (4.12.4) are initialized before other static fields (12.4.2),
|
||||
// so a qualified reference to the constant variable is possible.
|
||||
// And we have to ignore a reference to the enum constant which is not a constant variable (4.12.4, 15.29).
|
||||
if (!enumType.isAssignableFrom(referencedField.getType()) && referencedField.computeConstantValue() != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return field that has initializer with this element as subexpression or null if not found
|
||||
*/
|
||||
|
||||
@@ -1,21 +1,58 @@
|
||||
enum Enum242390 {
|
||||
TYPE1(<error descr="Illegal forward reference">Enum242390.TYPE2</error>),
|
||||
TYPE2(TYPE1);
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
static final String C1 = Enum242390.D;
|
||||
static final String C2 = <error descr="Illegal forward reference">D</error>;
|
||||
static final String D = "";
|
||||
|
||||
private final Enum242390 next;
|
||||
Enum242390(Enum242390 next) {
|
||||
this.next = next;
|
||||
enum Enum1 {
|
||||
A(<error descr="Illegal forward reference">B</error>.var),
|
||||
B(A.var),
|
||||
C(<error descr="Illegal forward reference">constant</error>),
|
||||
D(Enum1.constant),
|
||||
E(<error descr="Illegal forward reference">staticVar</error>),
|
||||
F(<error descr="Illegal forward reference">Enum1.staticVar</error>)
|
||||
;
|
||||
Enum1(String str) {
|
||||
}
|
||||
|
||||
static final String constant = "const";
|
||||
static String staticVar = "staticVar";
|
||||
String var = "var";
|
||||
}
|
||||
|
||||
enum Enum242390_2 {
|
||||
A(Enum242390_2.D);
|
||||
enum Enum2 {
|
||||
A(<error descr="Illegal forward reference">B</error>.var),
|
||||
B(A.var),
|
||||
C(<error descr="Illegal forward reference">constant</error>),
|
||||
D(<error descr="Illegal forward reference">Enum2.constant</error>)
|
||||
;
|
||||
Enum2(List<String> str) {
|
||||
}
|
||||
|
||||
Enum242390_2(String s) { }
|
||||
static final List<String> constant = new ArrayList<>();
|
||||
List<String> var = new ArrayList<>();
|
||||
}
|
||||
|
||||
enum Enum3 {
|
||||
A(<error descr="Illegal forward reference">B</error>),
|
||||
B(<error descr="Illegal forward reference">Enum3.C</error>),
|
||||
C(A),
|
||||
D(Enum3.B),
|
||||
E(<error descr="Illegal forward reference">constant</error>),
|
||||
F(<error descr="Illegal forward reference">Enum3.constant</error>),
|
||||
G(A.var),
|
||||
H(<error descr="Illegal forward reference">staticVar</error>),
|
||||
I(<error descr="Illegal forward reference">Enum3.staticVar</error>)
|
||||
;
|
||||
Enum3(Enum3 str) {
|
||||
}
|
||||
static final Enum3 constant = Enum3.A;
|
||||
static Enum3 staticVar = Enum3.B;
|
||||
Enum3 var;
|
||||
}
|
||||
|
||||
enum Enum4 {
|
||||
A
|
||||
;
|
||||
static final String C1 = Enum4.D;
|
||||
static final String C2 = <error descr="Illegal forward reference">D</error>;
|
||||
static final String C3 = A.D;
|
||||
static final String D = "";
|
||||
}
|
||||
@@ -84,6 +84,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testEnumImplementsInterface() { doTest7(false); }
|
||||
public void testEnum() { doTest5(false); }
|
||||
public void testEnum56239() { doTest6(false); }
|
||||
public void testEnum242390() { doTest7(false); }
|
||||
public void testSameErasure() { doTest5(false); }
|
||||
public void testPairsWithSameErasure() { doTest5(false); }
|
||||
public void testMethods() { doTest5(false); }
|
||||
|
||||
Reference in New Issue
Block a user