From 0c586ef5c1afd06ec359d7965c158cb80a40e182 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Mon, 3 Jun 2019 15:12:00 +0200 Subject: [PATCH] JVM_IR: Maintain annotations in SAM conversion. Copy method and parameter annotations to the generated SAM implementation method. --- .../jvm/lower/SingleAbstractMethodLowering.kt | 13 +++-- .../annotatedLambda/samFunExpression.kt | 1 - .../annotatedLambda/samFunReference.kt | 54 +++++++++++++++++++ .../annotations/annotatedLambda/samLambda.kt | 1 - .../codegen/BlackBoxCodegenTestGenerated.java | 5 ++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 ++ 7 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt index 247b353c396..a8cba1ecfe9 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt @@ -19,9 +19,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.* -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrField -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.types.IrType @@ -204,6 +202,15 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : ClassLow private fun IrBlockBuilder.createFunctionProxyInstance(superType: IrType, reference: IrFunctionReference): IrExpression { val implementation = createFunctionProxy(superType, reference) + if (reference.origin == IrStatementOrigin.ANONYMOUS_FUNCTION || reference.origin == IrStatementOrigin.LAMBDA) { + val target = reference.symbol.owner + implementation.functions.single().apply { + annotations.addAll(target.annotations) + valueParameters.forEachIndexed { i, p -> + p.annotations.addAll(target.valueParameters[i].annotations) + } + } + } localImplementations += implementation return irCall(implementation.constructors.single()).apply { reference.arguments.filterNotNull().forEachIndexed(::putValueArgument) diff --git a/compiler/testData/codegen/box/annotations/annotatedLambda/samFunExpression.kt b/compiler/testData/codegen/box/annotations/annotatedLambda/samFunExpression.kt index 9750d7d8971..c34c8dd2ca3 100644 --- a/compiler/testData/codegen/box/annotations/annotatedLambda/samFunExpression.kt +++ b/compiler/testData/codegen/box/annotations/annotatedLambda/samFunExpression.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt b/compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt new file mode 100644 index 00000000000..ed9a9b9b7c4 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt @@ -0,0 +1,54 @@ +// TARGET_BACKEND: JVM + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + public static Class apply(Runnable x) { + return x.getClass(); + } + + public static interface ABC { + void apply(String x1, String x2); + } + + public static Class applyABC(ABC x) { + return x.getClass(); + } +} + +// FILE: test.kt + +import java.lang.reflect.Method +import kotlin.test.assertEquals + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val x: String) + +fun testMethodNoAnnotations(method: Method, name: String) { + assertEquals(0, method.getDeclaredAnnotations().size, "No method annotations expected `$name`") + for ((index, annotations) in method.getParameterAnnotations().withIndex()) { + assertEquals(0, annotations.size, "No parameter $index annotations expected `$name`") + } +} + +fun testClass(clazz: Class<*>, name: String) { + val invokes = clazz.getDeclaredMethods().single() { !it.isBridge() } + testMethodNoAnnotations(invokes, name) +} + +@Ann("OK") +fun annotatedABC(@Ann("OK0") x: String, @Ann("OK1") y: String) {} + +@Ann("OK") +fun annotatedRunnable() {} + +fun box(): String { + testClass(Test.applyABC(::annotatedABC), "1") + testClass(Test.apply(::annotatedRunnable), "2") + val abcReference = ::annotatedABC + testClass(Test.applyABC(abcReference), "3") + val runnableReference = ::annotatedRunnable + testClass(Test.apply(runnableReference), "4") + return "OK" +} diff --git a/compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt b/compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt index 33ec2ab1fd8..7d5fecf3740 100644 --- a/compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt +++ b/compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 5273d8a0796..9647bf73a32 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -213,6 +213,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samFunExpression.kt"); } + @TestMetadata("samFunReference.kt") + public void testSamFunReference() throws Exception { + runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt"); + } + @TestMetadata("samLambda.kt") public void testSamLambda() throws Exception { runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index fd0a85b4531..432d2e00f4c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -213,6 +213,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samFunExpression.kt"); } + @TestMetadata("samFunReference.kt") + public void testSamFunReference() throws Exception { + runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt"); + } + @TestMetadata("samLambda.kt") public void testSamLambda() throws Exception { runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 8ceda1e74e6..f72f1e66592 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -213,6 +213,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samFunExpression.kt"); } + @TestMetadata("samFunReference.kt") + public void testSamFunReference() throws Exception { + runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt"); + } + @TestMetadata("samLambda.kt") public void testSamLambda() throws Exception { runTest("compiler/testData/codegen/box/annotations/annotatedLambda/samLambda.kt");