From b443848ea0924d8333d6579646e67262533968be Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 22 Feb 2022 21:58:19 +0100 Subject: [PATCH] Fix type table serialization in DescriptorSerializer Always serialize type table (and version requirement table) after everything else, to prevent bugs like KT-51446 where inline class underlying type was added to the type table after it has already been serialized. #KT-51446 Fixed --- .../fir/serialization/FirElementSerializer.kt | 38 ++++++------------- .../FirBlackBoxCodegenTestGenerated.java | 6 +++ .../serialization/DescriptorSerializer.kt | 37 +++++------------- .../directives/LanguageSettingsDirectives.kt | 1 + ...nstructorWithPrivateFieldUsingTypeTable.kt | 18 +++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ .../JvmIrAgainstOldBoxTestGenerated.java | 6 +++ .../JvmOldAgainstIrBoxTestGenerated.java | 6 +++ .../JvmEnvironmentConfigurator.kt | 2 + .../NativeCodegenBoxTestGenerated.java | 6 +++ 11 files changed, 78 insertions(+), 54 deletions(-) create mode 100644 compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index 83dcf8db12e..d360a5146e4 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -78,18 +78,11 @@ class FirElementSerializer private constructor( } } - val typeTableProto = typeTable.serialize() - if (typeTableProto != null) { - builder.typeTable = typeTableProto - } - - val versionRequirementTableProto = versionRequirementTable?.serialize() - if (versionRequirementTableProto != null) { - builder.versionRequirementTable = versionRequirementTableProto - } - extension.serializePackage(packageFqName, builder) + typeTable.serialize()?.let { builder.typeTable = it } + versionRequirementTable?.serialize()?.let { builder.versionRequirementTable = it } + return builder } @@ -179,11 +172,6 @@ class FirElementSerializer private constructor( builder.companionObjectName = getSimpleNameIndex(companionObject.name) } - val typeTableProto = typeTable.serialize() - if (typeTableProto != null) { - builder.typeTable = typeTableProto - } - val representation = (klass as? FirRegularClass)?.getInlineClassUnderlyingParameter(session) if (representation != null) { builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.name) @@ -208,10 +196,9 @@ class FirElementSerializer private constructor( writeVersionRequirementForInlineClasses(klass, builder, versionRequirementTable) - val versionRequirementTableProto = versionRequirementTable.serialize() - if (versionRequirementTableProto != null) { - builder.versionRequirementTable = versionRequirementTableProto - } + typeTable.serialize()?.let { builder.typeTable = it } + versionRequirementTable.serialize()?.let { builder.versionRequirementTable = it } + return builder } @@ -411,11 +398,12 @@ class FirElementSerializer private constructor( builder.addValueParameter(local.valueParameterProto(valueParameter)) } + contractSerializer.serializeContractOfFunctionIfAny(function, builder, this) + + extension.serializeFunction(function, builder, versionRequirementTable, local) + if (serializeTypeTableToFunction) { - val typeTableProto = typeTable.serialize() - if (typeTableProto != null) { - builder.typeTable = typeTableProto - } + typeTable.serialize()?.let { builder.typeTable = it } } versionRequirementTable?.run { @@ -430,10 +418,6 @@ class FirElementSerializer private constructor( } } - contractSerializer.serializeContractOfFunctionIfAny(function, builder, this) - - extension.serializeFunction(function, builder, versionRequirementTable, local) - return builder } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index d952b996abc..97e133eb238 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -7586,6 +7586,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt"); } + @Test + @TestMetadata("privateConstructorWithPrivateFieldUsingTypeTable.kt") + public void testPrivateConstructorWithPrivateFieldUsingTypeTable() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt"); + } + @Test @TestMetadata("privateTopLevelValInDifferentModule.kt") public void testPrivateTopLevelValInDifferentModule() throws Exception { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index df10a53a198..03fe554646e 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -171,11 +171,6 @@ class DescriptorSerializer private constructor( builder.companionObjectName = getSimpleNameIndex(companionObjectDescriptor.name) } - val typeTableProto = typeTable.serialize() - if (typeTableProto != null) { - builder.typeTable = typeTableProto - } - val representation = classDescriptor.inlineClassRepresentation if (representation != null) { builder.inlineClassUnderlyingPropertyName = getSimpleNameIndex(representation.underlyingPropertyName) @@ -214,10 +209,8 @@ class DescriptorSerializer private constructor( ) } - val versionRequirementTableProto = versionRequirementTable.serialize() - if (versionRequirementTableProto != null) { - builder.versionRequirementTable = versionRequirementTableProto - } + typeTable.serialize()?.let { builder.typeTable = it } + versionRequirementTable.serialize()?.let { builder.versionRequirementTable = it } return builder } @@ -423,11 +416,12 @@ class DescriptorSerializer private constructor( builder.addValueParameter(local.valueParameter(valueParameterDescriptor)) } + contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this) + + extension.serializeFunction(descriptor, builder, versionRequirementTable, local) + if (serializeTypeTableToFunction) { - val typeTableProto = typeTable.serialize() - if (typeTableProto != null) { - builder.typeTable = typeTableProto - } + typeTable.serialize()?.let { builder.typeTable = it } } versionRequirementTable?.run { @@ -450,10 +444,6 @@ class DescriptorSerializer private constructor( } } - contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this) - - extension.serializeFunction(descriptor, builder, versionRequirementTable, local) - return builder } @@ -771,18 +761,11 @@ class DescriptorSerializer private constructor( } } - val typeTableProto = typeTable.serialize() - if (typeTableProto != null) { - builder.typeTable = typeTableProto - } - - val versionRequirementTableProto = versionRequirementTable?.serialize() - if (versionRequirementTableProto != null) { - builder.versionRequirementTable = versionRequirementTableProto - } - extension.serializePackage(packageFqName, builder) + typeTable.serialize()?.let { builder.typeTable = it } + versionRequirementTable?.serialize()?.let { builder.versionRequirementTable = it } + return builder } diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt index 028b505e4e2..292bb82cc76 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt @@ -77,6 +77,7 @@ object LanguageSettingsDirectives : SimpleDirectivesContainer() { val DISABLE_CALL_ASSERTIONS by directive("Disable assertions on calls") val NO_UNIFIED_NULL_CHECKS by directive("No unified null checks") val PARAMETERS_METADATA by directive("Add parameters metadata for 1.8 reflection") + val USE_TYPE_TABLE by directive("Use type table in metadata serialization") // --------------------- Utils --------------------- diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt new file mode 100644 index 00000000000..37abdaa61c5 --- /dev/null +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt @@ -0,0 +1,18 @@ +// !LANGUAGE: +GenericInlineClassParameter +// WITH_STDLIB +// USE_TYPE_TABLE +// MODULE: lib +// FILE: A.kt + +inline class A private constructor(private val value: T) { + val publicValue: String get() = value.toString() + + companion object { + fun create(c: Char): A = A(c + "K") + } +} + +// MODULE: main(lib) +// FILE: B.kt + +fun box(): String = A.create('O').publicValue diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 959ad5b2988..935f325c68d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -7466,6 +7466,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt"); } + @Test + @TestMetadata("privateConstructorWithPrivateFieldUsingTypeTable.kt") + public void testPrivateConstructorWithPrivateFieldUsingTypeTable() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt"); + } + @Test @TestMetadata("privateTopLevelValInDifferentModule.kt") public void testPrivateTopLevelValInDifferentModule() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 7237c91c250..92c7579198d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -7586,6 +7586,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt"); } + @Test + @TestMetadata("privateConstructorWithPrivateFieldUsingTypeTable.kt") + public void testPrivateConstructorWithPrivateFieldUsingTypeTable() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt"); + } + @Test @TestMetadata("privateTopLevelValInDifferentModule.kt") public void testPrivateTopLevelValInDifferentModule() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java index dd2273a13bc..183bce5cb36 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxTestGenerated.java @@ -596,6 +596,12 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt"); } + @Test + @TestMetadata("privateConstructorWithPrivateFieldUsingTypeTable.kt") + public void testPrivateConstructorWithPrivateFieldUsingTypeTable() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt"); + } + @Test @TestMetadata("privateTopLevelValInDifferentModule.kt") public void testPrivateTopLevelValInDifferentModule() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java index 1c0f520599a..e0de8a0883a 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxTestGenerated.java @@ -590,6 +590,12 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt"); } + @Test + @TestMetadata("privateConstructorWithPrivateFieldUsingTypeTable.kt") + public void testPrivateConstructorWithPrivateFieldUsingTypeTable() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt"); + } + @Test @TestMetadata("privateTopLevelValInDifferentModule.kt") public void testPrivateTopLevelValInDifferentModule() throws Exception { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt index 523cfda70f4..514ded9a02d 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt @@ -48,6 +48,7 @@ import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.NO_OPTIMI import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.NO_UNIFIED_NULL_CHECKS import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.PARAMETERS_METADATA import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.JDK_RELEASE +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.USE_TYPE_TABLE import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives import org.jetbrains.kotlin.test.model.DependencyDescription @@ -147,6 +148,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig register(JVM_TARGET, JVMConfigurationKeys.JVM_TARGET) register(SERIALIZE_IR, JVMConfigurationKeys.SERIALIZE_IR) register(JDK_RELEASE, JVMConfigurationKeys.JDK_RELEASE) + register(USE_TYPE_TABLE, JVMConfigurationKeys.USE_TYPE_TABLE) } @OptIn(ExperimentalPathApi::class, ExperimentalStdlibApi::class) diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index 2f0b9cd1ffd..75b99345a57 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -5700,6 +5700,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt"); } + @Test + @TestMetadata("privateConstructorWithPrivateFieldUsingTypeTable.kt") + public void testPrivateConstructorWithPrivateFieldUsingTypeTable() throws Exception { + runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateFieldUsingTypeTable.kt"); + } + @Test @TestMetadata("privateTopLevelValInDifferentModule.kt") public void testPrivateTopLevelValInDifferentModule() throws Exception {