Fix function invocation mangling rule

Mangle invocations of functions with value classes in signature which
override (directly or indirectly) a method declared in Kotlin code.
Otherwise, NoSuchMethodError is being thrown.

^KT-55945: Fixed
This commit is contained in:
vladislav.grechko
2023-02-07 20:59:30 +01:00
committed by Space Team
parent f80ed4592d
commit 457837a255
29 changed files with 744 additions and 4 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.extensionReceiverName
import org.jetbrains.kotlin.backend.jvm.ir.isStaticValueClassReplacement
import org.jetbrains.kotlin.backend.jvm.ir.parentClassId
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrBuiltIns
@@ -36,6 +37,9 @@ class MemoizedInlineClassReplacements(
val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
val originalFunctionForMethodReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
private val mangleCallsToJavaMethodsWithValueClasses =
context.state.languageVersionSettings.supportsFeature(LanguageFeature.MangleCallsToJavaMethodsWithValueClasses)
/**
* Get a replacement for a function or a constructor.
*/
@@ -76,15 +80,20 @@ class MemoizedInlineClassReplacements(
}
// Otherwise, mangle functions with mangled parameters, ignoring constructors
it is IrSimpleFunction && !it.isFromJava() &&
(it.hasMangledParameters(includeMFVC = false) || mangleReturnTypes && it.hasMangledReturnType) ->
createMethodReplacement(it)
it is IrSimpleFunction && it.needsReplacement -> createMethodReplacement(it)
else ->
null
}
}
private val IrSimpleFunction.needsReplacement: Boolean
get() {
if (!hasMangledParameters(includeMFVC = false) && !(mangleReturnTypes && hasMangledReturnType)) return false
if (isFromJava()) return mangleCallsToJavaMethodsWithValueClasses && !overridesOnlyMethodsFromJava()
return true
}
/**
* Get the box function for an inline class. Concretely, this is a synthetic
* static function named "box-impl" which takes an unboxed value and returns
@@ -277,7 +277,10 @@ class MemoizedMultiFieldValueClassReplacements(
createStaticReplacement(function)
}
function is IrSimpleFunction && !function.isFromJava() && function.fullValueParameterList.any { it.type.needsMfvcFlattening() } && run {
function is IrSimpleFunction
&& !(function.isFromJava() && function.overridesOnlyMethodsFromJava())
&& function.fullValueParameterList.any { it.type.needsMfvcFlattening() }
&& run {
if (!function.isFakeOverride) return@run true
val superDeclaration = findSuperDeclaration(function, false, context.state.jvmDefaultMode)
getReplacementFunction(superDeclaration) != null
@@ -137,4 +137,6 @@ abstract class MemoizedValueClassAbstractReplacements(
getReplacementFunction(function) ?: function.also {
function.overriddenSymbols = replaceOverriddenSymbols(function)
}
protected fun IrSimpleFunction.overridesOnlyMethodsFromJava(): Boolean = allOverridden().all { it.isFromJava() }
}