Support suspend conversion in callable reference adaptation

#KT-15917 In Progress
This commit is contained in:
Mikhail Zarechenskiy
2020-04-22 04:51:07 +03:00
parent 537a59d6ca
commit ac642cf175
13 changed files with 221 additions and 3 deletions
@@ -23011,6 +23011,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.kt");
}
@TestMetadata("basicSuspendConversionForCallableReference.kt")
public void testBasicSuspendConversionForCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.kt");
}
@TestMetadata("basicSuspendConversionGenerics.kt")
public void testBasicSuspendConversionGenerics() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.kt");
@@ -23025,6 +23030,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
public void testSuspendConversionDisabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt");
}
@TestMetadata("suspendConversionWithFunInterfaces.kt")
public void testSuspendConversionWithFunInterfaces() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt");
}
@TestMetadata("suspendConversionWithReferenceAdaptation.kt")
public void testSuspendConversionWithReferenceAdaptation() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/syntheticExtensions")
@@ -75,9 +75,14 @@ class CallableReferenceAdaptation(
val argumentTypes: Array<KotlinType>,
val coercionStrategy: CoercionStrategy,
val defaults: Int,
val mappedArguments: Map<ValueParameterDescriptor, ResolvedCallArgument>
val mappedArguments: Map<ValueParameterDescriptor, ResolvedCallArgument>,
val suspendConversionStrategy: SuspendConversionStrategy
)
enum class SuspendConversionStrategy {
SUSPEND_CONVERSION, NO_CONVERSION
}
/**
* cases: class A {}, class B { companion object }, object C, enum class D { E }
* A::foo <-> Type
@@ -332,10 +337,21 @@ class CallableReferencesCandidateFactory(
else
mappedArguments
val suspendConversionStrategy =
if (
callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SuspendConversion) &&
!descriptor.isSuspend && expectedType?.isSuspendFunctionType == true
) {
SuspendConversionStrategy.SUSPEND_CONVERSION
} else {
SuspendConversionStrategy.NO_CONVERSION
}
return CallableReferenceAdaptation(
@Suppress("UNCHECKED_CAST") (mappedArgumentTypes as Array<KotlinType>),
coercion, defaults,
adaptedArguments
adaptedArguments,
suspendConversionStrategy
)
}
@@ -428,9 +444,12 @@ class CallableReferencesCandidateFactory(
descriptorReturnType
}
val suspendConversionStrategy = callableReferenceAdaptation?.suspendConversionStrategy
val isSuspend = descriptor.isSuspend || suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION
return callComponents.reflectionTypes.getKFunctionType(
Annotations.EMPTY, null, argumentsAndReceivers, null,
returnType, descriptor.builtIns, descriptor.isSuspend
returnType, descriptor.builtIns, isSuspend
) to callableReferenceAdaptation
}
else -> return ErrorUtils.createErrorType("Unsupported descriptor type: $descriptor") to null
@@ -0,0 +1,18 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo1(f: suspend () -> Unit) {}
fun bar1() {}
fun <T> foo2(e: T, f: suspend (T) -> Unit) {}
fun bar2(x: Int) {}
fun bar2(s: String) {}
fun test() {
<!INAPPLICABLE_CANDIDATE!>foo1<!>(::bar1)
<!INAPPLICABLE_CANDIDATE!>foo2<!>(42, <!UNRESOLVED_REFERENCE!>::bar2<!>)
<!INAPPLICABLE_CANDIDATE!>foo2<!>("str", <!UNRESOLVED_REFERENCE!>::bar2<!>)
<!INAPPLICABLE_CANDIDATE!>foo2<!>(42, ::bar1)
}
@@ -0,0 +1,18 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun foo1(f: suspend () -> Unit) {}
fun bar1() {}
fun <T> foo2(e: T, f: suspend (T) -> Unit) {}
fun bar2(x: Int) {}
fun bar2(s: String) {}
fun test() {
foo1(::bar1)
foo2(42, ::bar2)
foo2("str", ::bar2)
foo2(42, <!TYPE_MISMATCH!>::bar1<!>)
}
@@ -0,0 +1,8 @@
package
public fun bar1(): kotlin.Unit
public fun bar2(/*0*/ x: kotlin.Int): kotlin.Unit
public fun bar2(/*0*/ s: kotlin.String): kotlin.Unit
public fun foo1(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun </*0*/ T> foo2(/*0*/ e: T, /*1*/ f: suspend (T) -> kotlin.Unit): kotlin.Unit
public fun test(): kotlin.Unit
@@ -0,0 +1,21 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun interface SuspendRunnable {
suspend fun invoke()
}
fun foo1(s: SuspendRunnable) {}
fun bar1() {}
fun bar2(s: String = ""): Int = 0
fun bar3() {}
suspend fun bar3(s: String = ""): Int = 0
fun test() {
<!INAPPLICABLE_CANDIDATE!>foo1<!>(::bar1)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(::bar2)
<!INAPPLICABLE_CANDIDATE!>foo1<!>(<!UNRESOLVED_REFERENCE!>::bar3<!>) // Should be ambiguity
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun interface SuspendRunnable {
suspend fun invoke()
}
fun foo1(s: SuspendRunnable) {}
fun bar1() {}
fun bar2(s: String = ""): Int = 0
fun bar3() {}
suspend fun bar3(s: String = ""): Int = 0
fun test() {
foo1(::bar1)
foo1(::bar2)
foo1(::bar3) // Should be ambiguity
}
@@ -0,0 +1,15 @@
package
public fun bar1(): kotlin.Unit
public fun bar2(/*0*/ s: kotlin.String = ...): kotlin.Int
public fun bar3(): kotlin.Unit
public suspend fun bar3(/*0*/ s: kotlin.String = ...): kotlin.Int
public fun foo1(/*0*/ s: SuspendRunnable): kotlin.Unit
public fun test(): kotlin.Unit
public fun interface SuspendRunnable {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract suspend fun invoke(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun unitCoercion(f: suspend () -> Unit) {}
fun foo(): Int = 0
fun defaults(f: suspend (Int) -> String) {}
fun bar(i: Int, l: Long = 42L): String = ""
fun varargs(f: suspend (Int, Int, Int) -> String) {}
fun baz(vararg ints: Int): String = ""
fun unitCoercionAndDefaults(f: suspend () -> Unit) {}
fun all(s: String = ""): Int = 0
fun test() {
<!INAPPLICABLE_CANDIDATE!>unitCoercion<!>(::foo)
<!INAPPLICABLE_CANDIDATE!>defaults<!>(::bar)
<!INAPPLICABLE_CANDIDATE!>varargs<!>(::baz)
<!INAPPLICABLE_CANDIDATE!>unitCoercionAndDefaults<!>(::all)
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun unitCoercion(f: suspend () -> Unit) {}
fun foo(): Int = 0
fun defaults(f: suspend (Int) -> String) {}
fun bar(i: Int, l: Long = 42L): String = ""
fun varargs(f: suspend (Int, Int, Int) -> String) {}
fun baz(vararg ints: Int): String = ""
fun unitCoercionAndDefaults(f: suspend () -> Unit) {}
fun all(s: String = ""): Int = 0
fun test() {
unitCoercion(::foo)
defaults(::bar)
varargs(::baz)
unitCoercionAndDefaults(::all)
}
@@ -0,0 +1,11 @@
package
public fun all(/*0*/ s: kotlin.String = ...): kotlin.Int
public fun bar(/*0*/ i: kotlin.Int, /*1*/ l: kotlin.Long = ...): kotlin.String
public fun baz(/*0*/ vararg ints: kotlin.Int /*kotlin.IntArray*/): kotlin.String
public fun defaults(/*0*/ f: suspend (kotlin.Int) -> kotlin.String): kotlin.Unit
public fun foo(): kotlin.Int
public fun test(): kotlin.Unit
public fun unitCoercion(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun unitCoercionAndDefaults(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun varargs(/*0*/ f: suspend (kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.String): kotlin.Unit
@@ -23093,6 +23093,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.kt");
}
@TestMetadata("basicSuspendConversionForCallableReference.kt")
public void testBasicSuspendConversionForCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.kt");
}
@TestMetadata("basicSuspendConversionGenerics.kt")
public void testBasicSuspendConversionGenerics() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.kt");
@@ -23107,6 +23112,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
public void testSuspendConversionDisabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt");
}
@TestMetadata("suspendConversionWithFunInterfaces.kt")
public void testSuspendConversionWithFunInterfaces() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt");
}
@TestMetadata("suspendConversionWithReferenceAdaptation.kt")
public void testSuspendConversionWithReferenceAdaptation() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/syntheticExtensions")
@@ -23013,6 +23013,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversion.kt");
}
@TestMetadata("basicSuspendConversionForCallableReference.kt")
public void testBasicSuspendConversionForCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionForCallableReference.kt");
}
@TestMetadata("basicSuspendConversionGenerics.kt")
public void testBasicSuspendConversionGenerics() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/basicSuspendConversionGenerics.kt");
@@ -23027,6 +23032,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
public void testSuspendConversionDisabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt");
}
@TestMetadata("suspendConversionWithFunInterfaces.kt")
public void testSuspendConversionWithFunInterfaces() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt");
}
@TestMetadata("suspendConversionWithReferenceAdaptation.kt")
public void testSuspendConversionWithReferenceAdaptation() throws Exception {
runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithReferenceAdaptation.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/syntheticExtensions")