From 9f758b4f25f97eddeda5fe0d7e48782b9d4be3c5 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 7 Apr 2020 16:55:56 +0200 Subject: [PATCH] Support toString for AdaptedFunctionReference subclasses Also make it serializable like other lambdas, suspend lambdas and normal callable references. --- .../kotlin/codegen/JvmRuntimeTypes.kt | 2 +- .../ir/FirBlackBoxCodegenTestGenerated.java | 10 ++++++ .../adaptedReferences/toString.kt | 27 ++++++++++++++ .../serializability/adaptedReferences.kt | 36 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 10 ++++++ .../LightAnalysisModeTestGenerated.java | 10 ++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 10 ++++++ .../internal/AdaptedFunctionReference.java | 14 +++++++- .../kotlin-stdlib-runtime-merged.txt | 4 ++- 9 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt create mode 100644 compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt index 914afcb3ff6..b4d75b88905 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmRuntimeTypes.kt @@ -147,7 +147,7 @@ class JvmRuntimeTypes( ?: referencedFunction.dispatchReceiverParameter?.type, anonymousFunctionDescriptor.valueParameters.drop(receivers).map { it.type }, null, - referencedFunction.returnType!!, + anonymousFunctionDescriptor.returnType!!, referencedFunction.isSuspend ) diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 1ac62301884..44b2a508db1 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -2090,6 +2090,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleEmptyVararg.kt"); } + @TestMetadata("toString.kt") + public void testToString() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt"); + } + @TestMetadata("unboundReferences.kt") public void testUnboundReferences() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); @@ -2917,6 +2922,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: "); } + @TestMetadata("adaptedReferences.kt") + public void testAdaptedReferences() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt"); + } + public void testAllFilesPresentInSerializability() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/serializability"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt new file mode 100644 index 00000000000..44c510de3b9 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt @@ -0,0 +1,27 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// WITH_RUNTIME + +import kotlin.test.assertEquals + +class A { + fun foo(s: String = "", vararg xs: Long): CharSequence = "foo" +} + +fun check(expected: String, x: Any) { + assertEquals(expected, x.toString()) +} + +fun coercionToUnit(f: (A, String, LongArray) -> Unit): Any = f +fun varargToElement(f: (A, String, Long, Long) -> CharSequence): Any = f +fun defaultAndVararg(f: (A) -> CharSequence): Any = f +fun allOfTheAbove(f: (A) -> Unit): Any = f + +fun box(): String { + check("Function3", coercionToUnit(A::foo)) + check("Function4", varargToElement(A::foo)) + check("Function1", defaultAndVararg(A::foo)) + check("Function1", allOfTheAbove(A::foo)) + + return "OK" +} diff --git a/compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt b/compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt new file mode 100644 index 00000000000..d0fd6af8708 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt @@ -0,0 +1,36 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// WITH_REFLECT + +import java.io.* +import kotlin.test.assertEquals + +class A { + fun foo(s: String = "", vararg xs: Long): String = "foo" +} + +fun check(x: Any) { + val baos = ByteArrayOutputStream() + val oos = ObjectOutputStream(baos) + oos.writeObject(x) + oos.close() + + val bais = ByteArrayInputStream(baos.toByteArray()) + val ois = ObjectInputStream(bais) + assertEquals(x, ois.readObject()) + ois.close() +} + +fun coercionToUnit(f: (A, String, LongArray) -> Unit): Any = f +fun varargToElement(f: (A, String, Long, Long) -> String): Any = f +fun defaultAndVararg(f: (A) -> String): Any = f +fun allOfTheAbove(f: (A) -> Unit): Any = f + +fun box(): String { + check(coercionToUnit(A::foo)) + check(varargToElement(A::foo)) + check(defaultAndVararg(A::foo)) + check(allOfTheAbove(A::foo)) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 2379a2e9ed3..be754883f1a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -2110,6 +2110,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleEmptyVararg.kt"); } + @TestMetadata("toString.kt") + public void testToString() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt"); + } + @TestMetadata("unboundReferences.kt") public void testUnboundReferences() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); @@ -2937,6 +2942,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); } + @TestMetadata("adaptedReferences.kt") + public void testAdaptedReferences() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt"); + } + public void testAllFilesPresentInSerializability() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/serializability"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 1b6c8affeab..5908d718c02 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2110,6 +2110,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleEmptyVararg.kt"); } + @TestMetadata("toString.kt") + public void testToString() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt"); + } + @TestMetadata("unboundReferences.kt") public void testUnboundReferences() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); @@ -2937,6 +2942,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); } + @TestMetadata("adaptedReferences.kt") + public void testAdaptedReferences() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt"); + } + public void testAllFilesPresentInSerializability() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/serializability"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 54aa1a8bf84..6a98c1c7824 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -2090,6 +2090,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleEmptyVararg.kt"); } + @TestMetadata("toString.kt") + public void testToString() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/toString.kt"); + } + @TestMetadata("unboundReferences.kt") public void testUnboundReferences() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); @@ -2917,6 +2922,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); } + @TestMetadata("adaptedReferences.kt") + public void testAdaptedReferences() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt"); + } + public void testAllFilesPresentInSerializability() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/serializability"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/AdaptedFunctionReference.java b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/AdaptedFunctionReference.java index c0e1302bba8..7f17b6b9446 100644 --- a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/AdaptedFunctionReference.java +++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/AdaptedFunctionReference.java @@ -8,6 +8,8 @@ package kotlin.jvm.internal; import kotlin.SinceKotlin; import kotlin.reflect.KDeclarationContainer; +import java.io.Serializable; + import static kotlin.jvm.internal.CallableReference.NO_RECEIVER; /** @@ -24,7 +26,7 @@ import static kotlin.jvm.internal.CallableReference.NO_RECEIVER; */ @SuppressWarnings({"rawtypes", "WeakerAccess", "unused"}) @SinceKotlin(version = "1.4") -public class AdaptedFunctionReference { +public class AdaptedFunctionReference implements FunctionBase, Serializable { protected final Object receiver; private final Class owner; private final String name; @@ -47,6 +49,11 @@ public class AdaptedFunctionReference { this.flags = flags >> 1; } + @Override + public int getArity() { + return arity; + } + public KDeclarationContainer getOwner() { return owner == null ? null : isTopLevel ? Reflection.getOrCreateKotlinPackage(owner) : Reflection.getOrCreateKotlinClass(owner); @@ -77,4 +84,9 @@ public class AdaptedFunctionReference { result = result * 31 + flags; return result; } + + @Override + public String toString() { + return Reflection.renderLambdaToString(this); + } } diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index b67856151cb..7dbb7ca3886 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -3180,13 +3180,15 @@ public abstract interface class kotlin/jvm/functions/FunctionN : kotlin/Function public abstract fun invoke ([Ljava/lang/Object;)Ljava/lang/Object; } -public class kotlin/jvm/internal/AdaptedFunctionReference { +public class kotlin/jvm/internal/AdaptedFunctionReference : java/io/Serializable, kotlin/jvm/internal/FunctionBase { protected final field receiver Ljava/lang/Object; public fun (ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V public fun (ILjava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V public fun equals (Ljava/lang/Object;)Z + public fun getArity ()I public fun getOwner ()Lkotlin/reflect/KDeclarationContainer; public fun hashCode ()I + public fun toString ()Ljava/lang/String; } public final class kotlin/jvm/internal/ArrayIteratorKt {