diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt index 68c813681fb..c70d3d92ce1 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt @@ -151,7 +151,9 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa private lateinit var functionReferenceThis: IrValueParameterSymbol private lateinit var argumentToPropertiesMap: Map - private val functionReference = context.ir.symbols.functionReference + private val isLambda = irFunctionReference.origin == IrStatementOrigin.LAMBDA + + private val functionReferenceOrLambda = if (isLambda) context.ir.symbols.lambdaClass else context.ir.symbols.functionReference fun build(): BuiltFunctionReference { val startOffset = irFunctionReference.startOffset @@ -159,7 +161,7 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa val returnType = functionDescriptor.returnType!! val superTypes: MutableList = mutableListOf( - functionReference.descriptor.defaultType + functionReferenceOrLambda.descriptor.defaultType ) val numberOfParameters = unboundFunctionParameters.size @@ -210,29 +212,6 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa val invokeFunctionDescriptor = functionClassDescriptor.getFunction("invoke", functionClassTypeParameters) val invokeMethodBuilder = createInvokeMethodBuilder(invokeFunctionDescriptor) - val getSignatureBuilder = - createGetSignatureMethodBuilder(functionReference.owner.descriptor.getFunction("getSignature", emptyList())) - val getNameBuilder = createGetNameMethodBuilder(functionReference.owner.descriptor.getProperty("name", emptyList())) - val getOwnerBuilder = createGetOwnerMethodBuilder(functionReference.owner.descriptor.getFunction("getOwner", emptyList())) - - val suspendInvokeMethodBuilder = - if (suspendFunctionClassDescriptor != null) { - val suspendInvokeFunctionDescriptor = - suspendFunctionClassDescriptor.getFunction("invoke", suspendFunctionClassTypeParameters!!) - createInvokeMethodBuilder(suspendInvokeFunctionDescriptor) - } else null - - val inheritedScope = functionReference.descriptor.unsubstitutedMemberScope - .getContributedDescriptors().mapNotNull { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) } - .filterNot { it.name.asString() == "getSignature" || it.name.asString() == "name" || it.name.asString() == "getOwner" } - - contributedDescriptors.addAll( - ( - inheritedScope + invokeMethodBuilder.symbol.descriptor + - suspendInvokeMethodBuilder?.symbol?.descriptor + getSignatureBuilder.symbol.descriptor - ).filterNotNull() - ) - constructorBuilder.initialize() functionReferenceClass.declarations.add(constructorBuilder.ir) @@ -240,18 +219,46 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa invokeMethodBuilder.initialize() functionReferenceClass.declarations.add(invokeMethodBuilder.ir) - getSignatureBuilder.initialize() - functionReferenceClass.declarations.add(getSignatureBuilder.ir) - getNameBuilder.initialize() - functionReferenceClass.declarations.add(getNameBuilder.ir) + if (!isLambda) { + val getSignatureBuilder = + createGetSignatureMethodBuilder(functionReferenceOrLambda.owner.descriptor.getFunction("getSignature", emptyList())) + val getNameBuilder = createGetNameMethodBuilder(functionReferenceOrLambda.owner.descriptor.getProperty("name", emptyList())) + val getOwnerBuilder = + createGetOwnerMethodBuilder(functionReferenceOrLambda.owner.descriptor.getFunction("getOwner", emptyList())) - getOwnerBuilder.initialize() - functionReferenceClass.declarations.add(getOwnerBuilder.ir) + val suspendInvokeMethodBuilder = + if (suspendFunctionClassDescriptor != null) { + val suspendInvokeFunctionDescriptor = + suspendFunctionClassDescriptor.getFunction("invoke", suspendFunctionClassTypeParameters!!) + createInvokeMethodBuilder(suspendInvokeFunctionDescriptor) + } else null - suspendInvokeMethodBuilder?.let { - it.initialize() - functionReferenceClass.declarations.add(it.ir) + val inheritedScope = functionReferenceOrLambda.descriptor.unsubstitutedMemberScope + .getContributedDescriptors().mapNotNull { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) } + .filterNot { !isLambda && (it.name.asString() == "getSignature" || it.name.asString() == "name" || it.name.asString() == "getOwner") } + + contributedDescriptors.addAll( + ( + inheritedScope + invokeMethodBuilder.symbol.descriptor + + suspendInvokeMethodBuilder?.symbol?.descriptor + getSignatureBuilder.symbol.descriptor + ).filterNotNull() + ) + + + getSignatureBuilder.initialize() + functionReferenceClass.declarations.add(getSignatureBuilder.ir) + + getNameBuilder.initialize() + functionReferenceClass.declarations.add(getNameBuilder.ir) + + getOwnerBuilder.initialize() + functionReferenceClass.declarations.add(getOwnerBuilder.ir) + + suspendInvokeMethodBuilder?.let { + it.initialize() + functionReferenceClass.declarations.add(it.ir) + } } return BuiltFunctionReference(functionReferenceClass, constructorBuilder.ir) @@ -260,7 +267,7 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa private fun createConstructorBuilder() = object : SymbolWithIrBuilder() { private val kFunctionRefConstructorSymbol = - functionReference.constructors.filter { it.descriptor.valueParameters.size == 2 }.single() + functionReferenceOrLambda.constructors.filter { it.descriptor.valueParameters.size == if (isLambda) 1 else 2 }.single() override fun buildSymbol() = IrConstructorSymbolImpl( ClassConstructorDescriptorImpl.create( @@ -308,13 +315,15 @@ class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPa IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, unboundFunctionParameters.size) putValueArgument(0, const) - val irReceiver = valueParameters.firstOrNull() - val receiver = boundFunctionParameters.singleOrNull() - //TODO pass proper receiver - val receiverValue = receiver?.let { - irGet(irReceiver!!.symbol.owner) - } ?: irNull() - putValueArgument(1, receiverValue) + if (!isLambda) { + val irReceiver = valueParameters.firstOrNull() + val receiver = boundFunctionParameters.singleOrNull() + //TODO pass proper receiver + val receiverValue = receiver?.let { + irGet(irReceiver!!.symbol.owner) + } ?: irNull() + putValueArgument(1, receiverValue) + } } //TODO don't write receiver again: use it from base class diff --git a/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt b/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt index b3695cb3c4e..6bc06b1ece1 100644 --- a/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt +++ b/compiler/testData/codegen/box/coroutines/createCoroutinesOnManualInstances_1_2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.kt b/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.kt index f78330b2c17..fa760a238c1 100644 --- a/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.kt +++ b/compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt inline fun test(p: T) { diff --git a/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.kt b/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.kt index eb17581bb81..98751109cac 100644 --- a/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.kt +++ b/compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // FILE: 1.kt inline fun test(p: Any) {