Do not report ABSTRACT_MEMBER_NOT_IMPLEMENTED on enum classes

Partial fix of KT-3454
This commit is contained in:
Pavel V. Talanov
2014-10-09 21:47:02 +04:00
parent e703de5796
commit 4136c80358
6 changed files with 159 additions and 5 deletions
@@ -35,6 +35,7 @@ import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE;
import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE_PARAMETER;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.classCanHaveAbstractMembers;
public class DeclarationsChecker {
@NotNull
@@ -385,7 +386,7 @@ public class DeclarationsChecker {
ASTNode abstractNode = modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;
if (abstractNode != null) { //has abstract modifier
if (!(classDescriptor.getModality() == Modality.ABSTRACT) && classDescriptor.getKind() != ClassKind.ENUM_CLASS) {
if (!classCanHaveAbstractMembers(classDescriptor)) {
String name = property.getName();
trace.report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(property, name != null ? name : "", classDescriptor));
return;
@@ -489,9 +490,7 @@ public class DeclarationsChecker {
if (containingDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
boolean inTrait = classDescriptor.getKind() == ClassKind.TRAIT;
boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS;
boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT;
if (hasAbstractModifier && !inAbstractClass && !inEnum) {
if (hasAbstractModifier && !classCanHaveAbstractMembers(classDescriptor)) {
trace.report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, functionDescriptor.getName().asString(), classDescriptor));
}
if (hasAbstractModifier && inTrait) {
@@ -49,6 +49,7 @@ import java.util.*;
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.classCanHaveAbstractMembers;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
public class OverrideResolver {
@@ -372,7 +373,7 @@ public class OverrideResolver {
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, manyImpl.iterator().next()));
}
if (classDescriptor.getModality() != Modality.ABSTRACT && !abstractNoImpl.isEmpty()) {
if (!classCanHaveAbstractMembers(classDescriptor) && !abstractNoImpl.isEmpty()) {
trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()));
}
}
@@ -0,0 +1,21 @@
trait T1 {
fun foo()
}
enum class EnumImplementingTraitWithFun: T1 {
E1 {
override fun foo() {}
}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>E2<!>
}
trait T2 {
val bar: Int
}
enum class EnumImplementingTraitWithVal: T2 {
E1 {
override val bar = 1
}
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>E2<!>
}
@@ -0,0 +1,123 @@
package
internal final enum class EnumImplementingTraitWithFun : kotlin.Enum<EnumImplementingTraitWithFun>, T1 {
private constructor EnumImplementingTraitWithFun()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
public enum entry E1 : EnumImplementingTraitWithFun {
private constructor E1()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal open override /*1*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-E1> : EnumImplementingTraitWithFun.E1 {
private constructor <class-object-for-E1>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public enum entry E2 : EnumImplementingTraitWithFun {
private constructor E2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-E2> : EnumImplementingTraitWithFun.E2 {
private constructor <class-object-for-E2>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): EnumImplementingTraitWithFun
public final /*synthesized*/ fun values(): kotlin.Array<EnumImplementingTraitWithFun>
}
internal final enum class EnumImplementingTraitWithVal : kotlin.Enum<EnumImplementingTraitWithVal>, T2 {
private constructor EnumImplementingTraitWithVal()
internal abstract override /*1*/ /*fake_override*/ val bar: kotlin.Int
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
public enum entry E1 : EnumImplementingTraitWithVal {
private constructor E1()
internal open override /*1*/ val bar: kotlin.Int = 1
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-E1> : EnumImplementingTraitWithVal.E1 {
private constructor <class-object-for-E1>()
internal open override /*1*/ /*fake_override*/ val bar: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public enum entry E2 : EnumImplementingTraitWithVal {
private constructor E2()
internal abstract override /*1*/ /*fake_override*/ val bar: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-E2> : EnumImplementingTraitWithVal.E2 {
private constructor <class-object-for-E2>()
internal abstract override /*1*/ /*fake_override*/ val bar: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): EnumImplementingTraitWithVal
public final /*synthesized*/ fun values(): kotlin.Array<EnumImplementingTraitWithVal>
}
internal trait T1 {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal abstract fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal trait T2 {
internal abstract val bar: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -3781,6 +3781,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("enumImplementingTrait.kt")
public void testEnumImplementingTrait() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/enumImplementingTrait.kt");
doTest(fileName);
}
@TestMetadata("enumInheritance.kt")
public void testEnumInheritance() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/enumInheritance.kt");
@@ -401,4 +401,8 @@ public class DescriptorUtils {
builtIns.getNumber().getDefaultType().equals(type) ||
builtIns.getAnyType().equals(type);
}
public static boolean classCanHaveAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
return classDescriptor.getModality() == Modality.ABSTRACT || classDescriptor.getKind() == ClassKind.ENUM_CLASS;
}
}