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
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.Name
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
internal val functionReferencePhase = makeIrFilePhase(
@@ -76,6 +77,9 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
private val shouldGenerateIndyLambdas =
context.state.lambdasScheme == JvmClosureGenerationScheme.INDY
private val shouldGenerateLightweightLambdas =
shouldGenerateIndyLambdas && context.state.languageVersionSettings.supportsFeature(LanguageFeature.LightweightLambdas)
private val isJavaSamConversionWithEqualsHashCode =
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 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
// 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 =
samSuperType
?: when {
isLambda -> context.ir.symbols.lambdaClass
isLightweightLambda -> context.ir.symbols.any
isHeavyweightLambda -> context.ir.symbols.lambdaClass
isFunInterfaceConstructorReference -> context.ir.symbols.funInterfaceConstructorReferenceClass
useOptimizedSuperClass -> when {
isAdaptedReference -> context.ir.symbols.adaptedFunctionReference
@@ -642,7 +650,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
}
createImplicitParameterDeclarationWithWrappedDescriptor()
copyAttributes(irFunctionReference)
if (isLambda) {
if (!isLightweightLambda) {
metadata = irFunctionReference.symbol.owner.metadata
}
}
@@ -773,7 +781,8 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
context.irBuiltIns.anyClass.owner.constructors.single()
else -> {
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)
superType.getClass()!!.constructors.single {
it.valueParameters.size == expectedArity
@@ -803,7 +812,9 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
call.putValueArgument(0, funInterfaceJavaClassRef)
} else {
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) {
call.putValueArgument(index++, generateBoundReceiver())
}