KT-45375 Lightweight lambdas; KT-52817 introduce @JvmSerializableLambda

This commit is contained in:
Pavel Mikhailovskii
2022-07-18 09:20:55 +02:00
parent 1557f919f5
commit 846537b367
33 changed files with 243 additions and 15 deletions
@@ -1290,6 +1290,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt");
} }
@Test
@TestMetadata("JvmSerializableLambdaAnnotation.kt")
public void testJvmSerializableLambdaAnnotation() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/JvmSerializableLambdaAnnotation.kt");
}
@Test @Test
@TestMetadata("kt1860-negative.kt") @TestMetadata("kt1860-negative.kt")
public void testKt1860_negative() throws Exception { public void testKt1860_negative() throws Exception {
@@ -253,13 +253,12 @@ class GenerationState private constructor(
JvmClosureGenerationScheme.CLASS JvmClosureGenerationScheme.CLASS
} }
val lambdasScheme = run { val lambdasScheme = configuration.get(JVMConfigurationKeys.LAMBDAS).let { fromConfig ->
val fromConfig = configuration.get(JVMConfigurationKeys.LAMBDAS) if (fromConfig == null || target < fromConfig.minJvmTarget) {
?: JvmClosureGenerationScheme.DEFAULT if (languageVersionSettings.supportsFeature(LanguageFeature.LightweightLambdas) && target >= JvmClosureGenerationScheme.INDY.minJvmTarget)
if (target >= fromConfig.minJvmTarget) JvmClosureGenerationScheme.INDY
fromConfig else JvmClosureGenerationScheme.CLASS
else } else fromConfig
JvmClosureGenerationScheme.DEFAULT
} }
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module) val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
@@ -16,8 +16,6 @@ enum class JvmClosureGenerationScheme(
; ;
companion object { companion object {
val DEFAULT = CLASS
@JvmStatic @JvmStatic
fun fromString(string: String?): JvmClosureGenerationScheme? { fun fromString(string: String?): JvmClosureGenerationScheme? {
val lowerStr = string?.toLowerCaseAsciiOnly() ?: return null val lowerStr = string?.toLowerCaseAsciiOnly() ?: return null
@@ -1290,6 +1290,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt");
} }
@Test
@TestMetadata("JvmSerializableLambdaAnnotation.kt")
public void testJvmSerializableLambdaAnnotation() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/JvmSerializableLambdaAnnotation.kt");
}
@Test @Test
@TestMetadata("kt1860-negative.kt") @TestMetadata("kt1860-negative.kt")
public void testKt1860_negative() throws Exception { public void testKt1860_negative() throws Exception {
@@ -1290,6 +1290,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt");
} }
@Test
@TestMetadata("JvmSerializableLambdaAnnotation.kt")
public void testJvmSerializableLambdaAnnotation() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/JvmSerializableLambdaAnnotation.kt");
}
@Test @Test
@TestMetadata("kt1860-negative.kt") @TestMetadata("kt1860-negative.kt")
public void testKt1860_negative() throws Exception { public void testKt1860_negative() throws Exception {
@@ -33,5 +33,6 @@ object JvmExpressionCheckers : ExpressionCheckers() {
get() = setOf( get() = setOf(
FirJavaAnnotationsChecker, FirJavaAnnotationsChecker,
FirJvmPackageNameAnnotationsChecker, FirJvmPackageNameAnnotationsChecker,
FirJvmSerializableLambdaChecker,
) )
} }
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnnotationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.getActualTargetList
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.resolve.fqName
import org.jetbrains.kotlin.name.FqName
object FirJvmSerializableLambdaChecker : FirAnnotationChecker() {
private val JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSerializableLambda")
override fun check(expression: FirAnnotation, context: CheckerContext, reporter: DiagnosticReporter) {
if (expression.fqName(context.session) == JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME) {
val declaration = context.containingDeclarations.last()
if (declaration !is FirAnonymousFunction) {
val actualTargets = getActualTargetList(declaration)
val targetDescription = actualTargets.defaultTargets.firstOrNull()?.description ?: "unidentified target"
reporter.reportOn(
expression.source,
FirErrors.WRONG_ANNOTATION_TARGET,
targetDescription,
context
)
}
}
}
}
@@ -26346,6 +26346,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/invokedynamic/lambdas/genericLambdaSignature.kt"); runTest("compiler/testData/codegen/box/invokedynamic/lambdas/genericLambdaSignature.kt");
} }
@Test
@TestMetadata("jvmSerializableLambda.kt")
public void testJvmSerializableLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/lambdas/jvmSerializableLambda.kt");
}
@Test @Test
@TestMetadata("kt52875.kt") @TestMetadata("kt52875.kt")
public void testKt52875() throws Exception { public void testKt52875() throws Exception {
@@ -42140,6 +42146,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/lambdaClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/lambdaClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("lightweightLambdas.kt")
public void testLightweightLambdas() throws Exception {
runTest("compiler/testData/codegen/box/reflection/lambdaClasses/lightweightLambdas.kt");
}
@Test @Test
@TestMetadata("parameterNamesAndNullability.kt") @TestMetadata("parameterNamesAndNullability.kt")
public void testParameterNamesAndNullability() throws Exception { public void testParameterNamesAndNullability() throws Exception {
@@ -38,6 +38,9 @@ val VOLATILE_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.Volatile")
@JvmField @JvmField
val TRANSIENT_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.Transient") val TRANSIENT_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.Transient")
@JvmField
val JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSerializableLambda")
fun DeclarationDescriptor.findJvmOverloadsAnnotation(): AnnotationDescriptor? = fun DeclarationDescriptor.findJvmOverloadsAnnotation(): AnnotationDescriptor? =
annotations.findAnnotation(JVM_OVERLOADS_FQ_NAME) annotations.findAnnotation(JVM_OVERLOADS_FQ_NAME)
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.jvm.checkers
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
import org.jetbrains.kotlin.resolve.BindingContext.ANNOTATION
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME
object JvmSerializableLambdaAnnotationChecker : AdditionalAnnotationChecker {
override fun checkEntries(
entries: List<KtAnnotationEntry>,
actualTargets: List<KotlinTarget>,
trace: BindingTrace,
annotated: KtAnnotated?,
languageVersionSettings: LanguageVersionSettings
) {
entries.find { trace.get(ANNOTATION, it)?.fqName == JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME }?.let {
if (!actualTargets.contains(KotlinTarget.LAMBDA_EXPRESSION) && !actualTargets.contains(KotlinTarget.ANONYMOUS_FUNCTION)) {
trace.report(
Errors.WRONG_ANNOTATION_TARGET.on(it, actualTargets.firstOrNull()?.description ?: "unidentified target")
)
}
}
}
}
@@ -119,6 +119,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
container.useInstance(FunctionWithBigAritySupport.LanguageVersionDependent) container.useInstance(FunctionWithBigAritySupport.LanguageVersionDependent)
container.useInstance(GenericArrayClassLiteralSupport.Enabled) container.useInstance(GenericArrayClassLiteralSupport.Enabled)
container.useInstance(JavaActualAnnotationArgumentExtractor()) container.useInstance(JavaActualAnnotationArgumentExtractor())
container.useInstance(JvmSerializableLambdaAnnotationChecker)
} }
override fun configureModuleDependentCheckers(container: StorageComponentContainer) { override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
internal val functionReferencePhase = makeIrFilePhase( internal val functionReferencePhase = makeIrFilePhase(
@@ -76,6 +77,9 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
private val shouldGenerateIndyLambdas = private val shouldGenerateIndyLambdas =
context.state.lambdasScheme == JvmClosureGenerationScheme.INDY context.state.lambdasScheme == JvmClosureGenerationScheme.INDY
private val shouldGenerateLightweightLambdas =
shouldGenerateIndyLambdas && context.state.languageVersionSettings.supportsFeature(LanguageFeature.LightweightLambdas)
private val isJavaSamConversionWithEqualsHashCode = private val isJavaSamConversionWithEqualsHashCode =
context.state.languageVersionSettings.supportsFeature(LanguageFeature.JavaSamConversionEqualsHashCode) context.state.languageVersionSettings.supportsFeature(LanguageFeature.JavaSamConversionEqualsHashCode)
@@ -525,7 +529,10 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
private inner class FunctionReferenceBuilder(val irFunctionReference: IrFunctionReference, val samSuperType: IrType? = null) { private inner class FunctionReferenceBuilder(val irFunctionReference: IrFunctionReference, val samSuperType: IrType? = null) {
private val isLambda = irFunctionReference.origin.isLambda private val isLambda = irFunctionReference.origin.isLambda
private val isLightweightLambda = isLambda
&& shouldGenerateLightweightLambdas
&& !irFunctionReference.symbol.owner.hasAnnotation(JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME)
private val isHeavyweightLambda = isLambda && !isLightweightLambda
private val callee = irFunctionReference.symbol.owner private val callee = irFunctionReference.symbol.owner
// Only function references can bind a receiver and even then we can only bind either an extension or a dispatch receiver. // Only function references can bind a receiver and even then we can only bind either an extension or a dispatch receiver.
@@ -605,7 +612,8 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
private val superType = private val superType =
samSuperType samSuperType
?: when { ?: when {
isLambda -> context.ir.symbols.lambdaClass isLightweightLambda -> context.ir.symbols.any
isHeavyweightLambda -> context.ir.symbols.lambdaClass
isFunInterfaceConstructorReference -> context.ir.symbols.funInterfaceConstructorReferenceClass isFunInterfaceConstructorReference -> context.ir.symbols.funInterfaceConstructorReferenceClass
useOptimizedSuperClass -> when { useOptimizedSuperClass -> when {
isAdaptedReference -> context.ir.symbols.adaptedFunctionReference isAdaptedReference -> context.ir.symbols.adaptedFunctionReference
@@ -642,7 +650,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
} }
createImplicitParameterDeclarationWithWrappedDescriptor() createImplicitParameterDeclarationWithWrappedDescriptor()
copyAttributes(irFunctionReference) copyAttributes(irFunctionReference)
if (isLambda) { if (!isLightweightLambda) {
metadata = irFunctionReference.symbol.owner.metadata metadata = irFunctionReference.symbol.owner.metadata
} }
} }
@@ -773,7 +781,8 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
context.irBuiltIns.anyClass.owner.constructors.single() context.irBuiltIns.anyClass.owner.constructors.single()
else -> { else -> {
val expectedArity = val expectedArity =
if (isLambda && !isAdaptedReference) 1 if (isLightweightLambda && !isAdaptedReference) 0
else if (isHeavyweightLambda && !isAdaptedReference) 1
else 1 + (if (boundReceiver != null) 1 else 0) + (if (useOptimizedSuperClass) 4 else 0) else 1 + (if (boundReceiver != null) 1 else 0) + (if (useOptimizedSuperClass) 4 else 0)
superType.getClass()!!.constructors.single { superType.getClass()!!.constructors.single {
it.valueParameters.size == expectedArity it.valueParameters.size == expectedArity
@@ -803,7 +812,9 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
call.putValueArgument(0, funInterfaceJavaClassRef) call.putValueArgument(0, funInterfaceJavaClassRef)
} else { } else {
var index = 0 var index = 0
call.putValueArgument(index++, irInt(argumentTypes.size + if (irFunctionReference.isSuspend) 1 else 0)) if (!isLightweightLambda) {
call.putValueArgument(index++, irInt(argumentTypes.size + if (irFunctionReference.isSuspend) 1 else 0))
}
if (boundReceiver != null) { if (boundReceiver != null) {
call.putValueArgument(index++, generateBoundReceiver()) call.putValueArgument(index++, generateBoundReceiver())
} }
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// IGNORE_BACKEND: WASM // IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS // WASM_MUTE_REASON: IGNORED_IN_JS
// IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// IGNORE_BACKEND: WASM // IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS // WASM_MUTE_REASON: IGNORED_IN_JS
// IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR
@@ -0,0 +1,13 @@
// LANGUAGE: +LightweightLambdas
// TARGET_BACKEND: JVM_IR
// JVM_TARGET: 1.8
// FULL_JDK
// WITH_STDLIB
import kotlin.test.assertTrue
fun box(): String {
assertTrue((@kotlin.jvm.JvmSerializableLambda {}) is java.io.Serializable)
return "OK"
}
@@ -0,0 +1,21 @@
// LANGUAGE: +LightweightLambdas
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM_IR
// JVM_TARGET: 1.8
// WITH_REFLECT
import kotlin.reflect.jvm.reflect
import kotlin.test.*
import kotlin.jvm.JvmSerializableLambda
fun box(): String {
assertNull({}.reflect())
assertNull((fun () {}).reflect())
assertNull((fun Any.() {}).reflect())
assertNotNull((@JvmSerializableLambda {}).reflect())
assertNotNull((@JvmSerializableLambda fun () {}).reflect())
assertNotNull((@JvmSerializableLambda fun Any.() {}).reflect())
return "OK"
}
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -1,3 +1,4 @@
// LAMBDAS: CLASS
// !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas // !OPT_IN: kotlin.reflect.jvm.ExperimentalReflectionOnLambdas
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_REFLECT // WITH_REFLECT
@@ -0,0 +1,17 @@
// LAMBDAS: INDY
// FIR_IDENTICAL
// WITH_STDLIB
import kotlin.jvm.JvmSerializableLambda
fun foo() = fun () {}
val good1 = @JvmSerializableLambda {}
val good2 = @JvmSerializableLambda fun () {}
val good3 = @JvmSerializableLambda fun Any.() {}
val good4 = listOf(@JvmSerializableLambda {})[0]
val bad1 = <!WRONG_ANNOTATION_TARGET!>@JvmSerializableLambda<!> 1
val bad2 = <!WRONG_ANNOTATION_TARGET!>@JvmSerializableLambda<!> object {}
val bad3 = <!WRONG_ANNOTATION_TARGET!>@JvmSerializableLambda<!> ::foo
val bad4 = listOf(<!WRONG_ANNOTATION_TARGET!>@JvmSerializableLambda<!> 1)[0]
@@ -0,0 +1,11 @@
package
public val bad1: kotlin.Int
public val bad2: kotlin.Any
public val bad3: kotlin.reflect.KFunction0<() -> kotlin.Unit>
public val bad4: kotlin.Int
public val good1: () -> kotlin.Unit
public val good2: () -> kotlin.Unit
public val good3: kotlin.Any.() -> kotlin.Unit
public val good4: () -> kotlin.Unit
public fun foo(): () -> kotlin.Unit
@@ -1296,6 +1296,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt"); runTest("compiler/testData/diagnostics/tests/annotations/javaAnnotationWithClassArray.kt");
} }
@Test
@TestMetadata("JvmSerializableLambdaAnnotation.kt")
public void testJvmSerializableLambdaAnnotation() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/JvmSerializableLambdaAnnotation.kt");
}
@Test @Test
@TestMetadata("kt1860-negative.kt") @TestMetadata("kt1860-negative.kt")
public void testKt1860_negative() throws Exception { public void testKt1860_negative() throws Exception {
@@ -26346,6 +26346,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/invokedynamic/lambdas/genericLambdaSignature.kt"); runTest("compiler/testData/codegen/box/invokedynamic/lambdas/genericLambdaSignature.kt");
} }
@Test
@TestMetadata("jvmSerializableLambda.kt")
public void testJvmSerializableLambda() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/lambdas/jvmSerializableLambda.kt");
}
@Test @Test
@TestMetadata("kt52875.kt") @TestMetadata("kt52875.kt")
public void testKt52875() throws Exception { public void testKt52875() throws Exception {
@@ -42140,6 +42146,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/lambdaClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/lambdaClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("lightweightLambdas.kt")
public void testLightweightLambdas() throws Exception {
runTest("compiler/testData/codegen/box/reflection/lambdaClasses/lightweightLambdas.kt");
}
@Test @Test
@TestMetadata("parameterNamesAndNullability.kt") @TestMetadata("parameterNamesAndNullability.kt")
public void testParameterNamesAndNullability() throws Exception { public void testParameterNamesAndNullability() throws Exception {
@@ -264,6 +264,7 @@ enum class LanguageFeature(
RangeUntilOperator(KOTLIN_1_8), // KT-15613 RangeUntilOperator(KOTLIN_1_8), // KT-15613
GenericInlineClassParameter(sinceVersion = KOTLIN_1_8, kind = UNSTABLE_FEATURE), // KT-32162 GenericInlineClassParameter(sinceVersion = KOTLIN_1_8, kind = UNSTABLE_FEATURE), // KT-32162
DataObjects(KOTLIN_1_8), // KT-4107 DataObjects(KOTLIN_1_8), // KT-4107
LightweightLambdas(KOTLIN_1_8, defaultState = State.DISABLED),
// 1.9 // 1.9
@@ -166,3 +166,13 @@ public expect annotation class Synchronized()
@SinceKotlin("1.2") @SinceKotlin("1.2")
@OptionalExpectation @OptionalExpectation
internal expect annotation class JvmPackageName(val name: String) internal expect annotation class JvmPackageName(val name: String)
/**
* Makes the annotated lambda function `java.io.Serializable`, generates a pretty `toString` implementation and adds reflection metadata.
*/
@Target(EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@SinceKotlin("1.8")
@OptionalExpectation
public expect annotation class JvmSerializableLambda
@@ -44,3 +44,12 @@ public actual annotation class Strictfp
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
@MustBeDocumented @MustBeDocumented
public actual annotation class Synchronized public actual annotation class Synchronized
/**
* Makes the annotated lambda function implement `java.io.Serializable`,
* generates a pretty `toString` implementation and adds reflection metadata.
*/
@Target(EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@SinceKotlin("1.8")
public actual annotation class JvmSerializableLambda
@@ -3309,6 +3309,9 @@ public abstract interface annotation class kotlin/jvm/JvmOverloads : java/lang/a
public abstract interface annotation class kotlin/jvm/JvmRecord : java/lang/annotation/Annotation { public abstract interface annotation class kotlin/jvm/JvmRecord : java/lang/annotation/Annotation {
} }
public abstract interface annotation class kotlin/jvm/JvmSerializableLambda : java/lang/annotation/Annotation {
}
public abstract interface annotation class kotlin/jvm/JvmStatic : java/lang/annotation/Annotation { public abstract interface annotation class kotlin/jvm/JvmStatic : java/lang/annotation/Annotation {
} }