JVM_IR JavaSamConversionEqualsHashCode
This commit is contained in:
+7
-2
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.indy.*
|
||||
import org.jetbrains.kotlin.config.JvmClosureGenerationScheme
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -75,6 +76,9 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
private val shouldGenerateIndyLambdas =
|
||||
context.state.lambdasScheme == JvmClosureGenerationScheme.INDY
|
||||
|
||||
private val isJavaSamConversionWithEqualsHashCode =
|
||||
context.state.languageVersionSettings.supportsFeature(LanguageFeature.JavaSamConversionEqualsHashCode)
|
||||
|
||||
override fun visitBlock(expression: IrBlock): IrExpression {
|
||||
if (!expression.origin.isLambda)
|
||||
return super.visitBlock(expression)
|
||||
@@ -444,7 +448,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
private fun canGenerateIndySamConversionOnFunctionalExpression(samSuperType: IrType, expression: IrExpression): Boolean {
|
||||
val samClass = samSuperType.classOrNull
|
||||
?: throw AssertionError("Class type expected: ${samSuperType.render()}")
|
||||
if (!samClass.owner.isFromJava())
|
||||
if (!samClass.owner.isFromJava() || isJavaSamConversionWithEqualsHashCode)
|
||||
return false
|
||||
if (expression is IrBlock && expression.origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE)
|
||||
return false
|
||||
@@ -595,7 +599,8 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
private val isKotlinFunInterface = samInterface != null && !samInterface.isFromJava()
|
||||
|
||||
private val needToGenerateSamEqualsHashCodeMethods =
|
||||
isKotlinFunInterface && (isAdaptedReference || !isLambda)
|
||||
(isKotlinFunInterface || isJavaSamConversionWithEqualsHashCode) &&
|
||||
(isAdaptedReference || !isLambda)
|
||||
|
||||
private val superType =
|
||||
samSuperType
|
||||
|
||||
+7
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInPublicInlineScope
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.rawType
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -34,6 +35,10 @@ internal val singleAbstractMethodPhase = makeIrFilePhase(
|
||||
)
|
||||
|
||||
private class JvmSingleAbstractMethodLowering(context: JvmBackendContext) : SingleAbstractMethodLowering(context) {
|
||||
|
||||
private val isJavaSamConversionWithEqualsHashCode =
|
||||
context.state.languageVersionSettings.supportsFeature(LanguageFeature.JavaSamConversionEqualsHashCode)
|
||||
|
||||
override val inInlineFunctionScope: Boolean
|
||||
get() = allScopes.any { it.irElement.safeAs<IrDeclaration>()?.isInPublicInlineScope == true }
|
||||
|
||||
@@ -56,5 +61,6 @@ private class JvmSingleAbstractMethodLowering(context: JvmBackendContext) : Sing
|
||||
private val IrType.isKotlinFunInterface: Boolean
|
||||
get() = getClass()?.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
||||
|
||||
override val IrType.needEqualsHashCodeMethods get() = isKotlinFunInterface
|
||||
override val IrType.needEqualsHashCodeMethods
|
||||
get() = isKotlinFunInterface || isJavaSamConversionWithEqualsHashCode
|
||||
}
|
||||
|
||||
+7
-4
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.getSingleAbstractMethod
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.findInterfaceImplementation
|
||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||
@@ -80,6 +81,10 @@ internal class LambdaMetafactoryArgumentsBuilder(
|
||||
private val context: JvmBackendContext,
|
||||
private val crossinlineLambdas: Set<IrSimpleFunction>
|
||||
) {
|
||||
|
||||
private val isJavaSamConversionWithEqualsHashCode =
|
||||
context.state.languageVersionSettings.supportsFeature(LanguageFeature.JavaSamConversionEqualsHashCode)
|
||||
|
||||
/**
|
||||
* @see java.lang.invoke.LambdaMetafactory
|
||||
*/
|
||||
@@ -99,12 +104,10 @@ internal class LambdaMetafactoryArgumentsBuilder(
|
||||
|
||||
// Can't use JDK LambdaMetafactory for function references by default (because of 'equals').
|
||||
// TODO special mode that would generate indy everywhere?
|
||||
if (!reference.origin.isLambda && !samClass.isFromJava()) {
|
||||
if (!reference.origin.isLambda && (!samClass.isFromJava() || isJavaSamConversionWithEqualsHashCode)) {
|
||||
semanticsHazard = true
|
||||
}
|
||||
|
||||
// Don't use JDK LambdaMetafactory for serializable lambdas
|
||||
// TODO implement support for serializable lambdas with LambdaMetafactory (requires additional code for deserialization)
|
||||
if (samClass.isInheritedFromSerializable()) {
|
||||
shouldBeSerializable = true
|
||||
}
|
||||
@@ -133,7 +136,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
|
||||
functionHazard = true
|
||||
}
|
||||
|
||||
// Can't use invokedynamic if the referenced function has to be inlined for correct semantics
|
||||
// Can't use invokedynamic if the referenced function has to be inlined for correct semantics.
|
||||
// Also in some cases like `private inline fun` we'd need accessors, which `SyntheticAccessorLowering`
|
||||
// won't generate under the assumption that the inline function will be inlined. Plus if the function
|
||||
// is in a different module we should probably copy it anyway (and regenerate all objects in it).
|
||||
|
||||
Reference in New Issue
Block a user