Support toString for AdaptedFunctionReference subclasses

Also make it serializable like other lambdas, suspend lambdas and normal
callable references.
This commit is contained in:
Alexander Udalov
2020-04-07 16:55:56 +02:00
parent fa879e667f
commit 9f758b4f25
9 changed files with 120 additions and 3 deletions
@@ -147,7 +147,7 @@ class JvmRuntimeTypes(
?: referencedFunction.dispatchReceiverParameter?.type,
anonymousFunctionDescriptor.valueParameters.drop(receivers).map { it.type },
null,
referencedFunction.returnType!!,
anonymousFunctionDescriptor.returnType!!,
referencedFunction.isSuspend
)
@@ -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);
}
@@ -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<A, java.lang.String, long[], kotlin.Unit>", coercionToUnit(A::foo))
check("Function4<A, java.lang.String, java.lang.Long, java.lang.Long, java.lang.CharSequence>", varargToElement(A::foo))
check("Function1<A, java.lang.CharSequence>", defaultAndVararg(A::foo))
check("Function1<A, kotlin.Unit>", allOfTheAbove(A::foo))
return "OK"
}
@@ -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"
}
@@ -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);
}
@@ -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);
}
@@ -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);
}
@@ -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);
}
}
@@ -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 <init> (ILjava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V
public fun <init> (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 {