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.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE;
|
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.BindingContext.TYPE_PARAMETER;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.classCanHaveAbstractMembers;
|
||||||
|
|
||||||
public class DeclarationsChecker {
|
public class DeclarationsChecker {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -385,7 +386,7 @@ public class DeclarationsChecker {
|
|||||||
ASTNode abstractNode = modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;
|
ASTNode abstractNode = modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;
|
||||||
|
|
||||||
if (abstractNode != null) { //has abstract modifier
|
if (abstractNode != null) { //has abstract modifier
|
||||||
if (!(classDescriptor.getModality() == Modality.ABSTRACT) && classDescriptor.getKind() != ClassKind.ENUM_CLASS) {
|
if (!classCanHaveAbstractMembers(classDescriptor)) {
|
||||||
String name = property.getName();
|
String name = property.getName();
|
||||||
trace.report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(property, name != null ? name : "", classDescriptor));
|
trace.report(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(property, name != null ? name : "", classDescriptor));
|
||||||
return;
|
return;
|
||||||
@@ -489,9 +490,7 @@ public class DeclarationsChecker {
|
|||||||
if (containingDescriptor instanceof ClassDescriptor) {
|
if (containingDescriptor instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
|
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
|
||||||
boolean inTrait = classDescriptor.getKind() == ClassKind.TRAIT;
|
boolean inTrait = classDescriptor.getKind() == ClassKind.TRAIT;
|
||||||
boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS;
|
if (hasAbstractModifier && !classCanHaveAbstractMembers(classDescriptor)) {
|
||||||
boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT;
|
|
||||||
if (hasAbstractModifier && !inAbstractClass && !inEnum) {
|
|
||||||
trace.report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, functionDescriptor.getName().asString(), classDescriptor));
|
trace.report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, functionDescriptor.getName().asString(), classDescriptor));
|
||||||
}
|
}
|
||||||
if (hasAbstractModifier && inTrait) {
|
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.descriptors.CallableMemberDescriptor.Kind.*;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
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;
|
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
|
||||||
|
|
||||||
public class OverrideResolver {
|
public class OverrideResolver {
|
||||||
@@ -372,7 +373,7 @@ public class OverrideResolver {
|
|||||||
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, manyImpl.iterator().next()));
|
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()));
|
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);
|
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")
|
@TestMetadata("enumInheritance.kt")
|
||||||
public void testEnumInheritance() throws Exception {
|
public void testEnumInheritance() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/enumInheritance.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/enumInheritance.kt");
|
||||||
|
|||||||
@@ -401,4 +401,8 @@ public class DescriptorUtils {
|
|||||||
builtIns.getNumber().getDefaultType().equals(type) ||
|
builtIns.getNumber().getDefaultType().equals(type) ||
|
||||||
builtIns.getAnyType().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