definitely initialized should check order (IDEA-181149)

missed for field initialization; similar to class initializers
This commit is contained in:
Anna.Kozlova
2017-10-25 19:04:38 +02:00
parent 0a88a925c9
commit c415cde83e
3 changed files with 32 additions and 5 deletions

View File

@@ -22,6 +22,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -126,7 +127,7 @@ public class HighlightControlFlowUtil {
final PsiClass aClass = field.getContainingClass();
if (aClass != null) {
// field might be assigned in the other field initializers
if (isFieldInitializedInOtherFieldInitializer(aClass, field, isFieldStatic)) return true;
if (isFieldInitializedInOtherFieldInitializer(aClass, field, isFieldStatic, Condition.TRUE)) return true;
}
final PsiClassInitializer[] initializers;
if (aClass != null) {
@@ -172,12 +173,14 @@ public class HighlightControlFlowUtil {
private static boolean isFieldInitializedInOtherFieldInitializer(@NotNull PsiClass aClass,
@NotNull PsiField field,
final boolean fieldStatic) {
final boolean fieldStatic,
final Condition<PsiField> condition) {
PsiField[] fields = aClass.getFields();
for (PsiField psiField : fields) {
if (psiField != field
&& psiField.hasModifierProperty(PsiModifier.STATIC) == fieldStatic
&& variableDefinitelyAssignedIn(field, psiField)) {
&& variableDefinitelyAssignedIn(field, psiField)
&& condition.value(psiField)) {
return true;
}
}
@@ -322,6 +325,8 @@ public class HighlightControlFlowUtil {
if (!containingFile.getManager().areElementsEquivalent(classInitializer.getContainingClass(), ((PsiField)variable).getContainingClass())) return null;
block = classInitializer.getBody();
aClass = classInitializer.getContainingClass();
if (aClass == null || isFieldInitializedInOtherFieldInitializer(aClass, (PsiField)variable, variable.hasModifierProperty(PsiModifier.STATIC), field -> startOffset > field.getTextOffset())) return null;
}
else {
// field reference outside code block
@@ -331,7 +336,7 @@ public class HighlightControlFlowUtil {
aClass = field.getContainingClass();
final PsiField anotherField = PsiTreeUtil.getTopmostParentOfType(expression, PsiField.class);
if (aClass == null ||
isFieldInitializedInOtherFieldInitializer(aClass, field, field.hasModifierProperty(PsiModifier.STATIC))) {
isFieldInitializedInOtherFieldInitializer(aClass, field, field.hasModifierProperty(PsiModifier.STATIC), psiField -> startOffset > psiField.getTextOffset())) {
return null;
}
if (anotherField != null && !anotherField.hasModifierProperty(PsiModifier.STATIC) && field.hasModifierProperty(PsiModifier.STATIC) &&

View File

@@ -0,0 +1,21 @@
class TestStaticBlockFinalInitializer {
public static final String BAR;
public static final String XYZ_BEFORE;
public static final String XYZ_BEFORE_1 = <error descr="Variable 'BAR' might not have been initialized">BAR</error>;
static {
XYZ_BEFORE = <error descr="Variable 'BAR' might not have been initialized">BAR</error>;
}
public static final String BAZ = (BAR = "Test");
public static final String XYZ_AFTER;
public static final String XYZ_AFTER_1 = BAR;
static {
XYZ_AFTER = BAR;
}
}

View File

@@ -31,6 +31,7 @@ import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationLocalInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageAnnotators;
@@ -61,7 +62,6 @@ import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.VfsTestUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.ui.UIUtil;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -134,6 +134,7 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testLocalVariableInitialization() { doTest(false); }
public void testVarDoubleInitialization() { doTest(false); }
public void testFieldDoubleInitialization() { doTest(false); }
public void testFinalFieldInitialization() { doTest(false); }
public void testAssignToFinal() { doTest(false); }
public void testUnhandledExceptionsInSuperclass() { doTest(false); }
public void testNoUnhandledExceptionsMultipleInheritance() { doTest(false); }