From 7deaf8cc4113f9468c349873461dd224b461a556 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 13 Dec 2016 20:47:45 +0300 Subject: [PATCH] Allow impl class to be data class, allow impl constructor properties --- .../rendering/DefaultErrorMessages.java | 2 +- .../kotlin/diagnostics/rendering/Renderers.kt | 2 +- .../kotlin/resolve/DescriptorResolver.java | 2 +- .../checkers/HeaderImplDeclarationChecker.kt | 4 -- .../headerClass/implDataClass.kt | 32 ++++++++++ .../headerClass/implDataClass.txt | 63 +++++++++++++++++++ .../incompatibleClasses/common.kt | 3 - .../multiplatform/incompatibleClasses/jvm.kt | 3 - .../incompatibleClasses/output.txt | 21 ++----- .../checkers/DiagnosticsTestGenerated.java | 6 ++ 10 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.txt 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 c4aa6b86074..835cbc5577b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -272,7 +272,7 @@ public class DefaultErrorMessages { MAP.put(IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE, "Right-hand side of 'impl' type alias cannot contain use-site variance or star projections"); MAP.put(IMPL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION, "Type arguments in the right-hand side of 'impl' type alias should be its type parameters in the same order, e.g. 'impl typealias Foo = Bar'"); - MAP.put(HEADER_WITHOUT_IMPLEMENTATION, "Header declaration ''{0}'' has no implementation in module {1}{2}", NAME, + MAP.put(HEADER_WITHOUT_IMPLEMENTATION, "Header declaration ''{0}'' has no implementation in module{1}{2}", NAME, PLATFORM, PlatformIncompatibilityDiagnosticRenderer.INSTANCE); MAP.put(IMPLEMENTATION_WITHOUT_HEADER, "Modifier 'impl' is only applicable to members that are initially declared in platform-independent code"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt index cb5a86fc909..3fe5fcca6a7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt @@ -76,7 +76,7 @@ object Renderers { @JvmField val NAME = Renderer { it.name.asString() } @JvmField val PLATFORM = Renderer { - if (it.platformKind == PlatformKind.DEFAULT) "" else "for " + it.platformKind.name + if (it.platformKind == PlatformKind.DEFAULT) "" else " for " + it.platformKind.name } @JvmField val VISIBILITY = Renderer { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index 7b2852f2dca..f449152be7d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -1141,7 +1141,7 @@ public class DescriptorResolver { /* lateInit = */ false, /* isConst = */ false, /* isHeader = */ false, - /* isImpl = */ false, + /* isImpl = */ modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD), /* isExternal = */ false ); propertyWrapper.setDescriptor(propertyDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt index 12e6999dd23..5645a53690b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/HeaderImplDeclarationChecker.kt @@ -188,8 +188,6 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null) object ClassKind : Incompatible("class kinds are different (class, interface, object, enum, annotation)") - object ClassModifiers : Incompatible("modifiers are different (data)") - object Supertypes : Incompatible("some supertypes are missing in the implementation") class ClassScopes( @@ -325,8 +323,6 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null) areCompatibleTypeParameters(aTypeParams, bTypeParams, substitutor).let { if (it != Compatible) return it } - if (!equalBy(a, b) { it.isData }) return Incompatible.ClassModifiers - if (!b.typeConstructor.supertypes.containsAll(a.typeConstructor.supertypes.map(substitutor))) return Incompatible.Supertypes areCompatibleClassScopes(a, b, checkImpl && !implTypealias, substitutor).let { if (it != Compatible) return it } diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.kt new file mode 100644 index 00000000000..c69b286c3dc --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.kt @@ -0,0 +1,32 @@ +// !LANGUAGE: +MultiPlatformProjects +// MODULE: m1-common +// FILE: common.kt + +header class Foo(x: Int, y: String) { + val x: Int + val y: String +} + +header class Bar(z: Double) + +header class Baz(w: List) { + val w: List + + operator fun component1(): List + + // Disabled because default arguments are not allowed + // fun copy(w: List = ...): Baz + + override fun equals(other: Any?): Boolean + override fun hashCode(): Int + override fun toString(): String +} + +// MODULE: m2-jvm(m1-common) +// FILE: jvm.kt + +impl data class Foo(impl val x: Int, impl val y: String) + +impl data class Bar(val z: Double) + +impl data class Baz(impl val w: List) diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.txt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.txt new file mode 100644 index 00000000000..132215c41b7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.txt @@ -0,0 +1,63 @@ +// -- Module: -- +package + +public final header class Bar { + public constructor Bar(/*0*/ z: kotlin.Double) + 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 header class Baz { + public constructor Baz(/*0*/ w: kotlin.collections.List) + public final val w: kotlin.collections.List + public final operator header fun component1(): kotlin.collections.List + public open header override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open header override /*1*/ fun hashCode(): kotlin.Int + public open header override /*1*/ fun toString(): kotlin.String +} + +public final header class Foo { + public constructor Foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String) + public final val x: kotlin.Int + public final val y: kotlin.String + 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 +} + + +// -- Module: -- +package + +public final impl data class Bar { + public constructor Bar(/*0*/ z: kotlin.Double) + public final val z: kotlin.Double + public final operator /*synthesized*/ fun component1(): kotlin.Double + public final /*synthesized*/ fun copy(/*0*/ z: kotlin.Double = ...): Bar + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final impl data class Baz { + public constructor Baz(/*0*/ w: kotlin.collections.List) + public final val w: kotlin.collections.List + public final operator /*synthesized*/ fun component1(): kotlin.collections.List + public final /*synthesized*/ fun copy(/*0*/ w: kotlin.collections.List = ...): Baz + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final impl data class Foo { + public constructor Foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String) + public final val x: kotlin.Int + public final val y: kotlin.String + public final operator /*synthesized*/ fun component1(): kotlin.Int + public final operator /*synthesized*/ fun component2(): kotlin.String + public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ...): Foo + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/multiplatform/incompatibleClasses/common.kt b/compiler/testData/multiplatform/incompatibleClasses/common.kt index 5e33fa0c7b4..8bf34161e26 100644 --- a/compiler/testData/multiplatform/incompatibleClasses/common.kt +++ b/compiler/testData/multiplatform/incompatibleClasses/common.kt @@ -12,9 +12,6 @@ open header class OpenClass abstract header class AbstractClass final header class FinalClass -// header data class DataClass(val x: Int) -header class NonDataClass(x: Int) - header class C1 header class C2 header class C3 diff --git a/compiler/testData/multiplatform/incompatibleClasses/jvm.kt b/compiler/testData/multiplatform/incompatibleClasses/jvm.kt index ca3f37c68ea..1d4e298a450 100644 --- a/compiler/testData/multiplatform/incompatibleClasses/jvm.kt +++ b/compiler/testData/multiplatform/incompatibleClasses/jvm.kt @@ -12,9 +12,6 @@ final impl class OpenClass open impl class AbstractClass abstract impl class FinalClass -// impl class DataClass(val x: Int) -impl data class NonDataClass(val x: Int) - impl class C1 impl class C2 impl class C3 diff --git a/compiler/testData/multiplatform/incompatibleClasses/output.txt b/compiler/testData/multiplatform/incompatibleClasses/output.txt index cb6d02a7ec5..8c773b84aba 100644 --- a/compiler/testData/multiplatform/incompatibleClasses/output.txt +++ b/compiler/testData/multiplatform/incompatibleClasses/output.txt @@ -71,25 +71,19 @@ The following declaration is incompatible because modality is different: final header class FinalClass ^ -compiler/testData/multiplatform/incompatibleClasses/common.kt:16:14: error: header declaration 'NonDataClass' has no implementation in module -The following declaration is incompatible because modifiers are different (data): - public final impl data class NonDataClass - -header class NonDataClass(x: Int) - ^ -compiler/testData/multiplatform/incompatibleClasses/common.kt:18:14: error: header declaration 'C1' has no implementation in module +compiler/testData/multiplatform/incompatibleClasses/common.kt:15:14: error: header declaration 'C1' has no implementation in module The following declaration is incompatible because number of type parameters is different: public final impl class C1 header class C1 ^ -compiler/testData/multiplatform/incompatibleClasses/common.kt:19:14: error: header declaration 'C2' has no implementation in module +compiler/testData/multiplatform/incompatibleClasses/common.kt:16:14: error: header declaration 'C2' has no implementation in module The following declaration is incompatible because declaration-site variances of type parameters are different: public final impl class C2 header class C2 ^ -compiler/testData/multiplatform/incompatibleClasses/common.kt:25:23: error: header declaration 'ExtendsNumber' has no implementation in module +compiler/testData/multiplatform/incompatibleClasses/common.kt:22:23: error: header declaration 'ExtendsNumber' has no implementation in module The following declaration is incompatible because some supertypes are missing in the implementation: public abstract impl class ExtendsNumber @@ -128,16 +122,13 @@ open impl class AbstractClass compiler/testData/multiplatform/incompatibleClasses/jvm.kt:13:10: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code abstract impl class FinalClass ^ -compiler/testData/multiplatform/incompatibleClasses/jvm.kt:16:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code -impl data class NonDataClass(val x: Int) -^ -compiler/testData/multiplatform/incompatibleClasses/jvm.kt:18:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:15:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code impl class C1 ^ -compiler/testData/multiplatform/incompatibleClasses/jvm.kt:19:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:16:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code impl class C2 ^ -compiler/testData/multiplatform/incompatibleClasses/jvm.kt:25:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:22:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code impl abstract class ExtendsNumber : Any() ^ diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index adc3f07204a..9e85496a8ef 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -13080,6 +13080,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("implDataClass.kt") + public void testImplDataClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/implDataClass.kt"); + doTest(fileName); + } + @TestMetadata("simpleHeaderClass.kt") public void testSimpleHeaderClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/multiplatform/headerClass/simpleHeaderClass.kt");