diff --git a/compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt b/compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt new file mode 100644 index 00000000000..a691c69925c --- /dev/null +++ b/compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt @@ -0,0 +1,16 @@ +// IGNORE_BACKEND: JS, NATIVE, JS_IR, JVM_IR +// WITH_REFLECT + +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +interface A { + suspend fun f(param: String): MutableList +} + +fun box(): String { + val type = A::class.members.single { it.name == "f" }.returnType.javaType + assertEquals("java.util.List", type.toString()) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 301b6579e94..8c92662773c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -18771,6 +18771,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/reflection/mapping/types/supertypes.kt"); } + @TestMetadata("suspendFun.kt") + public void testSuspendFun() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt"); + } + @TestMetadata("topLevelFunctions.kt") public void testTopLevelFunctions() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/types/topLevelFunctions.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index aec53296cd1..91a21462a41 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -18771,6 +18771,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/reflection/mapping/types/supertypes.kt"); } + @TestMetadata("suspendFun.kt") + public void testSuspendFun() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt"); + } + @TestMetadata("topLevelFunctions.kt") public void testTopLevelFunctions() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/types/topLevelFunctions.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 80d3acf8ffd..3d16cdd15b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -18771,6 +18771,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/reflection/mapping/types/supertypes.kt"); } + @TestMetadata("suspendFun.kt") + public void testSuspendFun() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt"); + } + @TestMetadata("topLevelFunctions.kt") public void testTopLevelFunctions() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/types/topLevelFunctions.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt index 6549f5f735f..3ffb1b3ea0b 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt @@ -6,9 +6,12 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor +import java.lang.reflect.ParameterizedType import java.lang.reflect.Type +import java.lang.reflect.WildcardType import java.util.* import kotlin.coroutines.Continuation import kotlin.reflect.* @@ -63,7 +66,9 @@ internal abstract class KCallableImpl : KCallable { get() = _parameters() private val _returnType = ReflectProperties.lazySoft { - KTypeImpl(descriptor.returnType!!) { caller.returnType } + KTypeImpl(descriptor.returnType!!) { + extractContinuationArgument() ?: caller.returnType + } } override val returnType: KType @@ -191,4 +196,19 @@ internal abstract class KCallableImpl : KCallable { else -> throw UnsupportedOperationException("Unknown primitive: $type") } } else null + + private fun extractContinuationArgument(): Type? { + if ((descriptor as? FunctionDescriptor)?.isSuspend == true) { + // kotlin.coroutines.Continuation + val continuationType = caller.parameterTypes.lastOrNull() as? ParameterizedType + if (continuationType?.rawType == Continuation::class.java) { + // ? super java.lang.String + val wildcard = continuationType.actualTypeArguments.single() as? WildcardType + // java.lang.String + return wildcard?.lowerBounds?.first() + } + } + + return null + } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index c4d99b6b5aa..e817655439b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -16871,6 +16871,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/reflection/mapping/types/supertypes.kt"); } + @TestMetadata("suspendFun.kt") + public void testSuspendFun() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt"); + } + @TestMetadata("topLevelFunctions.kt") public void testTopLevelFunctions() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/types/topLevelFunctions.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index ca6fdb443c1..62f4385d74a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -17936,6 +17936,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/reflection/mapping/types/supertypes.kt"); } + @TestMetadata("suspendFun.kt") + public void testSuspendFun() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/types/suspendFun.kt"); + } + @TestMetadata("topLevelFunctions.kt") public void testTopLevelFunctions() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/types/topLevelFunctions.kt");