[NI] Support callable references to suspend functions
#KT-30658 Fixed
This commit is contained in:
+8
-3
@@ -315,7 +315,7 @@ class CallableReferencesCandidateFactory(
|
|||||||
|
|
||||||
return callComponents.reflectionTypes.getKFunctionType(
|
return callComponents.reflectionTypes.getKFunctionType(
|
||||||
Annotations.EMPTY, null, argumentsAndReceivers, null,
|
Annotations.EMPTY, null, argumentsAndReceivers, null,
|
||||||
returnType, descriptor.builtIns, isSuspend = false
|
returnType, descriptor.builtIns, descriptor.isSuspend
|
||||||
) to defaults
|
) to defaults
|
||||||
}
|
}
|
||||||
else -> error("Unsupported descriptor type: $descriptor")
|
else -> error("Unsupported descriptor type: $descriptor")
|
||||||
@@ -347,17 +347,22 @@ fun extractInputOutputTypesFromCallableReferenceExpectedType(expectedType: Unwra
|
|||||||
if (expectedType == null) return null
|
if (expectedType == null) return null
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
expectedType.isFunctionType ->
|
expectedType.isFunctionType || expectedType.isSuspendFunctionType ->
|
||||||
extractInputOutputTypesFromFunctionType(expectedType)
|
extractInputOutputTypesFromFunctionType(expectedType)
|
||||||
|
|
||||||
ReflectionTypes.isBaseTypeForNumberedReferenceTypes(expectedType) ->
|
ReflectionTypes.isBaseTypeForNumberedReferenceTypes(expectedType) ->
|
||||||
InputOutputTypes(emptyList(), expectedType.arguments.single().type.unwrap())
|
InputOutputTypes(emptyList(), expectedType.arguments.single().type.unwrap())
|
||||||
|
|
||||||
ReflectionTypes.isNumberedKFunctionOrKSuspendFunction(expectedType) -> {
|
ReflectionTypes.isNumberedKFunction(expectedType) -> {
|
||||||
val functionFromSupertype = expectedType.immediateSupertypes().first { it.isFunctionType }.unwrap()
|
val functionFromSupertype = expectedType.immediateSupertypes().first { it.isFunctionType }.unwrap()
|
||||||
extractInputOutputTypesFromFunctionType(functionFromSupertype)
|
extractInputOutputTypesFromFunctionType(functionFromSupertype)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReflectionTypes.isNumberedKSuspendFunction(expectedType) -> {
|
||||||
|
val kSuspendFunctionType = expectedType.immediateSupertypes().first { it.isSuspendFunctionType }.unwrap()
|
||||||
|
extractInputOutputTypesFromFunctionType(kSuspendFunctionType)
|
||||||
|
}
|
||||||
|
|
||||||
ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(expectedType) -> {
|
ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(expectedType) -> {
|
||||||
val functionFromSupertype = expectedType.supertypes().first { it.isFunctionType }.unwrap()
|
val functionFromSupertype = expectedType.supertypes().first { it.isFunctionType }.unwrap()
|
||||||
extractInputOutputTypesFromFunctionType(functionFromSupertype)
|
extractInputOutputTypesFromFunctionType(functionFromSupertype)
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !LANGUAGE: +NewInference
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !USE_EXPERIMENTAL: kotlin.Experimental
|
||||||
|
|
||||||
|
import kotlin.reflect.KSuspendFunction0
|
||||||
|
import kotlin.reflect.KSuspendFunction1
|
||||||
|
import kotlin.reflect.KFunction0
|
||||||
|
import kotlin.reflect.KFunction1
|
||||||
|
|
||||||
|
fun test0(serialize: KSuspendFunction0<Unit>) {}
|
||||||
|
fun test1(serialize: KSuspendFunction1<Int, Unit>) {}
|
||||||
|
|
||||||
|
suspend fun foo() {}
|
||||||
|
suspend fun bar(x: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
test0(::foo)
|
||||||
|
test1(<!TYPE_MISMATCH!>::foo<!>)
|
||||||
|
|
||||||
|
test0(<!TYPE_MISMATCH!>::bar<!>)
|
||||||
|
test1(::bar)
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public suspend fun bar(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||||
|
public suspend fun foo(): kotlin.Unit
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
public fun test0(/*0*/ serialize: kotlin.reflect.KSuspendFunction0<kotlin.Unit>): kotlin.Unit
|
||||||
|
public fun test1(/*0*/ serialize: kotlin.reflect.KSuspendFunction1<kotlin.Int, kotlin.Unit>): kotlin.Unit
|
||||||
+5
@@ -1802,6 +1802,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/applyInsideCoroutine.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/applyInsideCoroutine.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableReferenceToASuspendFunction.kt")
|
||||||
|
public void testCallableReferenceToASuspendFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/callableReferenceToASuspendFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("chainCallWithExtensionExplicitTypes.kt")
|
@TestMetadata("chainCallWithExtensionExplicitTypes.kt")
|
||||||
public void testChainCallWithExtensionExplicitTypes() throws Exception {
|
public void testChainCallWithExtensionExplicitTypes() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/chainCallWithExtensionExplicitTypes.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/chainCallWithExtensionExplicitTypes.kt");
|
||||||
|
|||||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+5
@@ -1802,6 +1802,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/applyInsideCoroutine.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/applyInsideCoroutine.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callableReferenceToASuspendFunction.kt")
|
||||||
|
public void testCallableReferenceToASuspendFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/callableReferenceToASuspendFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("chainCallWithExtensionExplicitTypes.kt")
|
@TestMetadata("chainCallWithExtensionExplicitTypes.kt")
|
||||||
public void testChainCallWithExtensionExplicitTypes() throws Exception {
|
public void testChainCallWithExtensionExplicitTypes() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/chainCallWithExtensionExplicitTypes.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/chainCallWithExtensionExplicitTypes.kt");
|
||||||
|
|||||||
@@ -152,11 +152,14 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isNumberedKFunctionOrKSuspendFunction(type: KotlinType): Boolean {
|
fun isNumberedKFunctionOrKSuspendFunction(type: KotlinType): Boolean {
|
||||||
|
return isNumberedKFunction(type) || isNumberedKSuspendFunction(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNumberedKFunction(type: KotlinType): Boolean {
|
||||||
val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
|
val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
|
||||||
val shortName = descriptor.name.asString()
|
val shortName = descriptor.name.asString()
|
||||||
|
|
||||||
return (shortName.length > K_FUNCTION_PREFIX.length && shortName.startsWith(K_FUNCTION_PREFIX) ||
|
return (shortName.length > K_FUNCTION_PREFIX.length && shortName.startsWith(K_FUNCTION_PREFIX)) &&
|
||||||
isNumberedKSuspendFunction(type)) &&
|
|
||||||
DescriptorUtils.getFqName(descriptor).parent().toSafe() == KOTLIN_REFLECT_FQ_NAME
|
DescriptorUtils.getFqName(descriptor).parent().toSafe() == KOTLIN_REFLECT_FQ_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user