From 9648338b19519e6b8b5f4d1a259b7cd11ae61d3a Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 Jul 2015 15:55:01 +0300 Subject: [PATCH] Enum with interface keywords leads to fail in DeclarationChecker --- .../kotlin/resolve/DeclarationsChecker.java | 41 +++++++++++-------- .../tests/enum/interfaceWithEnumKeyword.kt | 8 ++++ .../tests/enum/interfaceWithEnumKeyword.txt | 18 ++++++++ .../testData/psi/EnumWithAnnotationKeyword.kt | 4 ++ .../psi/EnumWithAnnotationKeyword.txt | 28 +++++++++++++ .../testData/psi/InterfaceWithEnumKeyword.kt | 4 ++ .../testData/psi/InterfaceWithEnumKeyword.txt | 17 ++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 6 +++ 8 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.kt create mode 100644 compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java index d79a2ce185b..b89e99b8bb5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java @@ -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 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 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(); + } } + } diff --git a/compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.kt b/compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.kt new file mode 100644 index 00000000000..2bc34f6a387 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.kt @@ -0,0 +1,8 @@ +enum interface Some { + // Enum part + D + + // Interface like part + fun test() + val foo: Int +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.txt b/compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.txt new file mode 100644 index 00000000000..77763a6a677 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/interfaceWithEnumKeyword.txt @@ -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 +} diff --git a/compiler/testData/psi/EnumWithAnnotationKeyword.kt b/compiler/testData/psi/EnumWithAnnotationKeyword.kt index d0db8d9d964..009686dd353 100644 --- a/compiler/testData/psi/EnumWithAnnotationKeyword.kt +++ b/compiler/testData/psi/EnumWithAnnotationKeyword.kt @@ -1,3 +1,7 @@ data annotation enum class E { D +} + +enum annotation E1 { + D } \ No newline at end of file diff --git a/compiler/testData/psi/EnumWithAnnotationKeyword.txt b/compiler/testData/psi/EnumWithAnnotationKeyword.txt index 55d95c601bc..7a124338c7f 100644 --- a/compiler/testData/psi/EnumWithAnnotationKeyword.txt +++ b/compiler/testData/psi/EnumWithAnnotationKeyword.txt @@ -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 + + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('D') + PsiWhiteSpace('\n') PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/InterfaceWithEnumKeyword.kt b/compiler/testData/psi/InterfaceWithEnumKeyword.kt index 1cca818e525..31ee2f6e2bc 100644 --- a/compiler/testData/psi/InterfaceWithEnumKeyword.kt +++ b/compiler/testData/psi/InterfaceWithEnumKeyword.kt @@ -4,4 +4,8 @@ enum interface class E1 { interface enum class E2 { D +} + +enum interface E3 { + D } \ No newline at end of file diff --git a/compiler/testData/psi/InterfaceWithEnumKeyword.txt b/compiler/testData/psi/InterfaceWithEnumKeyword.txt index 68312e43b83..a7700037e02 100644 --- a/compiler/testData/psi/InterfaceWithEnumKeyword.txt +++ b/compiler/testData/psi/InterfaceWithEnumKeyword.txt @@ -54,4 +54,21 @@ JetFile: InterfaceWithEnumKeyword.kt PsiErrorElement:Expecting member declaration 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)('}') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 531d101c161..1563eeaba42 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -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");