From 310a70bf8413f27944b4c744c846cc412f8b5685 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 2 Dec 2013 17:13:58 +0400 Subject: [PATCH] Report a separate diagnostic on inheritance from singletons --- .../jetbrains/jet/lang/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 3 ++- .../jetbrains/jet/lang/resolve/BodyResolver.java | 16 +++++++++++----- .../tests/enum/inheritFromEnumEntry.kt | 5 +++++ .../diagnostics/tests/objects/Objects.kt | 2 +- .../tests/objects/ObjectsInheritance.kt | 3 +-- .../scopes/ImportObjectAndUseAsSupertype.kt | 2 +- .../checkers/JetDiagnosticsTestGenerated.java | 5 +++++ .../jet/lang/resolve/DescriptorUtils.java | 2 +- 9 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/enum/inheritFromEnumEntry.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index c0229b896e0..066aa46a1a6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -139,6 +139,7 @@ public interface Errors { DiagnosticFactory0 FINAL_SUPERTYPE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 SINGLETON_IN_SUPERTYPE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 NULLABLE_SUPERTYPE = DiagnosticFactory0.create(ERROR, NULLABLE_TYPE); // Trait-specific diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index c5db18ec9b3..8142722be04 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -17,8 +17,8 @@ package org.jetbrains.jet.lang.diagnostics.rendering; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory; import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; @@ -318,6 +318,7 @@ public class DefaultErrorMessages { MAP.put(CONSTRUCTOR_IN_TRAIT, "A trait may not have a constructor"); MAP.put(SUPERTYPE_APPEARS_TWICE, "A supertype appears twice"); MAP.put(FINAL_SUPERTYPE, "This type is final, so it cannot be inherited from"); + MAP.put(SINGLETON_IN_SUPERTYPE, "Cannot inherit from a singleton"); MAP.put(ILLEGAL_SELECTOR, "Expression ''{0}'' cannot be a selector (occur after a dot)", TO_STRING); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index fb011a7d072..14507de3660 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -256,10 +256,13 @@ public class BodyResolver { JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference); recordSupertype(typeReference, supertype); if (supertype == null) return; - ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); - if (classDescriptor == null) return; - if (descriptor.getKind() != ClassKind.TRAIT && !classDescriptor.getConstructors().isEmpty() && - !ErrorUtils.isError(classDescriptor) && classDescriptor.getKind() != ClassKind.TRAIT) { + ClassDescriptor superClass = TypeUtils.getClassDescriptor(supertype); + if (superClass == null) return; + if (superClass.getKind().isSingleton()) { + // A "singleton in supertype" diagnostic will be reported later + return; + } + if (descriptor.getKind() != ClassKind.TRAIT && !superClass.getConstructors().isEmpty() && !ErrorUtils.isError(superClass)) { trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier)); } } @@ -322,7 +325,10 @@ public class BodyResolver { trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference)); } - if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) { + if (DescriptorUtils.isSingleton(classDescriptor)) { + trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference)); + } + else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) { trace.report(FINAL_SUPERTYPE.on(typeReference)); } } diff --git a/compiler/testData/diagnostics/tests/enum/inheritFromEnumEntry.kt b/compiler/testData/diagnostics/tests/enum/inheritFromEnumEntry.kt new file mode 100644 index 00000000000..0fc9968acf7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/inheritFromEnumEntry.kt @@ -0,0 +1,5 @@ +enum class E { + ENTRY +} + +class A : E.ENTRY diff --git a/compiler/testData/diagnostics/tests/objects/Objects.kt b/compiler/testData/diagnostics/tests/objects/Objects.kt index f9f8fc7a515..4d78d578240 100644 --- a/compiler/testData/diagnostics/tests/objects/Objects.kt +++ b/compiler/testData/diagnostics/tests/objects/Objects.kt @@ -14,7 +14,7 @@ package toplevelObjectDeclarations } } - object B : A {} + object B : A {} val x = A.foo() diff --git a/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt b/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt index 441221407cc..a5511222d81 100644 --- a/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt +++ b/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt @@ -1,6 +1,5 @@ - package toplevelObjectDeclarations object CObj {} -object DOjb : CObj {} \ No newline at end of file +object DOjb : CObj {} diff --git a/compiler/testData/diagnostics/tests/scopes/ImportObjectAndUseAsSupertype.kt b/compiler/testData/diagnostics/tests/scopes/ImportObjectAndUseAsSupertype.kt index 856acab79a9..19c066a5156 100644 --- a/compiler/testData/diagnostics/tests/scopes/ImportObjectAndUseAsSupertype.kt +++ b/compiler/testData/diagnostics/tests/scopes/ImportObjectAndUseAsSupertype.kt @@ -12,7 +12,7 @@ package baz import foo.Bar -class C: Bar +class C: Bar fun test() { Bar.bar() diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index e74c72f60cb..ded8000aa22 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2577,6 +2577,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/enum/importEnumFromJava.kt"); } + @TestMetadata("inheritFromEnumEntry.kt") + public void testInheritFromEnumEntry() throws Exception { + doTest("compiler/testData/diagnostics/tests/enum/inheritFromEnumEntry.kt"); + } + @TestMetadata("inheritanceFromEnum.kt") public void testInheritanceFromEnum() throws Exception { doTest("compiler/testData/diagnostics/tests/enum/inheritanceFromEnum.kt"); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index c7384e0ae99..e58f929d9b7 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -243,7 +243,7 @@ public class DescriptorUtils { return isKindOf(descriptor, ClassKind.ENUM_ENTRY); } - public static boolean isSingleton(@NotNull DeclarationDescriptor classifier) { + public static boolean isSingleton(@Nullable DeclarationDescriptor classifier) { if (classifier instanceof ClassDescriptor) { ClassDescriptor clazz = (ClassDescriptor) classifier; return clazz.getKind().isSingleton();