diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index e5a35f27d7f..1fb17471519 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -173,6 +173,7 @@ public interface Errors { DiagnosticFactory0 FINAL_SUPERTYPE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 SINGLETON_IN_SUPERTYPE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 NULLABLE_SUPERTYPE = DiagnosticFactory0.create(ERROR, NULLABLE_TYPE); DiagnosticFactory0 DYNAMIC_SUPERTYPE = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 27ea77aa589..e83b45f3ce7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -415,6 +415,7 @@ public class DefaultErrorMessages { MAP.put(TRAIT_WITH_SUPERCLASS, "An interface cannot inherit from a class"); 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(DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES, "Data class inheritance from other classes is deprecated"); 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"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index c92dc77eec3..33b7502212d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -440,6 +440,10 @@ public class BodyResolver { trace.report(TRAIT_WITH_SUPERCLASS.on(typeReference)); addSupertype = false; } + else if (jetClass.hasModifier(JetTokens.DATA_KEYWORD)) { + trace.report(DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES.on(typeReference)); + addSupertype = false; + } if (classAppeared) { trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference)); diff --git a/compiler/testData/diagnostics/tests/dataClasses/dataInheritance.kt b/compiler/testData/diagnostics/tests/dataClasses/dataInheritance.kt new file mode 100644 index 00000000000..86661a48de6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/dataClasses/dataInheritance.kt @@ -0,0 +1,11 @@ +interface Allowed + +open class NotAllowed + +abstract data class Base(val x: Int) + +class Derived: Base(42) + +data class Nasty(x: Int, val y: Int): Base(x) + +data class Complex(val y: Int): Allowed, NotAllowed() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/dataClasses/dataInheritance.txt b/compiler/testData/diagnostics/tests/dataClasses/dataInheritance.txt new file mode 100644 index 00000000000..bc5eb8a0d1d --- /dev/null +++ b/compiler/testData/diagnostics/tests/dataClasses/dataInheritance.txt @@ -0,0 +1,56 @@ +package + +public interface Allowed { + 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 +} + +@kotlin.data() public abstract class Base { + public constructor Base(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public final /*synthesized*/ fun component1(): kotlin.Int + public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int = ...): Base + 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 +} + +@kotlin.data() public final class Complex : Allowed, NotAllowed { + public constructor Complex(/*0*/ y: kotlin.Int) + public final val y: kotlin.Int + public final /*synthesized*/ fun component1(): kotlin.Int + public final /*synthesized*/ fun copy(/*0*/ y: kotlin.Int = ...): Complex + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Derived : Base { + public constructor Derived() + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + public final override /*1*/ /*fake_override*/ fun component1(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun copy(/*0*/ x: kotlin.Int = ...): Base + 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 +} + +@kotlin.data() public final class Nasty : Base { + public constructor Nasty(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int) + public final override /*1*/ /*fake_override*/ val x: kotlin.Int + public final val y: kotlin.Int + public final override /*1*/ /*synthesized*/ fun component1(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun copy(/*0*/ x: kotlin.Int = ...): Base + public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...): Nasty + 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 open class NotAllowed { + public constructor NotAllowed() + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 11bfcdda511..c7ad9833c50 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -3330,6 +3330,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("dataInheritance.kt") + public void testDataInheritance() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dataClasses/dataInheritance.kt"); + doTest(fileName); + } + @TestMetadata("emptyConstructor.kt") public void testEmptyConstructor() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.kt");