Report a separate diagnostic on inheritance from singletons
This commit is contained in:
@@ -139,6 +139,7 @@ public interface Errors {
|
|||||||
|
|
||||||
|
|
||||||
DiagnosticFactory0<JetTypeReference> FINAL_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<JetTypeReference> FINAL_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<JetTypeReference> SINGLETON_IN_SUPERTYPE = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<JetNullableType> NULLABLE_SUPERTYPE = DiagnosticFactory0.create(ERROR, NULLABLE_TYPE);
|
DiagnosticFactory0<JetNullableType> NULLABLE_SUPERTYPE = DiagnosticFactory0.create(ERROR, NULLABLE_TYPE);
|
||||||
|
|
||||||
// Trait-specific
|
// Trait-specific
|
||||||
|
|||||||
+2
-1
@@ -17,8 +17,8 @@
|
|||||||
package org.jetbrains.jet.lang.diagnostics.rendering;
|
package org.jetbrains.jet.lang.diagnostics.rendering;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.Diagnostic;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
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(CONSTRUCTOR_IN_TRAIT, "A trait may not have a constructor");
|
||||||
MAP.put(SUPERTYPE_APPEARS_TWICE, "A supertype appears twice");
|
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(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);
|
MAP.put(ILLEGAL_SELECTOR, "Expression ''{0}'' cannot be a selector (occur after a dot)", TO_STRING);
|
||||||
|
|
||||||
|
|||||||
@@ -256,10 +256,13 @@ public class BodyResolver {
|
|||||||
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
|
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
|
||||||
recordSupertype(typeReference, supertype);
|
recordSupertype(typeReference, supertype);
|
||||||
if (supertype == null) return;
|
if (supertype == null) return;
|
||||||
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
|
ClassDescriptor superClass = TypeUtils.getClassDescriptor(supertype);
|
||||||
if (classDescriptor == null) return;
|
if (superClass == null) return;
|
||||||
if (descriptor.getKind() != ClassKind.TRAIT && !classDescriptor.getConstructors().isEmpty() &&
|
if (superClass.getKind().isSingleton()) {
|
||||||
!ErrorUtils.isError(classDescriptor) && classDescriptor.getKind() != ClassKind.TRAIT) {
|
// 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));
|
trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,7 +325,10 @@ public class BodyResolver {
|
|||||||
trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference));
|
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));
|
trace.report(FINAL_SUPERTYPE.on(typeReference));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
enum class E {
|
||||||
|
ENTRY
|
||||||
|
}
|
||||||
|
|
||||||
|
class A : <!SINGLETON_IN_SUPERTYPE!>E.ENTRY<!>
|
||||||
@@ -14,7 +14,7 @@ package toplevelObjectDeclarations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object B : <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>A<!> {}
|
object B : <!SINGLETON_IN_SUPERTYPE!>A<!> {}
|
||||||
|
|
||||||
val x = A.foo()
|
val x = A.foo()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
package toplevelObjectDeclarations
|
package toplevelObjectDeclarations
|
||||||
|
|
||||||
object CObj {}
|
object CObj {}
|
||||||
|
|
||||||
object DOjb : <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>CObj<!> {}
|
object DOjb : <!SINGLETON_IN_SUPERTYPE!>CObj<!> {}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ package baz
|
|||||||
|
|
||||||
import foo.Bar
|
import foo.Bar
|
||||||
|
|
||||||
class C: <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>Bar<!>
|
class C: <!SINGLETON_IN_SUPERTYPE!>Bar<!>
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
Bar.bar()
|
Bar.bar()
|
||||||
|
|||||||
@@ -2577,6 +2577,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
|||||||
doTest("compiler/testData/diagnostics/tests/enum/importEnumFromJava.kt");
|
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")
|
@TestMetadata("inheritanceFromEnum.kt")
|
||||||
public void testInheritanceFromEnum() throws Exception {
|
public void testInheritanceFromEnum() throws Exception {
|
||||||
doTest("compiler/testData/diagnostics/tests/enum/inheritanceFromEnum.kt");
|
doTest("compiler/testData/diagnostics/tests/enum/inheritanceFromEnum.kt");
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ public class DescriptorUtils {
|
|||||||
return isKindOf(descriptor, ClassKind.ENUM_ENTRY);
|
return isKindOf(descriptor, ClassKind.ENUM_ENTRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSingleton(@NotNull DeclarationDescriptor classifier) {
|
public static boolean isSingleton(@Nullable DeclarationDescriptor classifier) {
|
||||||
if (classifier instanceof ClassDescriptor) {
|
if (classifier instanceof ClassDescriptor) {
|
||||||
ClassDescriptor clazz = (ClassDescriptor) classifier;
|
ClassDescriptor clazz = (ClassDescriptor) classifier;
|
||||||
return clazz.getKind().isSingleton();
|
return clazz.getKind().isSingleton();
|
||||||
|
|||||||
Reference in New Issue
Block a user