Prohibit extending kotlin.Enum directly
#KT-7773 Fixed
This commit is contained in:
@@ -49,9 +49,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.PositioningStrategies.*;
|
||||
import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
|
||||
import static org.jetbrains.kotlin.diagnostics.Severity.INFO;
|
||||
import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
|
||||
import static org.jetbrains.kotlin.diagnostics.Severity.*;
|
||||
|
||||
/**
|
||||
* For error messages, see DefaultErrorMessages and IdeErrorMessages.
|
||||
@@ -272,6 +270,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtNullableType> NULLABLE_SUPERTYPE = DiagnosticFactory0.create(ERROR, NULLABLE_TYPE);
|
||||
DiagnosticFactory0<KtTypeReference> DYNAMIC_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<KtTypeReference, ClassDescriptor> CLASS_CANNOT_BE_EXTENDED_DIRECTLY = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtElement> MISSING_CONSTRUCTOR_KEYWORD = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> NON_PRIVATE_CONSTRUCTOR_IN_ENUM = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
+1
@@ -541,6 +541,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(SEALED_SUPERTYPE, "This type is sealed, so it can be inherited by only its own nested classes or objects");
|
||||
MAP.put(SEALED_SUPERTYPE_IN_LOCAL_CLASS, "Local class cannot extend a sealed class");
|
||||
MAP.put(SINGLETON_IN_SUPERTYPE, "Cannot inherit from a singleton");
|
||||
MAP.put(CLASS_CANNOT_BE_EXTENDED_DIRECTLY, "Class {0} cannot be extended directly", NAME);
|
||||
|
||||
MAP.put(CYCLIC_CONSTRUCTOR_DELEGATION_CALL, "There's a cycle in the delegation calls chain");
|
||||
MAP.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects");
|
||||
|
||||
@@ -584,6 +584,9 @@ public class BodyResolver {
|
||||
else if (ModalityKt.isFinalOrEnum(classDescriptor)) {
|
||||
trace.report(FINAL_SUPERTYPE.on(typeReference));
|
||||
}
|
||||
else if (KotlinBuiltIns.isEnum(classDescriptor)) {
|
||||
trace.report(CLASS_CANNOT_BE_EXTENDED_DIRECTLY.on(typeReference, classDescriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class Test1 : <!CLASS_CANNOT_BE_EXTENDED_DIRECTLY!>Enum<Test1><!>("", 0)
|
||||
|
||||
class Outer {
|
||||
class Test2 : <!CLASS_CANNOT_BE_EXTENDED_DIRECTLY!>Enum<Test2><!>("", 0)
|
||||
}
|
||||
|
||||
fun outer() {
|
||||
class Test3 : <!CLASS_CANNOT_BE_EXTENDED_DIRECTLY!>Enum<Test3><!>("", 0)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package
|
||||
|
||||
public fun outer(): kotlin.Unit
|
||||
|
||||
public final class Outer {
|
||||
public constructor Outer()
|
||||
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
|
||||
|
||||
public final class Test2 : kotlin.Enum<Outer.Test2> {
|
||||
public constructor Test2()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Outer.Test2): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Outer.Test2!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
public final class Test1 : kotlin.Enum<Test1> {
|
||||
public constructor Test1()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Test1): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<Test1!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -7363,6 +7363,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extendingEnumDirectly.kt")
|
||||
public void testExtendingEnumDirectly() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionNamedAsEnumEntry.kt")
|
||||
public void testExtensionNamedAsEnumEntry() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/extensionNamedAsEnumEntry.kt");
|
||||
|
||||
@@ -1040,6 +1040,10 @@ public abstract class KotlinBuiltIns {
|
||||
return descriptor.getContainingDeclaration() == getAny();
|
||||
}
|
||||
|
||||
public static boolean isEnum(@NotNull ClassDescriptor descriptor) {
|
||||
return classFqNameEquals(descriptor, FQ_NAMES._enum);
|
||||
}
|
||||
|
||||
public static boolean isCharSequence(@Nullable KotlinType type) {
|
||||
return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.charSequence);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user