diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index cc5e6762377..fd9cd7f441c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -89,6 +89,7 @@ open class ClassCodegen protected constructor( when (val metadata = irClass.metadata) { is MetadataSource.Class -> DescriptorSerializer.create(metadata.descriptor, serializerExtension, parentClassCodegen?.serializer) is MetadataSource.File -> DescriptorSerializer.createTopLevel(serializerExtension) + is MetadataSource.Function -> DescriptorSerializer.createForLambda(serializerExtension) else -> null } @@ -239,6 +240,15 @@ open class ClassCodegen protected constructor( } } } + is MetadataSource.Function -> { + val fakeDescriptor = createFreeFakeLambdaDescriptor(metadata.descriptor) + val functionProto = serializer!!.functionProto(fakeDescriptor)?.build() + writeKotlinMetadata(visitor, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { + if (functionProto != null) { + AsmUtil.writeAnnotationData(it, serializer, functionProto) + } + } + } else -> { val entry = irClass.fileParent.fileEntry if (entry is MultifileFacadeFileEntry) { 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 fc35c051829..babd9ad3cb6 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 @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.* import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl @@ -144,6 +145,9 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext) if (irFunctionReference.isSuspend) superTypes += context.ir.symbols.suspendFunctionInterface.defaultType createImplicitParameterDeclarationWithWrappedDescriptor() copyAttributes(irFunctionReference) + if (isLambda) { + (this as IrClassImpl).metadata = irFunctionReference.symbol.owner.metadata + } } private val receiverFieldFromSuper = context.ir.symbols.functionReferenceReceiverField.owner diff --git a/compiler/testData/codegen/box/functions/functionNtoString.kt b/compiler/testData/codegen/box/functions/functionNtoString.kt index 008561d6e1c..9b56ddc7978 100644 --- a/compiler/testData/codegen/box/functions/functionNtoString.kt +++ b/compiler/testData/codegen/box/functions/functionNtoString.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/functions/functionNtoStringGeneric.kt b/compiler/testData/codegen/box/functions/functionNtoStringGeneric.kt index 8662943ba63..723cc2b0c0f 100644 --- a/compiler/testData/codegen/box/functions/functionNtoStringGeneric.kt +++ b/compiler/testData/codegen/box/functions/functionNtoStringGeneric.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt b/compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt index 59c50616846..7dd88ebfb82 100644 --- a/compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt +++ b/compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInField.kt b/compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInField.kt new file mode 100644 index 00000000000..c22c2c2db51 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInField.kt @@ -0,0 +1,13 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// WITH_REFLECT + +import kotlin.reflect.jvm.reflect + +class C { + val x = { OK: String -> } +} + +fun box(): String { + return C().x.reflect()?.parameters?.singleOrNull()?.name ?: "null" +} diff --git a/compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInStaticField.kt b/compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInStaticField.kt new file mode 100644 index 00000000000..07ecec98cc4 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInStaticField.kt @@ -0,0 +1,12 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JVM_IR +// TARGET_BACKEND: JVM +// WITH_REFLECT + +import kotlin.reflect.jvm.reflect + +val x = { OK: String -> } + +fun box(): String { + return x.reflect()?.parameters?.singleOrNull()?.name ?: "null" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index af90f56610d..c5f3d2e5086 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -23648,6 +23648,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testParameterNamesAndNullability() throws Exception { runTest("compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt"); } + + @TestMetadata("reflectOnLambdaInField.kt") + public void testReflectOnLambdaInField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInField.kt"); + } + + @TestMetadata("reflectOnLambdaInStaticField.kt") + public void testReflectOnLambdaInStaticField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInStaticField.kt"); + } } @TestMetadata("compiler/testData/codegen/box/reflection/mapping") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 120b1febeca..22b5647041e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -22465,6 +22465,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testParameterNamesAndNullability() throws Exception { runTest("compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt"); } + + @TestMetadata("reflectOnLambdaInField.kt") + public void testReflectOnLambdaInField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInField.kt"); + } + + @TestMetadata("reflectOnLambdaInStaticField.kt") + public void testReflectOnLambdaInStaticField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInStaticField.kt"); + } } @TestMetadata("compiler/testData/codegen/box/reflection/mapping") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index dcc14d0dd13..b99f3ae3b5c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -22137,6 +22137,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testParameterNamesAndNullability() throws Exception { runTest("compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt"); } + + @TestMetadata("reflectOnLambdaInField.kt") + public void testReflectOnLambdaInField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInField.kt"); + } + + @TestMetadata("reflectOnLambdaInStaticField.kt") + public void testReflectOnLambdaInStaticField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInStaticField.kt"); + } } @TestMetadata("compiler/testData/codegen/box/reflection/mapping") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index c5b47522f83..6e3e6c44ebc 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -22137,6 +22137,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testParameterNamesAndNullability() throws Exception { runTest("compiler/testData/codegen/box/reflection/lambdaClasses/parameterNamesAndNullability.kt"); } + + @TestMetadata("reflectOnLambdaInField.kt") + public void testReflectOnLambdaInField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInField.kt"); + } + + @TestMetadata("reflectOnLambdaInStaticField.kt") + public void testReflectOnLambdaInStaticField() throws Exception { + runTest("compiler/testData/codegen/box/reflection/lambdaClasses/reflectOnLambdaInStaticField.kt"); + } } @TestMetadata("compiler/testData/codegen/box/reflection/mapping")