From 3424e756adaf56a25acab5cbcedd2f81c53995c2 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Mon, 8 Aug 2022 12:00:09 +0200 Subject: [PATCH] [K/N] Fix for instantiating annotations from already lowered file If annotation class is already lowered, it can have more than one constructor. So we should use primary one, not any one. ^KT-53475 --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++ .../AnnotationImplementationTransformer.kt | 1 + .../annotationInstancesEmptyDefaultLowered.kt | 62 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 6 ++ .../IrCodegenBoxWasmTestGenerated.java | 5 ++ ...tiveAnnotationImplementationTransformer.kt | 2 +- .../NativeCodegenBoxTestGenerated.java | 6 ++ 10 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index f9de5029a88..e9be7fd57c8 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -450,6 +450,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt"); } + @Test + @TestMetadata("annotationInstancesEmptyDefaultLowered.kt") + public void testAnnotationInstancesEmptyDefaultLowered() throws Exception { + runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt"); + } + @Test @TestMetadata("annotationJvmHashCode.kt") public void testAnnotationJvmHashCode() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt index b9fa4b1a412..b197d796ed0 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt @@ -69,6 +69,7 @@ abstract class AnnotationImplementationTransformer(val context: BackendContext, val constructedClass = expression.type.classOrNull?.owner ?: return super.visitConstructorCall(expression) if (!constructedClass.isAnnotationClass) return super.visitConstructorCall(expression) if (constructedClass.typeParameters.isNotEmpty()) return super.visitConstructorCall(expression) // Not supported yet + require(expression.symbol.owner.isPrimary) { "Non-primary constructors of annotations are not supported" } val implClass = implementations.getOrPut(constructedClass) { createAnnotationImplementation(constructedClass) } val ctor = chooseConstructor(implClass, expression) diff --git a/compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt b/compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt new file mode 100644 index 00000000000..629bf941486 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt @@ -0,0 +1,62 @@ +// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: WASM +// DONT_TARGET_EXACT_BACKEND: JS + +// WITH_STDLIB +// !LANGUAGE: +InstantiationOfAnnotationClasses + +/** + * This test checks if annotation instantiation works correctly, when annotation class is lowered before instantiation point. + * So, filename of classes containing annotations should be earlier, than for box function + */ +// FILE: a.kt + +package test + +import kotlin.reflect.KClass + + +enum class E { A, B } + +annotation class A() + +annotation class B(val a: A = A()) + +annotation class C( + val i: Int = 42, + val b: B = B(), + val kClass: KClass<*> = B::class, + val kClassArray: Array> = [E::class, A::class], + val e: E = E.B, + val aS: Array = arrayOf("a", "b"), + val aI: IntArray = intArrayOf(1, 2) +) + +annotation class Partial( + val i: Int = 42, + val s: String = "foo", + val e: E = E.A +) + +// FILE: b.kt + +package test + +import kotlin.test.assertTrue as assert +import kotlin.test.assertEquals + +fun box(): String { + val c = C() + assertEquals(42, c.i) + assertEquals(A(), c.b.a) + assertEquals(B::class, c.kClass) + assertEquals(2, c.kClassArray.size) + assertEquals(E.B, c.e) + assert(arrayOf("a", "b").contentEquals(c.aS)) + assert(intArrayOf(1, 2).contentEquals(c.aI)) + val p = Partial(e = E.B, s = "bar") + assertEquals(42, p.i) + assertEquals("bar", p.s) + assertEquals(E.B, p.e) + return "OK" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 22dbe9c6e29..1509dfc21fc 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -426,6 +426,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt"); } + @Test + @TestMetadata("annotationInstancesEmptyDefaultLowered.kt") + public void testAnnotationInstancesEmptyDefaultLowered() throws Exception { + runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt"); + } + @Test @TestMetadata("annotationToString.kt") public void testAnnotationToString() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 55c6ae04a10..00faa8f1e9b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -450,6 +450,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt"); } + @Test + @TestMetadata("annotationInstancesEmptyDefaultLowered.kt") + public void testAnnotationInstancesEmptyDefaultLowered() throws Exception { + runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt"); + } + @Test @TestMetadata("annotationJvmHashCode.kt") public void testAnnotationJvmHashCode() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index b51c23924e8..88522c0bc89 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -370,6 +370,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt"); } + @TestMetadata("annotationInstancesEmptyDefaultLowered.kt") + public void ignoreAnnotationInstancesEmptyDefaultLowered() throws Exception { + runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt"); + } + @TestMetadata("annotationToString.kt") public void ignoreAnnotationToString() throws Exception { runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 5916acbfc85..5d050df95f6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -108,6 +108,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt"); } + @Test + @TestMetadata("annotationInstancesEmptyDefaultLowered.kt") + public void testAnnotationInstancesEmptyDefaultLowered() throws Exception { + runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt"); + } + @Test @TestMetadata("annotationToString.kt") public void testAnnotationToString() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index fe7482deabd..a1518a3f3b1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -113,6 +113,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt"); } + @TestMetadata("annotationInstancesEmptyDefaultLowered.kt") + public void testAnnotationInstancesEmptyDefaultLowered() throws Exception { + runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt"); + } + @TestMetadata("annotationToString.kt") public void testAnnotationToString() throws Exception { runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt"); diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeAnnotationImplementationTransformer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeAnnotationImplementationTransformer.kt index d2fd334750f..1591e8a4698 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeAnnotationImplementationTransformer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeAnnotationImplementationTransformer.kt @@ -69,7 +69,7 @@ internal class NativeAnnotationImplementationTransformer(context: Context, irFil properties.forEach { property -> generatedConstructor.addValueParameter(property.name.asString(), property.getter!!.returnType) } - createConstructorBody(generatedConstructor, annotationClass.constructors.single()) + createConstructorBody(generatedConstructor, annotationClass.primaryConstructor ?: error("Annotation class does not have primary constructor")) } private fun createConstructorBody(constructor: IrConstructor, delegate: IrConstructor) { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index 5a466909c1c..009cc4c8307 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -120,6 +120,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefault.kt"); } + @Test + @TestMetadata("annotationInstancesEmptyDefaultLowered.kt") + public void testAnnotationInstancesEmptyDefaultLowered() throws Exception { + runTest("compiler/testData/codegen/box/annotations/instances/annotationInstancesEmptyDefaultLowered.kt"); + } + @Test @TestMetadata("annotationToString.kt") public void testAnnotationToString() throws Exception {