diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt index b17d0bceec7..8c87459170a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt @@ -112,7 +112,7 @@ internal class AdapterGenerator( adapteeSymbol: IrFunctionSymbol, type: IrSimpleType ): IrExpression { - val firAdaptee = callableReferenceAccess.toResolvedCallableReference()?.resolvedSymbol?.fir as? FirSimpleFunction + val firAdaptee = callableReferenceAccess.toResolvedCallableReference()?.resolvedSymbol?.fir as? FirFunction val adaptee = adapteeSymbol.owner val expectedReturnType = type.arguments.last().typeOrNull return callableReferenceAccess.convertWithOffsets { startOffset, endOffset -> @@ -164,7 +164,7 @@ internal class AdapterGenerator( callableReferenceAccess: FirCallableReferenceAccess, startOffset: Int, endOffset: Int, - firAdaptee: FirSimpleFunction, + firAdaptee: FirFunction<*>, adaptee: IrFunction, type: IrSimpleType, boundDispatchReceiver: IrExpression?, @@ -172,6 +172,7 @@ internal class AdapterGenerator( ): IrSimpleFunction { val returnType = type.arguments.last().typeOrNull!! val parameterTypes = type.arguments.dropLast(1).map { it.typeOrNull!! } + val firMemberAdaptee = firAdaptee as FirMemberDeclaration return irFactory.createFunction( startOffset, endOffset, IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE, @@ -180,13 +181,13 @@ internal class AdapterGenerator( DescriptorVisibilities.LOCAL, Modality.FINAL, returnType, - isInline = firAdaptee.isInline, - isExternal = firAdaptee.isExternal, - isTailrec = firAdaptee.isTailRec, - isSuspend = firAdaptee.isSuspend || type.isSuspendFunction(), - isOperator = firAdaptee.isOperator, - isInfix = firAdaptee.isInfix, - isExpect = firAdaptee.isExpect, + isInline = firMemberAdaptee.isInline, + isExternal = firMemberAdaptee.isExternal, + isTailrec = firMemberAdaptee.isTailRec, + isSuspend = firMemberAdaptee.isSuspend || type.isSuspendFunction(), + isOperator = firMemberAdaptee.isOperator, + isInfix = firMemberAdaptee.isInfix, + isExpect = firMemberAdaptee.isExpect, isFakeOverride = false ).also { irAdapterFunction -> irAdapterFunction.metadata = FirMetadataSource.Function(firAdaptee) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 77205c24102..4e98df5a288 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -122,16 +122,6 @@ class CallAndReferenceGenerator( origin ) } - is IrConstructorSymbol -> { - val constructor = symbol.owner - val klass = constructor.parent as? IrClass - IrFunctionReferenceImpl( - startOffset, endOffset, type, symbol, - typeArgumentsCount = constructor.typeParameters.size + (klass?.typeParameters?.size ?: 0), - valueArgumentsCount = constructor.valueParameters.size, - reflectionTarget = symbol - ) - } is IrFunctionSymbol -> { assert(type.isFunctionTypeOrSubtype()) { "Callable reference whose symbol refers to a function should be of functional type." @@ -144,9 +134,12 @@ class CallAndReferenceGenerator( generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType) } } else { + val klass = function.parent as? IrClass + val typeArgumentCount = function.typeParameters.size + + if (function is IrConstructor) klass?.typeParameters?.size ?: 0 else 0 IrFunctionReferenceImpl( startOffset, endOffset, type, symbol, - typeArgumentsCount = function.typeParameters.size, + typeArgumentsCount = typeArgumentCount, valueArgumentsCount = function.valueParameters.size, reflectionTarget = symbol ) diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferences.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferences.kt index 3d1f52642a1..893eefb0a03 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferences.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferences.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME import kotlin.reflect.KCallable diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferencesWithSuspendConversion.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferencesWithSuspendConversion.kt index 4a4f2e8f344..e9deaa41c8a 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferencesWithSuspendConversion.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/noReflectionForAdaptedCallableReferencesWithSuspendConversion.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +SuspendConversion // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME import kotlin.reflect.KCallable diff --git a/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.kt.txt b/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.kt.txt index d4ac82252f5..f0d6fc7435b 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.kt.txt @@ -30,13 +30,29 @@ class Outer { } fun testConstructor(): Any { - return use(fn = C::) + return use(fn = local fun (p0: Int): C { + return C(xs = [p0]) + } +) } fun testInnerClassConstructor(outer: Outer): Any { - return use(fn = outer::) + return use(fn = { // BLOCK + local fun Outer.(p0: Int): Inner { + return receiver.Inner(xs = [p0]) + } + + outer:: + }) } fun testInnerClassConstructorCapturingOuter(): Any { - return use(fn = Outer()::) + return use(fn = { // BLOCK + local fun Outer.(p0: Int): Inner { + return receiver.Inner(xs = [p0]) + } + + Outer():: + }) } + diff --git a/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt index 22d99c69903..82ebbb6d5a9 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/constructorWithAdaptedArguments.fir.txt @@ -70,17 +70,44 @@ FILE fqName: fileName:/constructorWithAdaptedArguments.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun testConstructor (): kotlin.Any declared in ' CALL 'public final fun use (fn: kotlin.Function1): kotlin.Any declared in ' type=kotlin.Any origin=null - fn: FUNCTION_REFERENCE 'public constructor (vararg xs: kotlin.Int) [primary] declared in .C' type=kotlin.reflect.KFunction1.C> origin=null reflectionTarget= + fn: FUN_EXPR type=kotlin.Function1.C> origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name: visibility:local modality:FINAL <> (p0:kotlin.Int) returnType:.C + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (p0: kotlin.Int): .C declared in .testConstructor' + CONSTRUCTOR_CALL 'public constructor (vararg xs: kotlin.Int) [primary] declared in .C' type=.C origin=null + xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int + GET_VAR 'p0: kotlin.Int declared in .testConstructor.' type=kotlin.Int origin=null FUN name:testInnerClassConstructor visibility:public modality:FINAL <> (outer:.Outer) returnType:kotlin.Any VALUE_PARAMETER name:outer index:0 type:.Outer BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructor (outer: .Outer): kotlin.Any declared in ' CALL 'public final fun use (fn: kotlin.Function1): kotlin.Any declared in ' type=kotlin.Any origin=null - fn: FUNCTION_REFERENCE 'public constructor (vararg xs: kotlin.Int) [primary] declared in .Outer.Inner' type=kotlin.reflect.KFunction1.Outer.Inner> origin=null reflectionTarget= - $this: GET_VAR 'outer: .Outer declared in .testInnerClassConstructor' type=.Outer origin=null + fn: BLOCK type=kotlin.Function1.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name: visibility:local modality:FINAL <> ($receiver:.Outer, p0:kotlin.Int) returnType:.Outer.Inner + $receiver: VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:receiver type:.Outer + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (p0: kotlin.Int): .Outer.Inner declared in .testInnerClassConstructor' + CONSTRUCTOR_CALL 'public constructor (vararg xs: kotlin.Int) [primary] declared in .Outer.Inner' type=.Outer.Inner origin=null + $outer: GET_VAR 'receiver: .Outer declared in .testInnerClassConstructor.' type=.Outer origin=ADAPTED_FUNCTION_REFERENCE + xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int + GET_VAR 'p0: kotlin.Int declared in .testInnerClassConstructor.' type=kotlin.Int origin=null + FUNCTION_REFERENCE 'local final fun (p0: kotlin.Int): .Outer.Inner declared in .testInnerClassConstructor' type=kotlin.Function1.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=null + $receiver: GET_VAR 'outer: .Outer declared in .testInnerClassConstructor' type=.Outer origin=null FUN name:testInnerClassConstructorCapturingOuter visibility:public modality:FINAL <> () returnType:kotlin.Any BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun testInnerClassConstructorCapturingOuter (): kotlin.Any declared in ' CALL 'public final fun use (fn: kotlin.Function1): kotlin.Any declared in ' type=kotlin.Any origin=null - fn: FUNCTION_REFERENCE 'public constructor (vararg xs: kotlin.Int) [primary] declared in .Outer.Inner' type=kotlin.reflect.KFunction1.Outer.Inner> origin=null reflectionTarget= - $this: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Outer' type=.Outer origin=null + fn: BLOCK type=kotlin.Function1.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name: visibility:local modality:FINAL <> ($receiver:.Outer, p0:kotlin.Int) returnType:.Outer.Inner + $receiver: VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:receiver type:.Outer + VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (p0: kotlin.Int): .Outer.Inner declared in .testInnerClassConstructorCapturingOuter' + CONSTRUCTOR_CALL 'public constructor (vararg xs: kotlin.Int) [primary] declared in .Outer.Inner' type=.Outer.Inner origin=null + $outer: GET_VAR 'receiver: .Outer declared in .testInnerClassConstructorCapturingOuter.' type=.Outer origin=ADAPTED_FUNCTION_REFERENCE + xs: VARARG type=kotlin.IntArray varargElementType=kotlin.Int + GET_VAR 'p0: kotlin.Int declared in .testInnerClassConstructorCapturingOuter.' type=kotlin.Int origin=null + FUNCTION_REFERENCE 'local final fun (p0: kotlin.Int): .Outer.Inner declared in .testInnerClassConstructorCapturingOuter' type=kotlin.Function1.Outer.Inner> origin=ADAPTED_FUNCTION_REFERENCE reflectionTarget=null + $receiver: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .Outer' type=.Outer origin=null diff --git a/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.kt.txt b/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.kt.txt index eda7defdd2c..1ee61feeda0 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.kt.txt @@ -27,5 +27,8 @@ fun testFn(): Any { } fun testCtor(): Any { - return use(fn = C::) + return use(fn = local fun (): C { + return C() + } +) } diff --git a/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.txt index 31909678561..af4140b63a2 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/kt37131.fir.txt @@ -58,4 +58,8 @@ FILE fqName: fileName:/kt37131.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public final fun testCtor (): kotlin.Any declared in ' CALL 'public final fun use (fn: kotlin.Function0): kotlin.Any declared in ' type=kotlin.Any origin=null - fn: FUNCTION_REFERENCE 'public constructor (x: kotlin.String) [primary] declared in .C' type=kotlin.reflect.KFunction0<.C> origin=null reflectionTarget= + fn: FUN_EXPR type=kotlin.Function0<.C> origin=ADAPTED_FUNCTION_REFERENCE + FUN ADAPTER_FOR_CALLABLE_REFERENCE name: visibility:local modality:FINAL <> () returnType:.C + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (): .C declared in .testCtor' + CONSTRUCTOR_CALL 'public constructor (x: kotlin.String) [primary] declared in .C' type=.C origin=null