IDEA-200139 Smart completion for super constructor call suggests base field

This commit is contained in:
peter
2018-10-11 09:12:18 +02:00
parent b972110432
commit 3c99a1b1e9
3 changed files with 37 additions and 6 deletions
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
import com.intellij.psi.*;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.JavaPsiConstructorUtil;
@@ -94,15 +95,14 @@ class CheckInitialized implements ElementFilter {
final Set<PsiField> fields = new HashSet<>();
final PsiClass containingClass = method.getContainingClass();
assert containingClass != null;
for (PsiField field : containingClass.getFields()) {
if (!field.hasModifierProperty(PsiModifier.STATIC) &&
!isInitializedBeforeConstructor(field, containingClass) &&
!isInitializedImplicitly(field)) {
if (!allowNonFinalFields || field.hasModifierProperty(PsiModifier.FINAL)) {
InheritanceUtil.processSupers(containingClass, true, eachClass -> {
for (PsiField field : eachClass.getFields()) {
if (!seemsInitialized(allowNonFinalFields, containingClass, field)) {
fields.add(field);
}
}
}
return true;
});
method.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
@@ -136,6 +136,17 @@ class CheckInitialized implements ElementFilter {
return fields;
}
private static boolean seemsInitialized(boolean allowNonFinalFields, PsiClass placeClass, PsiField field) {
if (field.hasModifierProperty(PsiModifier.STATIC)) return true;
if (field.getContainingClass() == placeClass) {
if (isInitializedBeforeConstructor(field, placeClass) ||
isInitializedImplicitly(field)) {
return true;
}
}
return allowNonFinalFields && !field.hasModifierProperty(PsiModifier.FINAL);
}
private static boolean isInitializedBeforeConstructor(PsiField field, PsiClass containingClass) {
if (field.getInitializer() != null) return true;
@@ -0,0 +1,14 @@
abstract class SuggestBase {
final int baseField;
static final int baseConstant;
SuggestBase(int baseField) {
this.baseField = baseField;
}
}
class SuggestChild extends SuggestBase {
SuggestChild(int input) {
super(<caret>)
}
}
@@ -466,6 +466,12 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
configureByTestName();
assertStringItems("aac", "aab", "hashCode");
}
public void testNoUninitializedSuperFieldsInConstructor() {
configureByTestName();
assertStringItems("input", "baseConstant");
}
public void testFieldsSetInAnotherConstructor() { doTest(); }
public void testFieldsSetAbove() { doTest(); }