highlight enum with abstract methods until enum initializer is added

IDEA-184704
This commit is contained in:
Anna.Kozlova
2018-01-11 19:31:43 +01:00
parent 796d03edf9
commit d74021cd16
9 changed files with 24 additions and 18 deletions
@@ -1082,7 +1082,8 @@ public class GenericsHighlightUtil {
@NotNull HighlightInfoHolder holder,
@NotNull JavaSdkVersion javaSdkVersion) {
PsiClass containingClass = enumConstant.getContainingClass();
if (enumConstant.getInitializingClass() == null) {
LOG.assertTrue(containingClass != null);
if (enumConstant.getInitializingClass() == null && HighlightClassUtil.hasEnumConstantsWithInitializer(containingClass)) {
HighlightInfo highlightInfo = HighlightClassUtil.checkInstantiationOfAbstractClass(containingClass, enumConstant.getNameIdentifier());
if (highlightInfo != null) {
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createImplementMethodsFix(enumConstant));
@@ -113,7 +113,7 @@ public class HighlightClassUtil {
@Nullable
static HighlightInfo checkClassMustBeAbstract(final PsiClass aClass, final TextRange textRange) {
if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) || aClass.getRBrace() == null || aClass.isEnum() && hasEnumConstants(aClass)) {
if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) || aClass.getRBrace() == null || aClass.isEnum() && hasEnumConstantsWithInitializer(aClass)) {
return null;
}
return checkClassWithAbstractMethods(aClass, textRange);
@@ -140,12 +140,17 @@ public class HighlightClassUtil {
return errorResult;
}
private static boolean hasEnumConstants(PsiClass aClass) {
PsiField[] fields = aClass.getFields();
for (PsiField field : fields) {
if (field instanceof PsiEnumConstant) return true;
}
return false;
public static boolean hasEnumConstantsWithInitializer(@NotNull PsiClass aClass) {
return CachedValuesManager.getCachedValue(aClass, () -> {
PsiField[] fields = aClass.getFields();
for (PsiField field : fields) {
if (field instanceof PsiEnumConstant && ((PsiEnumConstant)field).getInitializingClass() != null) {
return new CachedValueProvider.Result<>(true, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
}
}
return new CachedValueProvider.Result<>(false, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
});
}
@Nullable
@@ -130,8 +130,8 @@ interface Barz {
void baz();
}
enum Fooz implements Barz {
<error descr="Class 'Fooz' must implement abstract method 'baz()' in 'Barz'">FOO</error>;
<error descr="Class 'Fooz' must either be declared abstract or implement abstract method 'baz()' in 'Barz'">enum Fooz implements Barz</error> {
FOO;
}
///////////////////////
@@ -124,8 +124,8 @@ interface Barz {
void baz();
}
enum Fooz implements Barz {
<error descr="Class 'Fooz' must implement abstract method 'baz()' in 'Barz'">FOO</error>;
<error descr="Class 'Fooz' must either be declared abstract or implement abstract method 'baz()' in 'Barz'">enum Fooz implements Barz</error> {
FOO;
}
///////////////////////
@@ -4,5 +4,5 @@ interface Card {
}
enum E implements Card {
A<caret>
A{}, B<caret>
}
@@ -4,5 +4,5 @@ interface Card {
}
enum E implements Card {
A<caret>
A{}, B<caret>
}
@@ -5,7 +5,7 @@ enum E {
public int foo() {
return 0;
}
};
}, B {};
public abstract int foo();
}
@@ -1,6 +1,6 @@
// "Implement methods" "true"
enum E {
<caret>A;
<caret>A, B {};
public abstract int foo();
}
@@ -53,6 +53,6 @@ enum E implements I {
interface I2 {
void <warning descr="Abstract method 'method()' is not implemented in every subclass">method</warning>();
}
enum E2 implements I2 {
<error descr="Class 'E2' must implement abstract method 'method()' in 'I2'">A</error>
<error descr="Class 'E2' must either be declared abstract or implement abstract method 'method()' in 'I2'">enum E2 implements I2</error> {
A
}