Language feature for new inline class mangling rules (since 1.4)

This commit is contained in:
Dmitry Petrov
2020-05-28 19:13:57 +03:00
parent 94509bdb4e
commit a270ee094c
26 changed files with 296 additions and 6 deletions
@@ -251,7 +251,8 @@ class GenerationState private constructor(
val isInlineDisabled: Boolean = configuration.getBoolean(CommonConfigurationKeys.DISABLE_INLINE)
val useTypeTableInSerializer: Boolean = configuration.getBoolean(JVMConfigurationKeys.USE_TYPE_TABLE)
val unifiedNullChecks: Boolean = languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4
val functionsWithInlineClassReturnTypesMangled: Boolean = languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4
val functionsWithInlineClassReturnTypesMangled: Boolean =
languageVersionSettings.supportsFeature(LanguageFeature.MangleClassMembersReturningInlineClasses)
val rootContext: CodegenContext<*> = RootContext(this)
@@ -619,6 +619,9 @@ class KotlinTypeMapper @JvmOverloads constructor(
}
}
private val shouldMangleByReturnType =
languageVersionSettings.supportsFeature(LanguageFeature.MangleClassMembersReturningInlineClasses)
private fun mangleMemberNameIfRequired(
name: String,
descriptor: CallableMemberDescriptor,
@@ -657,7 +660,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
// so that we don't have to repeat the same logic in reflection
// in case of properties without getter methods.
if (kind !== OwnerKind.PROPERTY_REFERENCE_SIGNATURE || descriptor.isPropertyWithGetterSignaturePresent()) {
val suffix = getManglingSuffixBasedOnKotlinSignature(descriptor)
val suffix = getManglingSuffixBasedOnKotlinSignature(descriptor, shouldMangleByReturnType)
if (suffix != null) {
newName += suffix
} else if (kind === OwnerKind.ERASED_INLINE_CLASS) {
@@ -683,6 +686,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
} else newName
}
private fun CallableMemberDescriptor.isPropertyWithGetterSignaturePresent(): Boolean {
val propertyDescriptor = when (this) {
is PropertyDescriptor -> this
@@ -16,7 +16,10 @@ import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
import java.security.MessageDigest
import java.util.*
fun getManglingSuffixBasedOnKotlinSignature(descriptor: CallableMemberDescriptor): String? {
fun getManglingSuffixBasedOnKotlinSignature(
descriptor: CallableMemberDescriptor,
shouldMangleByReturnType: Boolean
): String? {
if (descriptor !is FunctionDescriptor) return null
if (descriptor is ConstructorDescriptor) return null
if (InlineClassDescriptorResolver.isSynthesizedBoxOrUnboxMethod(descriptor)) return null
@@ -30,9 +33,11 @@ fun getManglingSuffixBasedOnKotlinSignature(descriptor: CallableMemberDescriptor
// If a class member function returns inline class value, mangle its name.
// NB here function can be a suspend function JVM view with return type replaced with 'Any',
// should unwrap it and take original return type instead.
val unwrappedDescriptor = descriptor.unwrapInitialDescriptorForSuspendFunction()
if (requiresFunctionNameManglingForReturnType(unwrappedDescriptor)) {
return "-" + md5base64(":" + getSignatureElementForMangling(unwrappedDescriptor.returnType!!))
if (shouldMangleByReturnType) {
val unwrappedDescriptor = descriptor.unwrapInitialDescriptorForSuspendFunction()
if (requiresFunctionNameManglingForReturnType(unwrappedDescriptor)) {
return "-" + md5base64(":" + getSignatureElementForMangling(unwrappedDescriptor.returnType!!))
}
}
return null
}
@@ -12978,6 +12978,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nullableEqeqNonNull.kt")
public void testNullableEqeqNonNull() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
@@ -0,0 +1,13 @@
// !LANGUAGE: +InlineClasses -MangleClassMembersReturningInlineClasses
inline class S(val x: String)
class Test {
fun getO() = S("O")
val k = S("K")
}
fun box(): String {
val t = Test()
return t.getO().x + t.k.x
}
@@ -0,0 +1,16 @@
// !LANGUAGE: +InlineClasses -MangleClassMembersReturningInlineClasses
// FILE: 1.kt
package test
inline class S(val string: String)
inline fun foo() = S("OK")
// FILE: 2.kt
import test.*
fun box() : String =
foo().string
@@ -0,0 +1,16 @@
// !LANGUAGE: +InlineClasses -MangleClassMembersReturningInlineClasses
// FILE: 1.kt
package test
inline class S(val string: String)
inline val foo get() = S("OK")
// FILE: 2.kt
import test.*
fun box() : String = foo.string
@@ -0,0 +1,16 @@
// !LANGUAGE: +InlineClasses +MangleClassMembersReturningInlineClasses
// FILE: 1.kt
package test
inline class S(val string: String)
inline fun foo() = S("OK")
// FILE: 2.kt
import test.*
fun box() : String =
foo().string
@@ -0,0 +1,16 @@
// !LANGUAGE: +InlineClasses +MangleClassMembersReturningInlineClasses
// FILE: 1.kt
package test
inline class S(val string: String)
inline val foo get() = S("OK")
// FILE: 2.kt
import test.*
fun box() : String = foo.string
@@ -0,0 +1,17 @@
// !LANGUAGE: +InlineClasses -MangleClassMembersReturningInlineClasses
// IGNORE_BACKEND: JVM_IR
inline class S(val x: String)
class Test {
fun getO() = S("O")
val k = S("K")
}
fun box(): String {
val t = Test()
return t.getO().x + t.k.x
}
// 1 public final getO\(\)Ljava/lang/String;
// 1 public final getK\(\)Ljava/lang/String;
@@ -14193,6 +14193,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nullableEqeqNonNull.kt")
public void testNullableEqeqNonNull() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
@@ -1890,6 +1890,26 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
}
@TestMetadata("noReturnTypeManglingFun.kt")
public void testNoReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingFun.kt");
}
@TestMetadata("noReturnTypeManglingVal.kt")
public void testNoReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingVal.kt");
}
@TestMetadata("withReturnTypeManglingFun.kt")
public void testWithReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingFun.kt");
}
@TestMetadata("withReturnTypeManglingVal.kt")
public void testWithReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingVal.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
@@ -2951,6 +2951,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noBoxingUnboxingInAccessorsForDelegatedPropertyWithInlineClassDelegate.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nonOverridingMethodsAreCalledByInlineClass.kt")
public void testNonOverridingMethodsAreCalledByInlineClass() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/nonOverridingMethodsAreCalledByInlineClass.kt");
@@ -1890,6 +1890,26 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
}
@TestMetadata("noReturnTypeManglingFun.kt")
public void testNoReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingFun.kt");
}
@TestMetadata("noReturnTypeManglingVal.kt")
public void testNoReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingVal.kt");
}
@TestMetadata("withReturnTypeManglingFun.kt")
public void testWithReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingFun.kt");
}
@TestMetadata("withReturnTypeManglingVal.kt")
public void testWithReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingVal.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
@@ -14198,6 +14198,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nullableEqeqNonNull.kt")
public void testNullableEqeqNonNull() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
@@ -12978,6 +12978,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nullableEqeqNonNull.kt")
public void testNullableEqeqNonNull() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
@@ -1890,6 +1890,26 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
}
@TestMetadata("noReturnTypeManglingFun.kt")
public void testNoReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingFun.kt");
}
@TestMetadata("noReturnTypeManglingVal.kt")
public void testNoReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingVal.kt");
}
@TestMetadata("withReturnTypeManglingFun.kt")
public void testWithReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingFun.kt");
}
@TestMetadata("withReturnTypeManglingVal.kt")
public void testWithReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingVal.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
@@ -3036,6 +3036,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noBoxingUnboxingInAccessorsForDelegatedPropertyWithInlineClassDelegate.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nonOverridingMethodsAreCalledByInlineClass.kt")
public void testNonOverridingMethodsAreCalledByInlineClass() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/nonOverridingMethodsAreCalledByInlineClass.kt");
@@ -1890,6 +1890,26 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
}
@TestMetadata("noReturnTypeManglingFun.kt")
public void testNoReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingFun.kt");
}
@TestMetadata("noReturnTypeManglingVal.kt")
public void testNoReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingVal.kt");
}
@TestMetadata("withReturnTypeManglingFun.kt")
public void testWithReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingFun.kt");
}
@TestMetadata("withReturnTypeManglingVal.kt")
public void testWithReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingVal.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
@@ -124,6 +124,7 @@ enum class LanguageFeature(
ProperIeee754Comparisons(KOTLIN_1_4, kind = BUG_FIX),
FunctionalInterfaceConversion(KOTLIN_1_4, kind = UNSTABLE_FEATURE),
GenerateJvmOverloadsAsFinal(KOTLIN_1_4),
MangleClassMembersReturningInlineClasses(KOTLIN_1_4),
ProhibitSpreadOnSignaturePolymorphicCall(KOTLIN_1_5, kind = BUG_FIX),
ProhibitInvisibleAbstractMethodsInSuperclasses(KOTLIN_1_5, kind = BUG_FIX),
@@ -11168,6 +11168,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nullableEqeqNonNull.kt")
public void testNullableEqeqNonNull() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
@@ -1690,6 +1690,26 @@ public class IrJsCodegenInlineES6TestGenerated extends AbstractIrJsCodegenInline
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
}
@TestMetadata("noReturnTypeManglingFun.kt")
public void testNoReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingFun.kt");
}
@TestMetadata("noReturnTypeManglingVal.kt")
public void testNoReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingVal.kt");
}
@TestMetadata("withReturnTypeManglingFun.kt")
public void testWithReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingFun.kt");
}
@TestMetadata("withReturnTypeManglingVal.kt")
public void testWithReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingVal.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
@@ -11178,6 +11178,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nullableEqeqNonNull.kt")
public void testNullableEqeqNonNull() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
@@ -1690,6 +1690,26 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
}
@TestMetadata("noReturnTypeManglingFun.kt")
public void testNoReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingFun.kt");
}
@TestMetadata("noReturnTypeManglingVal.kt")
public void testNoReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingVal.kt");
}
@TestMetadata("withReturnTypeManglingFun.kt")
public void testWithReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingFun.kt");
}
@TestMetadata("withReturnTypeManglingVal.kt")
public void testWithReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingVal.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")
@@ -11243,6 +11243,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
}
@TestMetadata("noReturnTypeMangling.kt")
public void testNoReturnTypeMangling() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noReturnTypeMangling.kt");
}
@TestMetadata("nullableEqeqNonNull.kt")
public void testNullableEqeqNonNull() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nullableEqeqNonNull.kt");
@@ -1690,6 +1690,26 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
public void testInlineFunctionInsideInlineClassesBox() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/inlineFunctionInsideInlineClassesBox.kt");
}
@TestMetadata("noReturnTypeManglingFun.kt")
public void testNoReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingFun.kt");
}
@TestMetadata("noReturnTypeManglingVal.kt")
public void testNoReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/noReturnTypeManglingVal.kt");
}
@TestMetadata("withReturnTypeManglingFun.kt")
public void testWithReturnTypeManglingFun() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingFun.kt");
}
@TestMetadata("withReturnTypeManglingVal.kt")
public void testWithReturnTypeManglingVal() throws Exception {
runTest("compiler/testData/codegen/boxInline/inlineClasses/withReturnTypeManglingVal.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/innerClasses")