From 5db6a0b56306414ecd1c6ffed166ec16ed6e3bb9 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 29 May 2020 11:38:42 +0300 Subject: [PATCH] New mangling rules require language version 1.4 (not compiler version) Follow-up to a270ee094c4d7b9520e0898a242bb6ce4dfcad7b --- .../serialization/JvmSerializerExtension.kt | 2 +- .../inlineClassReturnTypeMangled.kt | 3 ++ .../AbstractVersionRequirementTest.kt | 27 ++++++++++++----- .../JvmVersionRequirementTest.kt | 29 ++++++++++++++++++- .../tools/kotlinp/testData/Annotations.txt | 16 +++++----- 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt index a3290f8cc42..1819404ee34 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt @@ -216,7 +216,7 @@ class JvmSerializerExtension @JvmOverloads constructor( private fun MutableVersionRequirementTable.writeFunctionNameManglingForReturnTypeRequirement(add: (Int) -> Unit) { if (functionsWithInlineClassReturnTypesMangled) { - add(writeVersionRequirement(1, 4, 0, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, this)) + add(writeVersionRequirement(1, 4, 0, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, this)) } } diff --git a/compiler/testData/versionRequirement/inlineClassReturnTypeMangled.kt b/compiler/testData/versionRequirement/inlineClassReturnTypeMangled.kt index 4a61bffc516..55642cbc600 100644 --- a/compiler/testData/versionRequirement/inlineClassReturnTypeMangled.kt +++ b/compiler/testData/versionRequirement/inlineClassReturnTypeMangled.kt @@ -6,3 +6,6 @@ class C { fun returnsInlineClassType(): IC = IC(42) val propertyOfInlineClassType: IC get() = IC(42) } + +fun returnsInlineClassType(): IC = IC(42) +val propertyOfInlineClassType: IC get() = IC(42) diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt index f4d261a09a6..1d23a4ef8fa 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/AbstractVersionRequirementTest.kt @@ -31,7 +31,8 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() { customLanguageVersion: LanguageVersion = LanguageVersionSettingsImpl.DEFAULT.languageVersion, analysisFlags: Map, Any?> = emptyMap(), fqNamesWithRequirements: List, - fqNamesWithoutRequirement: List = emptyList() + fqNamesWithoutRequirement: List = emptyList(), + shouldBeSingleRequirement: Boolean = true ) { compileFiles( listOf(File("compiler/testData/versionRequirement/${getTestName(true)}.kt")), @@ -45,6 +46,13 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() { val requirements = extractRequirement(descriptor) if (requirements.isEmpty()) throw AssertionError("No VersionRequirement for $descriptor") + if (shouldBeSingleRequirement && requirements.size > 1) { + throw AssertionError( + "Single VersionRequirement expected, got ${requirements.size}:\n" + + requirements.joinToString(separator = "\n") { it.toDebugString() } + ) + } + requirements.firstOrNull { expectedVersionRequirement == it.version && expectedLevel == it.level && @@ -53,14 +61,14 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() { expectedErrorCode == it.errorCode } ?: throw AssertionError( - "Version requirement not found:\n" + - "expectedVersionRequirement=" + expectedVersionRequirement + - "; expectedLevel=" + expectedLevel + - "; expectedMessage=" + expectedMessage + - "; expectedVersionKind=" + expectedVersionKind + - "; expectedErrorCode=" + expectedErrorCode + + "Version requirement not found, expected:\n" + + "versionRequirement=" + expectedVersionRequirement + + "; level=" + expectedLevel + + "; message=" + expectedMessage + + "; versionKind=" + expectedVersionKind + + "; errorCode=" + expectedErrorCode + "\nActual requirements:\n" + - requirements.joinToString(separator = "\n") { it.toString() } + requirements.joinToString(separator = "\n") { it.toDebugString() } ) } @@ -72,6 +80,9 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() { } } + private fun VersionRequirement.toDebugString(): String = + "versionRequirement=$version; level=$level; message=$message; versionKind=$kind; errorCode=$errorCode" + private fun extractRequirement(descriptor: DeclarationDescriptor): List { return when (descriptor) { is DeserializedMemberDescriptor -> descriptor.versionRequirements diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt index 65bea2d6978..11d4eed14f7 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt @@ -129,14 +129,41 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() { } fun testInlineClassReturnTypeMangled() { + // Class members returning inline class values are mangled, + // and have "since 1.4" version requirement along with "since 1.3" version requirement for inline class in signature doTest( - VersionRequirement.Version(1, 4, 0), DeprecationLevel.ERROR, null, COMPILER_VERSION, null, + VersionRequirement.Version(1, 4, 0), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null, fqNamesWithRequirements = listOf( "test.C.returnsInlineClassType", "test.C.propertyOfInlineClassType" ), + customLanguageVersion = LanguageVersion.KOTLIN_1_4, + shouldBeSingleRequirement = false + ) + // Top-level functions and properties returning inline class values are NOT mangled, + // and have "since 1.3" version requirement for inline class in signature only. + doTest( + VersionRequirement.Version(1, 3, 0), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null, + fqNamesWithRequirements = listOf( + "test.returnsInlineClassType", + "test.propertyOfInlineClassType" + ), + shouldBeSingleRequirement = true, customLanguageVersion = LanguageVersion.KOTLIN_1_4 ) + // In Kotlin 1.3, all functions and properties returning inline class values are NOT mangled, + // and have "since 1.3" version requirement for inline class in signature only. + doTest( + VersionRequirement.Version(1, 3, 0), DeprecationLevel.ERROR, null, LANGUAGE_VERSION, null, + fqNamesWithRequirements = listOf( + "test.returnsInlineClassType", + "test.propertyOfInlineClassType", + "test.C.returnsInlineClassType", + "test.C.propertyOfInlineClassType" + ), + shouldBeSingleRequirement = true, + customLanguageVersion = LanguageVersion.KOTLIN_1_3 + ) } fun testSuspendFun_1_2() { diff --git a/libraries/tools/kotlinp/testData/Annotations.txt b/libraries/tools/kotlinp/testData/Annotations.txt index 4e0e2160248..54f9aff218f 100644 --- a/libraries/tools/kotlinp/testData/Annotations.txt +++ b/libraries/tools/kotlinp/testData/Annotations.txt @@ -79,49 +79,49 @@ public final annotation class A : kotlin/Annotation { public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: ub()B public final val ub: kotlin/UByte public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: ub_max()B public final val ub_max: kotlin/UByte public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: ui()I public final val ui: kotlin/UInt public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: ui_max()I public final val ui_max: kotlin/UInt public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: ul()J public final val ul: kotlin/ULong public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: ul_max()J public final val ul_max: kotlin/ULong public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: us()S public final val us: kotlin/UShort public final get // requires language version 1.3.0 (level=ERROR) - // requires compiler version 1.4.0 (level=ERROR) + // requires language version 1.4.0 (level=ERROR) // getter: us_max()S public final val us_max: kotlin/UShort public final get