[NI] Support callable references to suspend functions

#KT-30658 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2019-03-28 11:50:37 +03:00
parent 017f9aea35
commit 1ac25259e8
6 changed files with 52 additions and 5 deletions
@@ -315,7 +315,7 @@ class CallableReferencesCandidateFactory(
return callComponents.reflectionTypes.getKFunctionType(
Annotations.EMPTY, null, argumentsAndReceivers, null,
returnType, descriptor.builtIns, isSuspend = false
returnType, descriptor.builtIns, descriptor.isSuspend
) to defaults
}
else -> error("Unsupported descriptor type: $descriptor")
@@ -347,17 +347,22 @@ fun extractInputOutputTypesFromCallableReferenceExpectedType(expectedType: Unwra
if (expectedType == null) return null
return when {
expectedType.isFunctionType ->
expectedType.isFunctionType || expectedType.isSuspendFunctionType ->
extractInputOutputTypesFromFunctionType(expectedType)
ReflectionTypes.isBaseTypeForNumberedReferenceTypes(expectedType) ->
InputOutputTypes(emptyList(), expectedType.arguments.single().type.unwrap())
ReflectionTypes.isNumberedKFunctionOrKSuspendFunction(expectedType) -> {
ReflectionTypes.isNumberedKFunction(expectedType) -> {
val functionFromSupertype = expectedType.immediateSupertypes().first { it.isFunctionType }.unwrap()
extractInputOutputTypesFromFunctionType(functionFromSupertype)
}
ReflectionTypes.isNumberedKSuspendFunction(expectedType) -> {
val kSuspendFunctionType = expectedType.immediateSupertypes().first { it.isSuspendFunctionType }.unwrap()
extractInputOutputTypesFromFunctionType(kSuspendFunctionType)
}
ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(expectedType) -> {
val functionFromSupertype = expectedType.supertypes().first { it.isFunctionType }.unwrap()
extractInputOutputTypesFromFunctionType(functionFromSupertype)
@@ -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)
}
@@ -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
@@ -1802,6 +1802,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
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")
public void testChainCallWithExtensionExplicitTypes() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/chainCallWithExtensionExplicitTypes.kt");
@@ -1802,6 +1802,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
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")
public void testChainCallWithExtensionExplicitTypes() throws Exception {
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 {
return isNumberedKFunction(type) || isNumberedKSuspendFunction(type)
}
fun isNumberedKFunction(type: KotlinType): Boolean {
val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
val shortName = descriptor.name.asString()
return (shortName.length > K_FUNCTION_PREFIX.length && shortName.startsWith(K_FUNCTION_PREFIX) ||
isNumberedKSuspendFunction(type)) &&
return (shortName.length > K_FUNCTION_PREFIX.length && shortName.startsWith(K_FUNCTION_PREFIX)) &&
DescriptorUtils.getFqName(descriptor).parent().toSafe() == KOTLIN_REFLECT_FQ_NAME
}