[NI] Record substituted generic signature for SAM arguments

#KT-36297 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-02-03 18:43:31 +03:00
parent 8ef79f932c
commit cb07c9172f
6 changed files with 113 additions and 1 deletions
@@ -797,7 +797,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
if (valueArgument == null || newResolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) == null) continue;
valueParametersWithSAMConversion.add(valueParameter.getOriginal());
valueParametersWithSAMConversion.add(valueParameter);
}
writeSamValueForValueParameters(valueParametersWithSAMConversion, newResolvedCall.getValueArgumentsByIndex());
@@ -0,0 +1,92 @@
// !LANGUAGE: +NewInference +SamConversionPerArgument +SamConversionForKotlinFunctions +FunctionalInterfaceConversion
// WITH_REFLECT
// FULL_JDK
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// FILE: Provider.java
public class Provider {
public <T> String samCall(java.util.concurrent.Callable<? extends T> value) {
return "fail";
}
}
// FILE: test.kt
import java.util.concurrent.Callable
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import kotlin.reflect.KClass
import kotlin.test.assertEquals
private fun getFirstArgumentType(types: Array<Type>, klass: KClass<*>): String {
return types
.filterIsInstance<ParameterizedType>()
.firstOrNull { it.rawType == klass.java }
?.let { it.actualTypeArguments[0] }
?.toString() ?: "fail, inferred type is null"
}
class KtProvider : Provider() {
override fun <T : Any> samCall(value: Callable<out T>): String =
getFirstArgumentType(value.javaClass.genericInterfaces, Callable::class)
}
fun interface KtCallable<T> {
fun invoke(): T
}
fun <T : Any> samCallViaFunInterface(value: KtCallable<out T>): String {
return getFirstArgumentType(value.javaClass.genericInterfaces, KtCallable::class)
}
fun testCallViaJava(p: Provider): String {
var result = "not changed"
wrapInline {
wrapNoInline {
result = p.samCall { "str" }
}
}
return result
}
fun testCallViaKotlin(p: KtProvider): String {
var result = "not changed"
wrapInline {
wrapNoInline {
result = p.samCall { "str" }
}
}
return result
}
fun testCallViaFunInterface(): String {
var result = "not changed"
wrapInline {
wrapNoInline {
result = samCallViaFunInterface { "str" }
}
}
return result
}
inline fun wrapInline(f: () -> Unit) {
f()
}
fun wrapNoInline(f: () -> Unit) {
f()
}
fun box(): String {
val inferredTypeInSamLambda1 = testCallViaJava(KtProvider())
val inferredTypeInSamLambda2 = testCallViaKotlin(KtProvider())
val inferredTypeInSamLambda3 = testCallViaFunInterface()
assertEquals(inferredTypeInSamLambda1, inferredTypeInSamLambda2)
assertEquals(inferredTypeInSamLambda2, inferredTypeInSamLambda3)
return if (inferredTypeInSamLambda1 == "class java.lang.String") "OK" else "fail: $inferredTypeInSamLambda1"
}
@@ -26536,6 +26536,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/sam/receiverEvaluatedOnce.kt");
}
@TestMetadata("recordSubstitutedTypeForCallableSamParameter.kt")
public void testRecordSubstitutedTypeForCallableSamParameter() throws Exception {
runTest("compiler/testData/codegen/box/sam/recordSubstitutedTypeForCallableSamParameter.kt");
}
@TestMetadata("compiler/testData/codegen/box/sam/constructors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -25353,6 +25353,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/sam/receiverEvaluatedOnce.kt");
}
@TestMetadata("recordSubstitutedTypeForCallableSamParameter.kt")
public void testRecordSubstitutedTypeForCallableSamParameter() throws Exception {
runTest("compiler/testData/codegen/box/sam/recordSubstitutedTypeForCallableSamParameter.kt");
}
@TestMetadata("compiler/testData/codegen/box/sam/constructors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -25060,6 +25060,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/sam/receiverEvaluatedOnce.kt");
}
@TestMetadata("recordSubstitutedTypeForCallableSamParameter.kt")
public void testRecordSubstitutedTypeForCallableSamParameter() throws Exception {
runTest("compiler/testData/codegen/box/sam/recordSubstitutedTypeForCallableSamParameter.kt");
}
@TestMetadata("compiler/testData/codegen/box/sam/constructors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -25060,6 +25060,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/sam/receiverEvaluatedOnce.kt");
}
@TestMetadata("recordSubstitutedTypeForCallableSamParameter.kt")
public void testRecordSubstitutedTypeForCallableSamParameter() throws Exception {
runTest("compiler/testData/codegen/box/sam/recordSubstitutedTypeForCallableSamParameter.kt");
}
@TestMetadata("compiler/testData/codegen/box/sam/constructors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)