Enum with interface keywords leads to fail in DeclarationChecker

This commit is contained in:
Nikolay Krasko
2015-07-14 15:55:01 +03:00
parent 71b406d792
commit 9648338b19
8 changed files with 109 additions and 17 deletions
@@ -635,10 +635,6 @@ public class DeclarationsChecker {
}
private void checkEnumEntry(@NotNull JetEnumEntry enumEntry, @NotNull ClassDescriptor classDescriptor) {
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration();
assert DescriptorUtils.isEnumClass(declaration) : "Enum entry should be declared in enum class: " + classDescriptor;
ClassDescriptor enumClass = (ClassDescriptor) declaration;
if (enumEntryUsesDeprecatedSuperConstructor(enumEntry)) {
trace.report(Errors.ENUM_ENTRY_USES_DEPRECATED_SUPER_CONSTRUCTOR.on(enumEntry, classDescriptor));
}
@@ -650,23 +646,34 @@ public class DeclarationsChecker {
trace.report(Errors.ENUM_ENTRY_AFTER_ENUM_MEMBER.on(enumEntry, classDescriptor));
}
List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
ConstructorDescriptor constructor = enumClass.getUnsubstitutedPrimaryConstructor();
if ((constructor == null || !constructor.getValueParameters().isEmpty()) && delegationSpecifiers.isEmpty()) {
trace.report(ENUM_ENTRY_SHOULD_BE_INITIALIZED.on(enumEntry, enumClass));
}
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration();
if (DescriptorUtils.isEnumClass(declaration)) {
ClassDescriptor enumClass = (ClassDescriptor) declaration;
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
if (typeReference != null) {
JetType type = trace.getBindingContext().get(TYPE, typeReference);
if (type != null) {
JetType enumType = enumClass.getDefaultType();
if (!type.getConstructor().equals(enumType.getConstructor())) {
trace.report(ENUM_ENTRY_ILLEGAL_TYPE.on(typeReference, enumClass));
List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
ConstructorDescriptor constructor = enumClass.getUnsubstitutedPrimaryConstructor();
if ((constructor == null || !constructor.getValueParameters().isEmpty()) && delegationSpecifiers.isEmpty()) {
trace.report(ENUM_ENTRY_SHOULD_BE_INITIALIZED.on(enumEntry, enumClass));
}
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
if (typeReference != null) {
JetType type = trace.getBindingContext().get(TYPE, typeReference);
if (type != null) {
JetType enumType = enumClass.getDefaultType();
if (!type.getConstructor().equals(enumType.getConstructor())) {
trace.report(ENUM_ENTRY_ILLEGAL_TYPE.on(typeReference, enumClass));
}
}
}
}
}
else {
assert DescriptorUtils.isTrait(declaration) : "Enum entry should be declared in enum class: " +
classDescriptor + " " +
classDescriptor.getKind();
}
}
}
@@ -0,0 +1,8 @@
<!ILLEGAL_ENUM_ANNOTATION!>enum<!> interface Some {
// Enum part
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED, ENUM_ENTRY_USES_DEPRECATED_OR_NO_DELIMITER!>D<!>
// Interface like part
fun test()
val foo: Int
}
@@ -0,0 +1,18 @@
package
internal interface Some {
public enum entry D : Some {
private constructor D()
internal abstract override /*1*/ /*fake_override*/ val foo: 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
internal abstract override /*1*/ /*fake_override*/ fun test(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal abstract val foo: 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
internal abstract fun test(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
+4
View File
@@ -1,3 +1,7 @@
data annotation enum class E {
D
}
enum annotation E1 {
D
}
+28
View File
@@ -32,4 +32,32 @@ JetFile: EnumWithAnnotationKeyword.kt
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('D')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
FUN
MODIFIER_LIST
PsiElement(enum)('enum')
PsiWhiteSpace(' ')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('annotation')
PsiWhiteSpace(' ')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('E1')
PsiErrorElement:Expecting a top level declaration
<empty list>
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('D')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+4
View File
@@ -4,4 +4,8 @@ enum interface class E1 {
interface enum class E2 {
D
}
enum interface E3 {
D
}
+17
View File
@@ -54,4 +54,21 @@ JetFile: InterfaceWithEnumKeyword.kt
PsiErrorElement:Expecting member declaration
<empty list>
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
CLASS
MODIFIER_LIST
PsiElement(enum)('enum')
PsiWhiteSpace(' ')
PsiElement(interface)('interface')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('E3')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('D')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -5193,6 +5193,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("interfaceWithEnumKeyword.kt")
public void testInterfaceWithEnumKeyword() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.kt");
doTest(fileName);
}
@TestMetadata("isEnumEntry.kt")
public void testIsEnumEntry() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/isEnumEntry.kt");