Allow data classes to inherit from other classes
#KT-10330 Fixed
This commit is contained in:
@@ -25,7 +25,8 @@ enum class LanguageFeature(val sinceVersion: LanguageVersion) {
|
|||||||
LocalDelegatedProperties(KOTLIN_1_1),
|
LocalDelegatedProperties(KOTLIN_1_1),
|
||||||
TopLevelSealedInheritance(KOTLIN_1_1),
|
TopLevelSealedInheritance(KOTLIN_1_1),
|
||||||
Coroutines(KOTLIN_1_1),
|
Coroutines(KOTLIN_1_1),
|
||||||
AdditionalBuiltInsMembers(KOTLIN_1_1)
|
AdditionalBuiltInsMembers(KOTLIN_1_1),
|
||||||
|
DataClassInheritance(KOTLIN_1_1),
|
||||||
;
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
|
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
import org.jetbrains.kotlin.config.LanguageFeatureSettings;
|
import org.jetbrains.kotlin.config.LanguageFeatureSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||||
@@ -475,7 +476,8 @@ public class BodyResolver {
|
|||||||
trace.report(INTERFACE_WITH_SUPERCLASS.on(typeReference));
|
trace.report(INTERFACE_WITH_SUPERCLASS.on(typeReference));
|
||||||
addSupertype = false;
|
addSupertype = false;
|
||||||
}
|
}
|
||||||
else if (ktClassOrObject.hasModifier(KtTokens.DATA_KEYWORD)) {
|
else if (ktClassOrObject.hasModifier(KtTokens.DATA_KEYWORD) &&
|
||||||
|
!languageFeatureSettings.supportsFeature(LanguageFeature.DataClassInheritance)) {
|
||||||
trace.report(DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES.on(typeReference));
|
trace.report(DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES.on(typeReference));
|
||||||
addSupertype = false;
|
addSupertype = false;
|
||||||
}
|
}
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// TODO: remove the suppression once data classes can have supertypes
|
|
||||||
@file:Suppress("DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES")
|
|
||||||
|
|
||||||
abstract class Base {
|
abstract class Base {
|
||||||
final override fun toString() = "OK"
|
final override fun toString() = "OK"
|
||||||
final override fun hashCode() = 42
|
final override fun hashCode() = 42
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
// See KT-6206 Always generate hashCode() and equals() for data classes even if base classes have non-trivial analogs
|
// See KT-6206 Always generate hashCode() and equals() for data classes even if base classes have non-trivial analogs
|
||||||
// TODO: remove the suppression once data classes can have supertypes
|
|
||||||
@file:Suppress("DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES")
|
|
||||||
|
|
||||||
abstract class Base {
|
abstract class Base {
|
||||||
override fun toString() = "Fail"
|
override fun toString() = "Fail"
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
interface Allowed
|
interface SuperInterface
|
||||||
|
|
||||||
open class NotAllowed
|
open class SuperClass
|
||||||
|
|
||||||
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Base(val x: Int)
|
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Base(val x: Int)
|
||||||
|
|
||||||
class Derived: Base(42)
|
class Derived: Base(42)
|
||||||
|
|
||||||
<!DATA_CLASS_OVERRIDE_CONFLICT!>data<!> class Nasty(val z: Int, val y: Int): <!DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES!>Base<!>(z)
|
<!DATA_CLASS_OVERRIDE_CONFLICT!>data<!> class Nasty(val z: Int, val y: Int): Base(z)
|
||||||
|
|
||||||
data class Complex(val y: Int): Allowed, <!DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES!>NotAllowed<!>()
|
data class Complex(val y: Int): SuperInterface, SuperClass()
|
||||||
|
|
||||||
|
<!DATA_CLASS_OVERRIDE_CONFLICT!>data<!> class SubData(val sss: String) : <!FINAL_SUPERTYPE!>Complex<!>(42)
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
package
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract data class Base {
|
public abstract data class Base {
|
||||||
public constructor Base(/*0*/ x: kotlin.Int)
|
public constructor Base(/*0*/ x: kotlin.Int)
|
||||||
public final val x: kotlin.Int
|
public final val x: kotlin.Int
|
||||||
@@ -16,7 +10,7 @@ public abstract data class Base {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
public final data class Complex : Allowed, NotAllowed {
|
public final data class Complex : SuperInterface, SuperClass {
|
||||||
public constructor Complex(/*0*/ y: kotlin.Int)
|
public constructor Complex(/*0*/ y: kotlin.Int)
|
||||||
public final val y: kotlin.Int
|
public final val y: kotlin.Int
|
||||||
public final operator /*synthesized*/ fun component1(): kotlin.Int
|
public final operator /*synthesized*/ fun component1(): kotlin.Int
|
||||||
@@ -50,8 +44,26 @@ public final data class Nasty : Base {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class NotAllowed {
|
public final data class SubData : Complex {
|
||||||
public constructor NotAllowed()
|
public constructor SubData(/*0*/ sss: kotlin.String)
|
||||||
|
public final val sss: kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ val y: kotlin.Int
|
||||||
|
public final override /*1*/ /*synthesized*/ fun component1(): kotlin.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun copy(/*0*/ y: kotlin.Int = ...): Complex
|
||||||
|
public final /*synthesized*/ fun copy(/*0*/ sss: kotlin.String = ...): SubData
|
||||||
|
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 SuperClass {
|
||||||
|
public constructor SuperClass()
|
||||||
|
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 interface SuperInterface {
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// !LANGUAGE: -DataClassInheritance
|
||||||
|
|
||||||
|
interface Allowed
|
||||||
|
|
||||||
|
open class NotAllowed
|
||||||
|
|
||||||
|
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Base(val x: Int)
|
||||||
|
|
||||||
|
class Derived: Base(42)
|
||||||
|
|
||||||
|
<!DATA_CLASS_OVERRIDE_CONFLICT!>data<!> class Nasty(val z: Int, val y: Int): <!DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES!>Base<!>(z)
|
||||||
|
|
||||||
|
data class Complex(val y: Int): Allowed, <!DATA_CLASS_CANNOT_HAVE_CLASS_SUPERTYPES!>NotAllowed<!>()
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract data class Base {
|
||||||
|
public constructor Base(/*0*/ x: kotlin.Int)
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public final operator /*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
|
||||||
|
}
|
||||||
|
|
||||||
|
public final data class Complex : Allowed, NotAllowed {
|
||||||
|
public constructor Complex(/*0*/ y: kotlin.Int)
|
||||||
|
public final val y: kotlin.Int
|
||||||
|
public final operator /*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
|
||||||
|
}
|
||||||
|
|
||||||
|
public final data class Nasty : Base {
|
||||||
|
public constructor Nasty(/*0*/ z: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||||
|
public final override /*1*/ /*fake_override*/ val x: kotlin.Int
|
||||||
|
public final val y: kotlin.Int
|
||||||
|
public final val z: kotlin.Int
|
||||||
|
public final override /*1*/ /*synthesized*/ fun component1(): kotlin.Int
|
||||||
|
public final operator /*synthesized*/ fun component2(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun copy(/*0*/ x: kotlin.Int = ...): Base
|
||||||
|
public final /*synthesized*/ fun copy(/*0*/ z: 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
|
||||||
|
}
|
||||||
@@ -18597,6 +18597,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/sourceCompatibility"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/sourceCompatibility"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noDataClassInheritance.kt")
|
||||||
|
public void testNoDataClassInheritance() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noDataClassInheritance.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noLocalDelegatedProperty.kt")
|
@TestMetadata("noLocalDelegatedProperty.kt")
|
||||||
public void testNoLocalDelegatedProperty() throws Exception {
|
public void testNoLocalDelegatedProperty() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noLocalDelegatedProperty.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sourceCompatibility/noLocalDelegatedProperty.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user