Do not report ABSTRACT_MEMBER_NOT_IMPLEMENTED on enum classes
Partial fix of KT-3454
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user