KT-45375 Lightweight lambdas; KT-52817 introduce @JvmSerializableLambda
This commit is contained in:
+6
@@ -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
|
||||||
|
|||||||
+6
@@ -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 {
|
||||||
|
|||||||
+6
@@ -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 {
|
||||||
|
|||||||
+1
@@ -33,5 +33,6 @@ object JvmExpressionCheckers : ExpressionCheckers() {
|
|||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirJavaAnnotationsChecker,
|
FirJavaAnnotationsChecker,
|
||||||
FirJvmPackageNameAnnotationsChecker,
|
FirJvmPackageNameAnnotationsChecker,
|
||||||
|
FirJvmSerializableLambdaChecker,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+37
@@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -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 {
|
||||||
|
|||||||
+3
@@ -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)
|
||||||
|
|
||||||
|
|||||||
+34
@@ -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")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
@@ -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) {
|
||||||
|
|||||||
+16
-5
@@ -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
@@ -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
|
||||||
|
|||||||
Vendored
+1
@@ -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
|
||||||
|
|||||||
Vendored
+1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
+17
@@ -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]
|
||||||
+11
@@ -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
|
||||||
Generated
+6
@@ -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 {
|
||||||
|
|||||||
+12
@@ -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
|
||||||
+3
@@ -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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user