JVM IR: Fix signature mapping for inline classes using new mangling
When resolving inline class methods in binary dependencies we look for methods matching both the new and the old mangling scheme. On the IR backend the method signature has to be computed for the inline class replacement, since the logic for signature mangling is not contained in the method signature mapping, unlike in the old backend.
This commit is contained in:
committed by
Ilmir Usmanov
parent
91717cdcdd
commit
9c4f8f7e54
+5
@@ -165,6 +165,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineFunctionCall.kt")
|
||||
public void testInlineClassInlineFunctionCall() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineFunctionCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineProperty.kt")
|
||||
public void testInlineClassInlineProperty() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineProperty.kt");
|
||||
|
||||
+2
-3
@@ -382,14 +382,13 @@ val IrMemberAccessExpression<*>.psiElement: PsiElement?
|
||||
fun IrSimpleType.isRawType(): Boolean =
|
||||
hasAnnotation(JvmGeneratorExtensions.RAW_TYPE_ANNOTATION_FQ_NAME)
|
||||
|
||||
internal fun classFileContainsMethod(function: IrFunction, context: JvmBackendContext, name: String): Boolean? {
|
||||
val classId = function.parentClassId ?: return null
|
||||
internal fun classFileContainsMethod(classId: ClassId, function: IrFunction, context: JvmBackendContext): Boolean? {
|
||||
val originalDescriptor = context.methodSignatureMapper.mapSignatureWithGeneric(function).asmMethod.descriptor
|
||||
val descriptor = if (function.isSuspend)
|
||||
listOf(*Type.getArgumentTypes(originalDescriptor), Type.getObjectType("kotlin/coroutines/Continuation"))
|
||||
.joinToString(prefix = "(", postfix = ")", separator = "") + AsmTypes.OBJECT_TYPE
|
||||
else originalDescriptor
|
||||
return classFileContainsMethod(classId, context.state, Method(name, descriptor))
|
||||
return classFileContainsMethod(classId, context.state, Method(function.name.asString(), descriptor))
|
||||
}
|
||||
|
||||
val IrMemberWithContainerSource.parentClassId: ClassId?
|
||||
|
||||
+22
-8
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.classFileContainsMethod
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.parentClassId
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isFromJava
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
|
||||
@@ -226,6 +227,27 @@ class MemoizedInlineClassReplacements(
|
||||
replacementOrigin: IrDeclarationOrigin,
|
||||
noFakeOverride: Boolean = false,
|
||||
body: IrFunction.() -> Unit
|
||||
): IrSimpleFunction {
|
||||
val useOldManglingScheme = context.state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures
|
||||
val replacement = buildReplacementInner(function, replacementOrigin, noFakeOverride, useOldManglingScheme, body)
|
||||
// When using the new mangling scheme we might run into dependencies using the old scheme
|
||||
// for which we will fall back to the old mangling scheme as well.
|
||||
if (
|
||||
!useOldManglingScheme &&
|
||||
replacement.name.asString().contains("-") &&
|
||||
function.parentClassId?.let { classFileContainsMethod(it, replacement, context) } == false
|
||||
) {
|
||||
return buildReplacementInner(function, replacementOrigin, noFakeOverride, true, body)
|
||||
}
|
||||
return replacement
|
||||
}
|
||||
|
||||
private fun buildReplacementInner(
|
||||
function: IrFunction,
|
||||
replacementOrigin: IrDeclarationOrigin,
|
||||
noFakeOverride: Boolean,
|
||||
useOldManglingScheme: Boolean,
|
||||
body: IrFunction.() -> Unit,
|
||||
): IrSimpleFunction = irFactory.buildFun {
|
||||
updateFrom(function)
|
||||
if (function is IrConstructor) {
|
||||
@@ -243,15 +265,7 @@ class MemoizedInlineClassReplacements(
|
||||
if (noFakeOverride) {
|
||||
isFakeOverride = false
|
||||
}
|
||||
val useOldManglingScheme = context.state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures
|
||||
name = mangledNameFor(function, mangleReturnTypes, useOldManglingScheme)
|
||||
if (
|
||||
!useOldManglingScheme &&
|
||||
name.asString().contains("-") &&
|
||||
classFileContainsMethod(function, context, name.asString()) == false
|
||||
) {
|
||||
name = mangledNameFor(function, mangleReturnTypes, true)
|
||||
}
|
||||
returnType = function.returnType
|
||||
}.apply {
|
||||
parent = function.parent
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// FILE: A.kt
|
||||
|
||||
inline class A(val x: String) {
|
||||
inline fun f(other: A): A = other
|
||||
}
|
||||
|
||||
// FILE: B.kt
|
||||
|
||||
fun box(): String {
|
||||
return A("Fail").f(A("OK")).x
|
||||
}
|
||||
Generated
+5
@@ -164,6 +164,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineFunctionCall.kt")
|
||||
public void testInlineClassInlineFunctionCall() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineFunctionCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineProperty.kt")
|
||||
public void testInlineClassInlineProperty() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineProperty.kt");
|
||||
|
||||
Generated
+5
@@ -165,6 +165,11 @@ public class IrCompileKotlinAgainstKotlinTestGenerated extends AbstractIrCompile
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineFunctionCall.kt")
|
||||
public void testInlineClassInlineFunctionCall() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineFunctionCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineProperty.kt")
|
||||
public void testInlineClassInlineProperty() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineProperty.kt");
|
||||
|
||||
+5
@@ -165,6 +165,11 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineFunctionCall.kt")
|
||||
public void testInlineClassInlineFunctionCall() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineFunctionCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineProperty.kt")
|
||||
public void testInlineClassInlineProperty() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineProperty.kt");
|
||||
|
||||
+5
@@ -165,6 +165,11 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassFromBinaryDependencies.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineFunctionCall.kt")
|
||||
public void testInlineClassInlineFunctionCall() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineFunctionCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInlineProperty.kt")
|
||||
public void testInlineClassInlineProperty() throws Exception {
|
||||
runTest("compiler/testData/compileKotlinAgainstKotlin/inlineClassInlineProperty.kt");
|
||||
|
||||
Reference in New Issue
Block a user