From c957a0b43b28d4c4d59c3f0f17720000000915f7 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 28 Mar 2023 12:37:36 +0300 Subject: [PATCH] [IR] Properly serialize IrDeclarationOrigin.GeneratedByPlugin to klibs ^KT-56911 Fixed --- .../ir/backend/js/DeclarationOrigins.kt | 3 +- .../ir/declarations/IrDeclarationOrigin.kt | 23 ++++++++++-- .../IrDeclarationDeserializer.kt | 6 ++- .../common/serialization/IrFileSerializer.kt | 2 +- .../backend/konan/lower/BridgesBuilding.kt | 5 ++- .../org/jetbrains/kotlin/gradle/K2Tests.kt | 19 +++++++++- .../build.gradle.kts | 37 +++++++++++++++++++ .../settings.gradle.kts | 0 .../commonMain/kotlin/ValidateViolation.kt | 13 +++++++ .../plugin/AbstractTransformerForGenerator.kt | 6 +-- ...ransformerForAdditionalMembersGenerator.kt | 6 +-- .../TransformerForCompanionGenerator.kt | 6 +-- .../TransformerForExternalClassGenerator.kt | 6 +-- ...sformerForTopLevelDeclarationsGenerator.kt | 6 +-- 14 files changed, 111 insertions(+), 27 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/settings.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/src/commonMain/kotlin/ValidateViolation.kt diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt index c73718c9549..1f7d1be3f27 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/DeclarationOrigins.kt @@ -5,10 +5,9 @@ package org.jetbrains.kotlin.ir.backend.js -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl -object JsLoweredDeclarationOrigin : IrDeclarationOrigin { +object JsLoweredDeclarationOrigin { object JS_INTRINSICS_STUB : IrDeclarationOriginImpl("JS_INTRINSICS_STUB") object JS_CLOSURE_BOX_CLASS_DECLARATION : IrDeclarationOriginImpl("JS_CLOSURE_BOX_CLASS_DECLARATION") object BRIDGE_WITH_STABLE_NAME : IrDeclarationOriginImpl("BRIDGE_WITH_STABLE_NAME") diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt index 53ad8a101d5..96c327c9954 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt @@ -87,9 +87,24 @@ interface IrDeclarationOrigin { object SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT : IrDeclarationOriginImpl("SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT", isSynthetic = true) - class GeneratedByPlugin(val pluginKey: GeneratedDeclarationKey) : IrDeclarationOrigin { + /** + * [pluginKey] may be null if declaration with this origin was deserialized from klib + */ + class GeneratedByPlugin private constructor(val pluginId: String, val pluginKey: GeneratedDeclarationKey?) : IrDeclarationOrigin { + constructor(pluginKey: GeneratedDeclarationKey) : this(pluginKey::class.qualifiedName!!, pluginKey) + + companion object { + fun fromSerializedString(name: String): GeneratedByPlugin? { + val pluginId = name.removeSurrounding("GENERATED[", "]").takeIf { it != name } ?: return null + return GeneratedByPlugin(pluginId, pluginKey = null) + } + } + + override val name: String + get() = "GENERATED[${pluginId}]" + override fun toString(): String { - return "GENERATED[${pluginKey}]" + return name } override fun equals(other: Any?): Boolean { @@ -103,11 +118,12 @@ interface IrDeclarationOrigin { } } + val name: String val isSynthetic: Boolean get() = false } abstract class IrDeclarationOriginImpl( - val name: String, + override val name: String, override val isSynthetic: Boolean = false ) : IrDeclarationOrigin { override fun toString(): String = name @@ -124,5 +140,4 @@ abstract class IrDeclarationOriginImpl( override fun hashCode(): Int { return name.hashCode() } - } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt index a69620b1868..bc7fed8628c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrDeclarationDeserializer.kt @@ -779,9 +779,11 @@ class IrDeclarationDeserializer( allKnownDeclarationOrigins.mapNotNull { it.objectInstance as? IrDeclarationOriginImpl }.associateBy { it.name } } - private fun deserializeIrDeclarationOrigin(protoName: Int): IrDeclarationOriginImpl { + private fun deserializeIrDeclarationOrigin(protoName: Int): IrDeclarationOrigin { val originName = libraryFile.string(protoName) - return declarationOriginIndex[originName] ?: object : IrDeclarationOriginImpl(originName) {} + return IrDeclarationOrigin.GeneratedByPlugin.fromSerializedString(originName) + ?: declarationOriginIndex[originName] + ?: object : IrDeclarationOriginImpl(originName) {} } fun deserializeDeclaration(proto: ProtoDeclaration, setParent: Boolean = true): IrDeclaration { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index d73d4800b92..a37aa8f20bd 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -183,7 +183,7 @@ open class IrFileSerializer( /* ------- Common fields ---------------------------------------------------- */ - private fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin): Int = serializeString((origin as IrDeclarationOriginImpl).name) + private fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin): Int = serializeString(origin.name) private fun serializeIrStatementOrigin(origin: IrStatementOrigin): Int = serializeString((origin as? IrStatementOriginImpl)?.debugName ?: error("Unable to serialize origin ${origin.javaClass.name}")) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt index 2d61f97aba8..8956939215a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt @@ -234,8 +234,11 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass { } internal class DECLARATION_ORIGIN_BRIDGE_METHOD(val bridgeTarget: IrFunction) : IrDeclarationOrigin { + override val name: String + get() = "BRIDGE_METHOD" + override fun toString(): String { - return "BRIDGE_METHOD(target=${bridgeTarget.symbol})" + return "$name(target=${bridgeTarget.symbol})" } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2Tests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2Tests.kt index 8ac240076d5..c1f8a0fb37c 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2Tests.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2Tests.kt @@ -5,8 +5,8 @@ package org.jetbrains.kotlin.gradle -import org.jetbrains.kotlin.gradle.testbase.BuildOptions -import org.jetbrains.kotlin.gradle.testbase.MppGradlePluginTests +import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.DisplayName import kotlin.test.Ignore @@ -37,3 +37,18 @@ class K2CommonizerIT : CommonizerIT() { class K2CommonizerHierarchicalIT : CommonizerHierarchicalIT() { override fun defaultBuildOptions(): BuildOptions = super.defaultBuildOptions().copy(languageVersion = "2.0") } + +@MppGradlePluginTests +@DisplayName("K2: custom tests") +class CustomK2Tests : KGPBaseTest() { + @GradleTest + @DisplayName("Serialization plugin in common source set. KT-56911") + fun testHmppDependenciesInJsTests(gradleVersion: GradleVersion) { + project("k2-serialization-plugin-in-common-sourceset", gradleVersion) { + val taskToExecute = ":compileKotlinJs" + build(taskToExecute) { + assertTasksExecuted(taskToExecute) + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/build.gradle.kts new file mode 100644 index 00000000000..9b8a9fbe157 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/build.gradle.kts @@ -0,0 +1,37 @@ +group = "com.h0tk3y.mpp.demo" +version = "1.0" + +plugins { + kotlin("multiplatform") + kotlin("plugin.serialization") +} + +repositories { + mavenLocal() + mavenCentral() +} + +kotlin { + jvm() + js(IR) { + browser { + commonWebpackConfig { + cssSupport { + enabled.set(true) + } + } + } + } + sourceSets { + all { + languageSettings.apply { + languageVersion = "2.0" + } + } + val commonMain by getting{ + dependencies{ + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0-RC") + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/settings.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/settings.gradle.kts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/src/commonMain/kotlin/ValidateViolation.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/src/commonMain/kotlin/ValidateViolation.kt new file mode 100644 index 00000000000..d3fa8b5bd2c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/k2-serialization-plugin-in-common-sourceset/src/commonMain/kotlin/ValidateViolation.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package testProject.k2 + +import kotlinx.serialization.Serializable + +@Serializable +data class ValidateViolation( + val filed: String, +) diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/AbstractTransformerForGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/AbstractTransformerForGenerator.kt index 2c294f13da3..414ee7f74c3 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/AbstractTransformerForGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/AbstractTransformerForGenerator.kt @@ -27,9 +27,9 @@ abstract class AbstractTransformerForGenerator( protected val irFactory = context.irFactory protected val irBuiltIns = context.irBuiltIns - abstract fun interestedIn(key: GeneratedDeclarationKey): Boolean - abstract fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey): IrBody? - abstract fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey): IrBody? + abstract fun interestedIn(key: GeneratedDeclarationKey?): Boolean + abstract fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey?): IrBody? + abstract fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey?): IrBody? final override fun visitElement(element: IrElement) { if (visitBodies) { diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForAdditionalMembersGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForAdditionalMembersGenerator.kt index a40c531197b..fbe0795eb0d 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForAdditionalMembersGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForAdditionalMembersGenerator.kt @@ -13,15 +13,15 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrBody class TransformerForAdditionalMembersGenerator(context: IrPluginContext) : AbstractTransformerForGenerator(context, visitBodies = false) { - override fun interestedIn(key: GeneratedDeclarationKey): Boolean { + override fun interestedIn(key: GeneratedDeclarationKey?): Boolean { return key == AdditionalMembersGenerator.Key } - override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey): IrBody? { + override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey?): IrBody? { return generateDefaultBodyForMaterializeFunction(function) } - override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey): IrBody? { + override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey?): IrBody? { return constructor.body } } diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForCompanionGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForCompanionGenerator.kt index 494deef9544..002713b8c51 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForCompanionGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForCompanionGenerator.kt @@ -16,17 +16,17 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl class TransformerForCompanionGenerator(context: IrPluginContext) : AbstractTransformerForGenerator(context, visitBodies = true) { - override fun interestedIn(key: GeneratedDeclarationKey): Boolean { + override fun interestedIn(key: GeneratedDeclarationKey?): Boolean { return key == CompanionGenerator.Key } - override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey): IrBody { + override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey?): IrBody { val const = IrConstImpl(-1, -1, irBuiltIns.intType, IrConstKind.Int, value = 10) val returnStatement = IrReturnImpl(-1, -1, irBuiltIns.nothingType, function.symbol, const) return irFactory.createBlockBody(-1, -1, listOf(returnStatement)) } - override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey): IrBody? { + override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey?): IrBody? { return generateBodyForDefaultConstructor(constructor) } } diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForExternalClassGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForExternalClassGenerator.kt index b0e07acee5f..dd859d13ff4 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForExternalClassGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForExternalClassGenerator.kt @@ -13,15 +13,15 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrBody class TransformerForExternalClassGenerator(context: IrPluginContext) : AbstractTransformerForGenerator(context, visitBodies = false) { - override fun interestedIn(key: GeneratedDeclarationKey): Boolean { + override fun interestedIn(key: GeneratedDeclarationKey?): Boolean { return key == ExternalClassGenerator.Key } - override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey): IrBody? { + override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey?): IrBody? { return generateDefaultBodyForMaterializeFunction(function) } - override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey): IrBody? { + override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey?): IrBody? { return generateBodyForDefaultConstructor(constructor) } } diff --git a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForTopLevelDeclarationsGenerator.kt b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForTopLevelDeclarationsGenerator.kt index df06c0465dc..1fc0c8a1276 100644 --- a/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForTopLevelDeclarationsGenerator.kt +++ b/plugins/fir-plugin-prototype/src/org/jetbrains/kotlin/ir/plugin/TransformerForTopLevelDeclarationsGenerator.kt @@ -17,18 +17,18 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl import org.jetbrains.kotlin.ir.types.classFqName class TransformerForTopLevelDeclarationsGenerator(context: IrPluginContext) : AbstractTransformerForGenerator(context, visitBodies = false) { - override fun interestedIn(key: GeneratedDeclarationKey): Boolean { + override fun interestedIn(key: GeneratedDeclarationKey?): Boolean { return key == TopLevelDeclarationsGenerator.Key } - override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey): IrBody { + override fun generateBodyForFunction(function: IrSimpleFunction, key: GeneratedDeclarationKey?): IrBody { val className = function.valueParameters.single().type.classFqName?.asString() ?: "" val const = IrConstImpl(-1, -1, irBuiltIns.stringType, IrConstKind.String, className) val returnExpression = IrReturnImpl(-1, -1, irBuiltIns.nothingType, function.symbol, const) return irFactory.createBlockBody(-1, -1, listOf(returnExpression)) } - override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey): IrBody? { + override fun generateBodyForConstructor(constructor: IrConstructor, key: GeneratedDeclarationKey?): IrBody? { return null } }