JVM_IR KT-47939 use FunInterfaceConstructorReference as base class
This commit is contained in:
committed by
TeamCityServer
parent
0ccd7a7e0c
commit
93713a9ad4
+12
@@ -3603,6 +3603,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorIsKFunction.kt")
|
||||||
|
public void testFunInterfaceConstructorIsKFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorIsKFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
|
public void testFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("funInterfaceConstructorThrowsNpe.kt")
|
@TestMetadata("funInterfaceConstructorThrowsNpe.kt")
|
||||||
public void testFunInterfaceConstructorThrowsNpe() throws Exception {
|
public void testFunInterfaceConstructorThrowsNpe() throws Exception {
|
||||||
|
|||||||
+34
-30
@@ -593,6 +593,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
samSuperType
|
samSuperType
|
||||||
?: when {
|
?: when {
|
||||||
isLambda -> context.ir.symbols.lambdaClass
|
isLambda -> context.ir.symbols.lambdaClass
|
||||||
|
isAdaptedFunInterfaceConstructorReference -> context.ir.symbols.funInterfaceConstructorReferenceClass
|
||||||
useOptimizedSuperClass -> when {
|
useOptimizedSuperClass -> when {
|
||||||
isAdaptedReference -> context.ir.symbols.adaptedFunctionReference
|
isAdaptedReference -> context.ir.symbols.adaptedFunctionReference
|
||||||
else -> context.ir.symbols.functionReferenceImpl
|
else -> context.ir.symbols.functionReferenceImpl
|
||||||
@@ -743,22 +744,29 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Super constructor:
|
// Super constructor:
|
||||||
|
// - For fun interface constructor references, super class is kotlin.jvm.internal.FunInterfaceConstructorReference
|
||||||
|
// with single constructor 'public FunInterfaceConstructorReference(Class funInterface)'
|
||||||
// - For SAM references, the super class is Any
|
// - For SAM references, the super class is Any
|
||||||
// - For lambdas, accepts arity
|
// - For lambdas, accepts arity
|
||||||
// - For optimized function references (1.4+), accepts:
|
// - For optimized function references (1.4+), accepts:
|
||||||
// arity, [receiver], owner, name, signature, flags
|
// arity, [receiver], owner, name, signature, flags
|
||||||
// - For unoptimized function references, accepts:
|
// - For unoptimized function references, accepts:
|
||||||
// arity, [receiver]
|
// arity, [receiver]
|
||||||
val constructor = if (samSuperType != null) {
|
val constructor =
|
||||||
context.irBuiltIns.anyClass.owner.constructors.single()
|
when {
|
||||||
} else {
|
isAdaptedFunInterfaceConstructorReference ->
|
||||||
val expectedArity =
|
context.ir.symbols.funInterfaceConstructorReferenceClass.owner.constructors.single()
|
||||||
if (isLambda && !isAdaptedReference) 1
|
samSuperType != null ->
|
||||||
else 1 + (if (boundReceiver != null) 1 else 0) + (if (useOptimizedSuperClass) 4 else 0)
|
context.irBuiltIns.anyClass.owner.constructors.single()
|
||||||
superType.getClass()!!.constructors.single {
|
else -> {
|
||||||
it.valueParameters.size == expectedArity
|
val expectedArity =
|
||||||
|
if (isLambda && !isAdaptedReference) 1
|
||||||
|
else 1 + (if (boundReceiver != null) 1 else 0) + (if (useOptimizedSuperClass) 4 else 0)
|
||||||
|
superType.getClass()!!.constructors.single {
|
||||||
|
it.valueParameters.size == expectedArity
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
body = context.createJvmIrBuilder(symbol).run {
|
body = context.createJvmIrBuilder(symbol).run {
|
||||||
irBlockBody(startOffset, endOffset) {
|
irBlockBody(startOffset, endOffset) {
|
||||||
@@ -776,28 +784,24 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
call: IrFunctionAccessExpression,
|
call: IrFunctionAccessExpression,
|
||||||
generateBoundReceiver: IrBuilder.() -> IrExpression
|
generateBoundReceiver: IrBuilder.() -> IrExpression
|
||||||
) {
|
) {
|
||||||
var index = 0
|
|
||||||
call.putValueArgument(index++, irInt(argumentTypes.size + if (irFunctionReference.isSuspend) 1 else 0))
|
|
||||||
if (boundReceiver != null) {
|
|
||||||
call.putValueArgument(index++, generateBoundReceiver())
|
|
||||||
}
|
|
||||||
if (isAdaptedFunInterfaceConstructorReference) {
|
if (isAdaptedFunInterfaceConstructorReference) {
|
||||||
val owner = kClassReference(constructedFunInterfaceSymbol!!.owner.defaultType)
|
val funInterfaceKClassRef = kClassReference(constructedFunInterfaceSymbol!!.owner.defaultType)
|
||||||
// owner: <FUN_INTERFACE_TYPE>
|
val funInterfaceJavaClassRef = kClassToJavaClass(funInterfaceKClassRef)
|
||||||
call.putValueArgument(index++, kClassToJavaClass(owner))
|
call.putValueArgument(0, funInterfaceJavaClassRef)
|
||||||
// name: ""
|
} else {
|
||||||
call.putValueArgument(index++, irString(""))
|
var index = 0
|
||||||
// signature: ""
|
call.putValueArgument(index++, irInt(argumentTypes.size + if (irFunctionReference.isSuspend) 1 else 0))
|
||||||
call.putValueArgument(index++, irString(""))
|
if (boundReceiver != null) {
|
||||||
// flags: 8 = 3 << 1
|
call.putValueArgument(index++, generateBoundReceiver())
|
||||||
call.putValueArgument(index, irInt(8))
|
}
|
||||||
} else if (!isLambda && useOptimizedSuperClass) {
|
if (!isLambda && useOptimizedSuperClass) {
|
||||||
val callableReferenceTarget = adaptedReferenceOriginalTarget ?: callee
|
val callableReferenceTarget = adaptedReferenceOriginalTarget ?: callee
|
||||||
val owner = calculateOwnerKClass(callableReferenceTarget.parent)
|
val owner = calculateOwnerKClass(callableReferenceTarget.parent)
|
||||||
call.putValueArgument(index++, kClassToJavaClass(owner))
|
call.putValueArgument(index++, kClassToJavaClass(owner))
|
||||||
call.putValueArgument(index++, irString(callableReferenceTarget.originalName.asString()))
|
call.putValueArgument(index++, irString(callableReferenceTarget.originalName.asString()))
|
||||||
call.putValueArgument(index++, generateSignature(callableReferenceTarget.symbol))
|
call.putValueArgument(index++, generateSignature(callableReferenceTarget.symbol))
|
||||||
call.putValueArgument(index, irInt(getFunctionReferenceFlags(callableReferenceTarget)))
|
call.putValueArgument(index, irInt(getFunctionReferenceFlags(callableReferenceTarget)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -377,6 +377,14 @@ class JvmSymbols(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val funInterfaceConstructorReferenceClass =
|
||||||
|
createClass(FqName("kotlin.jvm.internal.FunInterfaceConstructorReference"), classModality = Modality.OPEN) { irClass ->
|
||||||
|
irClass.superTypes = listOf(irBuiltIns.anyType)
|
||||||
|
irClass.addConstructor().also { irConstructor ->
|
||||||
|
irConstructor.addValueParameter("funInterface", javaLangClass.starProjectedType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getFunction(parameterCount: Int): IrClassSymbol = irBuiltIns.functionN(parameterCount).symbol
|
fun getFunction(parameterCount: Int): IrClassSymbol = irBuiltIns.functionN(parameterCount).symbol
|
||||||
|
|
||||||
private val jvmFunctionClasses = storageManager.createMemoizedFunction { n: Int ->
|
private val jvmFunctionClasses = storageManager.createMemoizedFunction { n: Int ->
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
// !LANGUAGE: +KotlinFunInterfaceConstructorReference
|
||||||
|
|
||||||
|
// DONT_TARGET_EXACT_BACKEND: JVM
|
||||||
|
// ^ old JVM BE generates bogus code
|
||||||
|
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
// ^ Failed: kr is class Function1
|
||||||
|
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.KFunction
|
||||||
|
|
||||||
|
fun interface KRunnable {
|
||||||
|
fun run()
|
||||||
|
}
|
||||||
|
|
||||||
|
val kr = ::KRunnable // : KFunction1<() -> Unit, KRunnable>
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return if (kr is KFunction<*>)
|
||||||
|
"OK"
|
||||||
|
else
|
||||||
|
"Failed: kr is ${kr::class}"
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// !LANGUAGE: +KotlinFunInterfaceConstructorReference
|
||||||
|
|
||||||
|
// IGNORE_BACKEND: JVM
|
||||||
|
// ^ unsupported in old JVM BE
|
||||||
|
|
||||||
|
fun interface KRunnable {
|
||||||
|
fun run()
|
||||||
|
}
|
||||||
|
|
||||||
|
val kr = ::KRunnable // : KFunction1<() -> Unit, KRunnable>
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var test = "Failed"
|
||||||
|
kr { test = "OK" }.run()
|
||||||
|
return test
|
||||||
|
}
|
||||||
+3
-3
@@ -3520,9 +3520,9 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("funInterfaceConstructorThrowsNpe.kt")
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
public void testFunInterfaceConstructorThrowsNpe() throws Exception {
|
public void testFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorThrowsNpe.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
@@ -3603,6 +3603,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorIsKFunction.kt")
|
||||||
|
public void testFunInterfaceConstructorIsKFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorIsKFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
|
public void testFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("funInterfaceConstructorThrowsNpe.kt")
|
@TestMetadata("funInterfaceConstructorThrowsNpe.kt")
|
||||||
public void testFunInterfaceConstructorThrowsNpe() throws Exception {
|
public void testFunInterfaceConstructorThrowsNpe() throws Exception {
|
||||||
|
|||||||
+3
-3
@@ -3078,9 +3078,9 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("funInterfaceConstructorThrowsNpe.kt")
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
public void ignoreFunInterfaceConstructorThrowsNpe() throws Exception {
|
public void ignoreFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorThrowsNpe.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
|||||||
+12
@@ -2462,6 +2462,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
public void testFunInterfaceConstructorEquality() throws Exception {
|
public void testFunInterfaceConstructorEquality() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorIsKFunction.kt")
|
||||||
|
public void testFunInterfaceConstructorIsKFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorIsKFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
|
public void testFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+12
@@ -2504,6 +2504,18 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
public void testFunInterfaceConstructorEquality() throws Exception {
|
public void testFunInterfaceConstructorEquality() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorIsKFunction.kt")
|
||||||
|
public void testFunInterfaceConstructorIsKFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorIsKFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
|
public void testFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+10
@@ -2230,6 +2230,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
public void testFunInterfaceConstructorEquality() throws Exception {
|
public void testFunInterfaceConstructorEquality() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceConstructorIsKFunction.kt")
|
||||||
|
public void testFunInterfaceConstructorIsKFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorIsKFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
|
public void testFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/callableReference/function")
|
@TestMetadata("compiler/testData/codegen/box/callableReference/function")
|
||||||
|
|||||||
@@ -31,12 +31,6 @@ public class FunctionReference extends CallableReference implements FunctionBase
|
|||||||
* fun useSuspend(f: suspend () -> Unit) {}
|
* fun useSuspend(f: suspend () -> Unit) {}
|
||||||
* useSuspend(::target)
|
* useSuspend(::target)
|
||||||
* </pre></ul>
|
* </pre></ul>
|
||||||
* <ul>3 - whether it is a synthetic <code>fun interface</code> constructor, i.e., <pre>
|
|
||||||
* fun interface KRunnable {
|
|
||||||
* fun run()
|
|
||||||
* }
|
|
||||||
* val kr: (() -> Unit) -> KRunnable = ::KRunnable
|
|
||||||
* </pre></ul>
|
|
||||||
* </li>
|
* </li>
|
||||||
*/
|
*/
|
||||||
@SinceKotlin(version = "1.4")
|
@SinceKotlin(version = "1.4")
|
||||||
|
|||||||
+12
@@ -2534,6 +2534,18 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
|
|||||||
public void testFunInterfaceConstructorEquality() throws Exception {
|
public void testFunInterfaceConstructorEquality() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorIsKFunction.kt")
|
||||||
|
public void testFunInterfaceConstructorIsKFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorIsKFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("funInterfaceConstructorOfImplicitKFunctionType.kt")
|
||||||
|
public void testFunInterfaceConstructorOfImplicitKFunctionType() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorOfImplicitKFunctionType.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
Reference in New Issue
Block a user