Write metadata for suspend function into anonymous coroutine classes
To render nice Kotlin types in toString() of continuation
This commit is contained in:
@@ -250,7 +250,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
|
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
private static FunctionDescriptor createFreeLambdaDescriptor(@NotNull FunctionDescriptor descriptor) {
|
public static FunctionDescriptor createFreeLambdaDescriptor(@NotNull FunctionDescriptor descriptor) {
|
||||||
FunctionDescriptor.CopyBuilder<? extends FunctionDescriptor> builder = descriptor.newCopyBuilder();
|
FunctionDescriptor.CopyBuilder<? extends FunctionDescriptor> builder = descriptor.newCopyBuilder();
|
||||||
List<TypeParameterDescriptor> typeParameters = new ArrayList<>(0);
|
List<TypeParameterDescriptor> typeParameters = new ArrayList<>(0);
|
||||||
builder.setTypeParameters(typeParameters);
|
builder.setTypeParameters(typeParameters);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.*
|
|||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
||||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||||
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
||||||
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
@@ -475,8 +477,10 @@ class CoroutineCodegenForNamedFunction private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun generateKotlinMetadataAnnotation() {
|
override fun generateKotlinMetadataAnnotation() {
|
||||||
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) {
|
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { av ->
|
||||||
// Do not write method metadata for raw coroutine state machines
|
val serializer = DescriptorSerializer.createForLambda(JvmSerializerExtension(v.serializationBindings, state))
|
||||||
|
val functionProto = serializer.functionProto(createFreeLambdaDescriptor(suspendFunctionJvmView)).build()
|
||||||
|
AsmUtil.writeAnnotationData(av, serializer, functionProto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
class A<T : String> {
|
||||||
|
suspend fun foo() {}
|
||||||
|
|
||||||
|
suspend fun bar(): T {
|
||||||
|
foo()
|
||||||
|
return suspendCoroutineOrReturn { x ->
|
||||||
|
x.resume(x.toString() as T)
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
builder {
|
||||||
|
result = A<String>().bar()
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (result == "(kotlin.coroutines.experimental.Continuation<T>) -> kotlin.Any?") "OK" else "Fail: $result"
|
||||||
|
}
|
||||||
+6
@@ -5018,6 +5018,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineToString.kt")
|
||||||
|
public void testCoroutineToString() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/coroutineToString.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("createCoroutineSafe.kt")
|
@TestMetadata("createCoroutineSafe.kt")
|
||||||
public void testCreateCoroutineSafe() throws Exception {
|
public void testCreateCoroutineSafe() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt");
|
||||||
|
|||||||
@@ -5018,6 +5018,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineToString.kt")
|
||||||
|
public void testCoroutineToString() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/coroutineToString.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("createCoroutineSafe.kt")
|
@TestMetadata("createCoroutineSafe.kt")
|
||||||
public void testCreateCoroutineSafe() throws Exception {
|
public void testCreateCoroutineSafe() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt");
|
||||||
|
|||||||
@@ -5018,6 +5018,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutineToString.kt")
|
||||||
|
public void testCoroutineToString() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/coroutineToString.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("createCoroutineSafe.kt")
|
@TestMetadata("createCoroutineSafe.kt")
|
||||||
public void testCreateCoroutineSafe() throws Exception {
|
public void testCreateCoroutineSafe() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/createCoroutineSafe.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user