diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmKotlinMangler.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmKotlinMangler.kt index dc4621b2a2d..41a13752d7b 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmKotlinMangler.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmKotlinMangler.kt @@ -14,18 +14,15 @@ import org.jetbrains.kotlin.fir.signaturer.FirMangler @NoMutableState class FirJvmKotlinMangler(private val session: FirSession) : AbstractKotlinMangler(), FirMangler { - override val FirDeclaration.mangleString: String - get() = getMangleComputer(MangleMode.FULL).computeMangle(this) + override fun FirDeclaration.mangleString(): String = getMangleComputer(MangleMode.FULL).computeMangle(this) - override val FirDeclaration.signatureString: String - get() = getMangleComputer(MangleMode.SIGNATURE).computeMangle(this) + override fun FirDeclaration.signatureString(): String = getMangleComputer(MangleMode.SIGNATURE).computeMangle(this) - override val FirDeclaration.fqnString: String - get() = getMangleComputer(MangleMode.FQNAME).computeMangle(this) + override fun FirDeclaration.fqnString(): String = getMangleComputer(MangleMode.FQNAME).computeMangle(this) - override fun FirDeclaration.isExported(): Boolean = true + override fun FirDeclaration.isExported(compatibleMode: Boolean): Boolean = true - override fun getExportChecker(): KotlinExportChecker { + override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker { return object : KotlinExportChecker { override fun check(declaration: FirDeclaration, type: SpecialDeclarationType): Boolean = true diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt index 9268d445fba..9cf26a799f1 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt @@ -40,17 +40,17 @@ class FirBasedSignatureComposer(private val mangler: FirMangler) : Fir2IrSignatu } override fun visitConstructor(constructor: FirConstructor, data: Any?) { - hashId = mangler.run { constructor.signatureMangle } + hashId = mangler.run { constructor.signatureMangle() } setExpected(constructor.isExpect) } override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?) { - hashId = mangler.run { simpleFunction.signatureMangle } + hashId = mangler.run { simpleFunction.signatureMangle() } setExpected(simpleFunction.isExpect) } override fun visitProperty(property: FirProperty, data: Any?) { - hashId = mangler.run { property.signatureMangle } + hashId = mangler.run { property.signatureMangle() } setExpected(property.isExpect) } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index 314ffde0583..ebfd4418bb8 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -457,11 +457,11 @@ val IrFunction.allParametersCount: Int // TODO: merge it with FakeOverrideBuilder. private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy() { - override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) { + override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction, compatibilityMode: Boolean) { declaration.acquireSymbol(IrSimpleFunctionSymbolImpl()) } - override fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) { + override fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty, compatibilityMode: Boolean) { val propertySymbol = IrPropertySymbolImpl() declaration.getter?.let { it.correspondingPropertySymbol = propertySymbol } declaration.setter?.let { it.correspondingPropertySymbol = propertySymbol } @@ -470,18 +470,18 @@ private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy() { declaration.getter?.let { it.correspondingPropertySymbol = declaration.symbol - linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override getter: $it")) + linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override getter: $it"), compatibilityMode) } declaration.setter?.let { it.correspondingPropertySymbol = declaration.symbol - linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override setter: $it")) + linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override setter: $it"), compatibilityMode) } } } fun IrClass.addFakeOverrides(irBuiltIns: IrBuiltIns, implementedMembers: List = emptyList()) { IrOverridingUtil(irBuiltIns, FakeOverrideBuilderForLowerings()) - .buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers) + .buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers, compatibilityMode = false) .forEach { addChild(it) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt index 60725596408..1cff43ee56e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt @@ -34,7 +34,7 @@ import kotlin.math.abs private fun mapToKey(declaration: T): String { return with(JsManglerIr) { if (declaration is IrDeclaration) { - declaration.hashedMangle.toString() + declaration.hashedMangle().toString() } else if (declaration is String) { declaration.hashMangle.toString() } else { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt index 7bdbc2f5a66..88f580c6eb3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverridingUtil.kt @@ -27,16 +27,16 @@ abstract class FakeOverrideBuilderStrategy { open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember = buildFakeOverrideMember(superType, member, clazz) - fun linkFakeOverride(fakeOverride: IrOverridableMember) { + fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) { when (fakeOverride) { - is IrFakeOverrideFunction -> linkFunctionFakeOverride(fakeOverride) - is IrFakeOverrideProperty -> linkPropertyFakeOverride(fakeOverride) + is IrFakeOverrideFunction -> linkFunctionFakeOverride(fakeOverride, compatibilityMode) + is IrFakeOverrideProperty -> linkPropertyFakeOverride(fakeOverride, compatibilityMode) else -> error("Unexpected fake override: $fakeOverride") } } - protected abstract fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) - protected abstract fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) + protected abstract fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction, compatibilityMode: Boolean) + protected abstract fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty, compatibilityMode: Boolean) } private fun IrOverridableMember.isPrivateToThisModule(thisClass: IrClass, memberClass: IrClass): Boolean { @@ -133,7 +133,7 @@ class IrOverridingUtil( } } - fun buildFakeOverridesForClass(clazz: IrClass) { + fun buildFakeOverridesForClass(clazz: IrClass, oldSignatures: Boolean) { val superTypes = clazz.superTypes @Suppress("UNCHECKED_CAST") @@ -158,14 +158,15 @@ class IrOverridingUtil( generateOverridesInFunctionGroup( group.value, fromCurrent.filter { it.name == group.key }, - clazz + clazz, oldSignatures ) } } fun buildFakeOverridesForClassUsingOverriddenSymbols( clazz: IrClass, - implementedMembers: List = emptyList() + implementedMembers: List = emptyList(), + compatibilityMode: Boolean ): List { val overriddenMembers = (clazz.declarations.filterIsInstance() + implementedMembers) .flatMap { member -> member.overriddenSymbols.map { it.owner } } @@ -189,7 +190,7 @@ class IrOverridingUtil( val unoverriddenSuperMembersGroupedByName = unoverriddenSuperMembers.groupBy { it.name } val fakeOverrides = mutableListOf() for (group in unoverriddenSuperMembersGroupedByName.values) { - createAndBindFakeOverrides(clazz, group, fakeOverrides) + createAndBindFakeOverrides(clazz, group, fakeOverrides, compatibilityMode) } return fakeOverrides } @@ -207,7 +208,8 @@ class IrOverridingUtil( private fun generateOverridesInFunctionGroup( membersFromSupertypes: List, membersFromCurrent: List, - current: IrClass + current: IrClass, + compatibilityMode: Boolean ) { val notOverridden = membersFromSupertypes.toMutableSet() @@ -217,7 +219,7 @@ class IrOverridingUtil( } val addedFakeOverrides = mutableListOf() - createAndBindFakeOverrides(current, notOverridden, addedFakeOverrides) + createAndBindFakeOverrides(current, notOverridden, addedFakeOverrides, compatibilityMode) current.declarations.addAll(addedFakeOverrides) } @@ -259,7 +261,8 @@ class IrOverridingUtil( private fun createAndBindFakeOverrides( current: IrClass, notOverridden: Collection, - addedFakeOverrides: MutableList + addedFakeOverrides: MutableList, + compatibilityMode: Boolean ) { val fromSuper = notOverridden.toMutableSet() while (fromSuper.isNotEmpty()) { @@ -268,7 +271,7 @@ class IrOverridingUtil( notOverriddenFromSuper, fromSuper ) - createAndBindFakeOverride(overridables, current, addedFakeOverrides) + createAndBindFakeOverride(overridables, current, addedFakeOverrides, compatibilityMode) } } @@ -381,7 +384,8 @@ class IrOverridingUtil( private fun createAndBindFakeOverride( overridables: Collection, current: IrClass, - addedFakeOverrides: MutableList + addedFakeOverrides: MutableList, + compatibilityMode: Boolean ) { val effectiveOverridden = filterVisibleFakeOverrides(overridables) @@ -416,7 +420,7 @@ class IrOverridingUtil( ) { "Overridden symbols should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE } addedFakeOverrides.add(fakeOverride) - fakeOverrideBuilder.linkFakeOverride(fakeOverride) + fakeOverrideBuilder.linkFakeOverride(fakeOverride, compatibilityMode) } private fun isVisibilityMoreSpecific( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/KotlinMangler.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/KotlinMangler.kt index 4ef072d5062..245f9d7caec 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/KotlinMangler.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/KotlinMangler.kt @@ -14,14 +14,16 @@ interface KotlinMangler { val String.hashMangle: Long - fun D.isExported(): Boolean - val D.mangleString: String - val D.signatureString: String - val D.fqnString: String + fun D.isExported(compatibleMode: Boolean): Boolean + fun D.mangleString(): String + fun D.signatureString(): String + fun D.fqnString(): String - val D.hashedMangle: Long get() = mangleString.hashMangle - val D.signatureMangle: Long get() = signatureString.hashMangle - val D.fqnMangle: Long get() = fqnString.hashMangle + fun D.hashedMangle(): Long = mangleString().hashMangle + fun D.signatureMangle(): Long = signatureString().hashMangle + fun D.fqnMangle(): Long = fqnString().hashMangle + + fun D.isPlatformSpecificExport(): Boolean = false val manglerName: String diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt index a96546e90bc..51fe1825882 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrideChecker.kt @@ -5,7 +5,10 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.IrOverridableMember +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -41,7 +44,7 @@ class FakeOverrideChecker( .filterNot { it.visibility == DescriptorVisibilities.PRIVATE || it.visibility == DescriptorVisibilities.INVISIBLE_FAKE } val descriptorSignatures = descriptorFakeOverrides - .map { with(descriptorMangler) { it.signatureString }} + .map { with(descriptorMangler) { it.signatureString() } } .sorted() val irFakeOverrides = clazz.declarations @@ -53,7 +56,7 @@ class FakeOverrideChecker( } val irSignatures = irFakeOverrides - .map { with(irMangler) { it.signatureString }} + .map { with(irMangler) { it.signatureString() } } .sorted() // We can't have equality here because dependency libraries could have diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt index 744f5d7eeab..e8df97c6a98 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.common.overrides +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer @@ -31,6 +32,7 @@ import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.KotlinMangler import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.fileOrNull import org.jetbrains.kotlin.ir.util.parentAsClass class FakeOverrideGlobalDeclarationTable( @@ -77,13 +79,15 @@ class FakeOverrideBuilder( // TODO: The declaration table is needed for the signaturer. private val fakeOverrideDeclarationTable = FakeOverrideDeclarationTable(mangler) - private val fakeOverrideClassQueue = mutableListOf() - fun enqueueClass(clazz: IrClass, signature: IdSignature) { +// private class CompatibilityMode(val oldSignatures: Boolean) + + private val fakeOverrideCandidates = mutableMapOf() + fun enqueueClass(clazz: IrClass, signature: IdSignature, compatibilityMode: CompatibilityMode) { fakeOverrideDeclarationTable.assumeDeclarationSignature(clazz, signature) - fakeOverrideClassQueue.add(clazz) + fakeOverrideCandidates[clazz] = compatibilityMode } - private fun buildFakeOverrideChainsForClass(clazz: IrClass) { + private fun buildFakeOverrideChainsForClass(clazz: IrClass, compatibilityMode: CompatibilityMode) { if (haveFakeOverrides.contains(clazz)) return if (!platformSpecificClassFilter.needToConstructFakeOverrides(clazz)) return @@ -93,20 +97,25 @@ class FakeOverrideBuilder( it.getClass() ?: error("Unexpected super type: $it") } - superClasses.forEach { - buildFakeOverrideChainsForClass(it) - haveFakeOverrides.add(it) + superClasses.forEach { superClass -> + val mode = fakeOverrideCandidates[superClass] ?: compatibilityMode + buildFakeOverrideChainsForClass(superClass, mode) + haveFakeOverrides.add(superClass) } - irOverridingUtil.buildFakeOverridesForClass(clazz) + fakeOverrideDeclarationTable.run { + inFile(clazz.fileOrNull) { + irOverridingUtil.buildFakeOverridesForClass(clazz, compatibilityMode.oldSignatures) + } + } } - override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) { - val signature = composeSignature(declaration) + override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction, compatibilityMode: Boolean) { + val signature = composeSignature(declaration, compatibilityMode) declareFunctionFakeOverride(declaration, signature) } - override fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) { + override fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty, compatibilityMode: Boolean) { // To compute a signature for a property with type parameters, // we must have its accessor's correspondingProperty pointing to the property's symbol. // See IrMangleComputer.mangleTypeParameterReference() for details. @@ -123,21 +132,21 @@ class FakeOverrideBuilder( it.correspondingPropertySymbol = tempSymbol } - val signature = composeSignature(declaration) + val signature = composeSignature(declaration, compatibilityMode) declarePropertyFakeOverride(declaration, signature) declaration.getter?.let { it.correspondingPropertySymbol = declaration.symbol - linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override getter: $it")) + linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override getter: $it"), compatibilityMode) } declaration.setter?.let { it.correspondingPropertySymbol = declaration.symbol - linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override setter: $it")) + linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override setter: $it"), compatibilityMode) } } - private fun composeSignature(declaration: IrDeclaration) = - fakeOverrideDeclarationTable.signaturer.composeSignatureForDeclaration(declaration) + private fun composeSignature(declaration: IrDeclaration, compatibleMode: Boolean) = + fakeOverrideDeclarationTable.signaturer.composeSignatureForDeclaration(declaration, compatibleMode) private fun declareFunctionFakeOverride(declaration: IrFakeOverrideFunction, signature: IdSignature) { val parent = declaration.parentAsClass @@ -159,16 +168,18 @@ class FakeOverrideBuilder( } } - private fun provideFakeOverrides(klass: IrClass) { - buildFakeOverrideChainsForClass(klass) + private fun provideFakeOverrides(klass: IrClass, compatibleMode: CompatibilityMode) { + buildFakeOverrideChainsForClass(klass, compatibleMode) irOverridingUtil.clear() haveFakeOverrides.add(klass) } fun provideFakeOverrides() { - while (fakeOverrideClassQueue.isNotEmpty()) { - val klass = fakeOverrideClassQueue.removeLast() - provideFakeOverrides(klass) + val entries = fakeOverrideCandidates.entries + while (entries.isNotEmpty()) { + val candidate = entries.last() + entries.remove(candidate) + provideFakeOverrides(candidate.key, candidate.value) } } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt index bb85d2b7d67..f42921a5002 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/BasicIrModuleDeserializer.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.library.IrLibrary +import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.protobuf.CodedInputStream import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite @@ -25,9 +26,10 @@ abstract class BasicIrModuleDeserializer( moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy, - private val containsErrorCode: Boolean = false, + libraryAbiVersion: KotlinAbiVersion, + private val containsErrorCode: Boolean = false ) : - IrModuleDeserializer(moduleDescriptor) { + IrModuleDeserializer(moduleDescriptor, libraryAbiVersion) { private val fileToDeserializerMap = mutableMapOf() diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt index 8ad6297765f..d80ffdd9027 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt @@ -6,14 +6,19 @@ package org.jetbrains.kotlin.backend.common.serialization import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.KotlinMangler -import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.ir.expressions.IrFunctionExpression +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid interface IdSignatureClashTracker { @@ -43,13 +48,13 @@ abstract class GlobalDeclarationTable( } } - open fun computeSignatureByDeclaration(declaration: IrDeclaration): IdSignature { + open fun computeSignatureByDeclaration(declaration: IrDeclaration, compatibleMode: Boolean): IdSignature { return table.getOrPut(declaration) { - publicIdSignatureComputer.composePublicIdSignature(declaration).also { clashTracker.commit(declaration, it) } + publicIdSignatureComputer.composePublicIdSignature(declaration, compatibleMode).also { clashTracker.commit(declaration, it) } } } - fun isExportedDeclaration(declaration: IrDeclaration): Boolean = with(mangler) { declaration.isExported() } + fun isExportedDeclaration(declaration: IrDeclaration, compatibleMode: Boolean): Boolean = with(mangler) { declaration.isExported(compatibleMode) } } open class DeclarationTable(globalTable: GlobalDeclarationTable) { @@ -62,24 +67,34 @@ open class DeclarationTable(globalTable: GlobalDeclarationTable) { signaturer.inFile(file?.symbol, block) } - fun isExportedDeclaration(declaration: IrDeclaration) = globalDeclarationTable.isExportedDeclaration(declaration) + + private fun IrDeclaration.isLocalDeclaration(compatibleMode: Boolean): Boolean { + return !isExportedDeclaration(this, compatibleMode) + } + + fun isExportedDeclaration(declaration: IrDeclaration, compatibleMode: Boolean) = + globalDeclarationTable.isExportedDeclaration(declaration, compatibleMode) protected open fun tryComputeBackendSpecificSignature(declaration: IrDeclaration): IdSignature? = null - private fun computeSignatureByDeclaration(declaration: IrDeclaration): IdSignature { - tryComputeBackendSpecificSignature(declaration)?.let { return it } - return if (declaration.isLocalDeclaration()) { - table.getOrPut(declaration) { signaturer.composeFileLocalIdSignature(declaration) } - } else globalDeclarationTable.computeSignatureByDeclaration(declaration) + private fun allocateIndexedSignature(declaration: IrDeclaration, compatibleMode: Boolean): IdSignature { + return table.getOrPut(declaration) { signaturer.composeFileLocalIdSignature(declaration, compatibleMode) } } - fun privateDeclarationSignature(declaration: IrDeclaration, builder: () -> IdSignature): IdSignature { - assert(declaration.isLocalDeclaration()) + private fun computeSignatureByDeclaration(declaration: IrDeclaration, compatibleMode: Boolean): IdSignature { + tryComputeBackendSpecificSignature(declaration)?.let { return it } + return if (declaration.isLocalDeclaration(compatibleMode)) { + allocateIndexedSignature(declaration, compatibleMode) + } else globalDeclarationTable.computeSignatureByDeclaration(declaration, compatibleMode) + } + + fun privateDeclarationSignature(declaration: IrDeclaration, compatibleMode: Boolean, builder: () -> IdSignature): IdSignature { + assert(declaration.isLocalDeclaration(compatibleMode)) return table.getOrPut(declaration) { builder() } } - fun signatureByDeclaration(declaration: IrDeclaration): IdSignature { - return computeSignatureByDeclaration(declaration) + fun signatureByDeclaration(declaration: IrDeclaration, compatibleMode: Boolean): IdSignature { + return computeSignatureByDeclaration(declaration, compatibleMode) } fun assumeDeclarationSignature(declaration: IrDeclaration, signature: IdSignature) { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt index bde4ece0255..7ccaeb565f5 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt @@ -140,7 +140,7 @@ class DescriptorByIdSignatureFinder( // We don't compute id for typealiases and classes. candidate is ClassDescriptor || candidate is TypeAliasDescriptor } else { - val candidateHash = with(mangler) { candidate.signatureMangle } + val candidateHash = with(mangler) { candidate.signatureMangle() } candidateHash == id } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt index a8580747e5c..1382dcc10d9 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.library.IrLibrary +import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.impl.* @@ -79,7 +80,7 @@ class CurrentModuleWithICDeserializer( private val irBuiltIns: IrBuiltIns, icData: List, icReaderFactory: (IrLibrary) -> IrModuleDeserializer) : - IrModuleDeserializer(delegate.moduleDescriptor) { + IrModuleDeserializer(delegate.moduleDescriptor, KotlinAbiVersion.CURRENT) { private val dirtyDeclarations = mutableMapOf() private val icKlib = ICKotlinLibrary(icData) 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 69a9dd646a5..f0f91101ec9 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 @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.InlineClassRepresentation import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.IrBody @@ -24,6 +25,7 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase +import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.* @@ -32,6 +34,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.protobuf.CodedInputStream import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite import org.jetbrains.kotlin.types.Variance +import kotlin.collections.set import org.jetbrains.kotlin.backend.common.serialization.proto.IrAnonymousInit as ProtoAnonymousInit import org.jetbrains.kotlin.backend.common.serialization.proto.IrClass as ProtoClass import org.jetbrains.kotlin.backend.common.serialization.proto.IrConstructor as ProtoConstructor @@ -73,6 +76,7 @@ class IrDeclarationDeserializer( private val skipMutableState: Boolean = false, additionalStatementOriginIndex: Map = emptyMap(), allowErrorStatementOrigins: Boolean = false, + private val compatibilityMode: CompatibilityMode ) { val bodyDeserializer = IrBodyDeserializer(builtIns, allowErrorNodes, irFactory, fileReader, this, statementOriginIndex + additionalStatementOriginIndex, allowErrorStatementOrigins) @@ -334,7 +338,7 @@ class IrDeclarationDeserializer( else -> computeMissingInlineClassRepresentationForCompatibility(this) } - fakeOverrideBuilder.enqueueClass(this, signature) + fakeOverrideBuilder.enqueueClass(this, signature, compatibilityMode) } } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt index 3dd0dc4eb87..ba96257bbb2 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt @@ -71,9 +71,7 @@ class FileDeserializationState( val symbolDeserializer = IrSymbolDeserializer( - linker.symbolTable, - fileReader, - file.symbol, + linker.symbolTable, fileReader, file.symbol, fileProto.actualList, ::addIdSignature, linker::handleExpectActualMapping, @@ -102,6 +100,7 @@ class FileDeserializationState( symbolDeserializer, linker.fakeOverrideBuilder.platformSpecificClassFilter, linker.fakeOverrideBuilder, + compatibilityMode = moduleDeserializer.compatibilityMode ) val fileDeserializer = IrFileDeserializer(file, fileReader, fileProto, symbolDeserializer, declarationDeserializer) 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 c5a687e44c4..550a60b8969 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 @@ -120,6 +120,7 @@ open class IrFileSerializer( val messageLogger: IrMessageLogger, private val declarationTable: DeclarationTable, private val expectDescriptorToSymbol: MutableMap, + private val compatibilityMode: CompatibilityMode, private val bodiesOnlyForInlines: Boolean = false, private val skipExpects: Boolean = false, // required for JS IC caches @@ -312,7 +313,7 @@ open class IrFileSerializer( } private fun protoIdSignature(declaration: IrDeclaration): Int { - val idSig = declarationTable.signatureByDeclaration(declaration) + val idSig = declarationTable.signatureByDeclaration(declaration, compatibilityMode.oldSignatures) return protoIdSignature(idSig) } @@ -1470,7 +1471,7 @@ open class IrFileSerializer( for (declaration in declarations) { val byteArray = serializeDeclaration(declaration).toByteArray() - val idSig = declarationTable.signatureByDeclaration(declaration) + val idSig = declarationTable.signatureByDeclaration(declaration, compatibleMode = false) // TODO: keep order similar // ^ TODO what does that mean? @@ -1521,8 +1522,8 @@ open class IrFileSerializer( } val byteArray = serializeDeclaration(it).toByteArray() - val idSig = declarationTable.signatureByDeclaration(it) - require(idSig === idSig.topLevelSignature()) { "IdSig: $idSig\ntopLevel: ${idSig.topLevelSignature()}" } + val idSig = declarationTable.signatureByDeclaration(it, compatibilityMode.oldSignatures) + require(idSig == idSig.topLevelSignature()) { "IdSig: $idSig\ntopLevel: ${idSig.topLevelSignature()}" } require(!idSig.isPackageSignature()) { "IsSig: $idSig\nDeclaration: ${it.render()}" } // TODO: keep order similar diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt index 1cbd18ff6bc..b5e8d29cb86 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleDeserializer.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.library.IrLibrary +import org.jetbrains.kotlin.library.KotlinAbiVersion internal fun IrSymbol.kind(): BinarySymbolData.SymbolKind { return when (this) { @@ -28,11 +29,35 @@ internal fun IrSymbol.kind(): BinarySymbolData.SymbolKind { } } -abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor) { +class CompatibilityMode(val abiVersion: KotlinAbiVersion) { + + init { + assert(abiVersion.isCompatible()) + } + + val oldSignatures: Boolean + get() { + if (abiVersion.minor == LAST_PRIVATE_SIG_ABI_VERSION.minor) { + return abiVersion.patch <= LAST_PRIVATE_SIG_ABI_VERSION.patch + } + return abiVersion.minor < LAST_PRIVATE_SIG_ABI_VERSION.minor + } + + companion object { + val LAST_PRIVATE_SIG_ABI_VERSION = KotlinAbiVersion(1, 5, 0) + + val WITH_PRIVATE_SIG = CompatibilityMode(LAST_PRIVATE_SIG_ABI_VERSION) + val WITH_COMMON_SIG = CompatibilityMode(KotlinAbiVersion.CURRENT) + + val CURRENT = WITH_COMMON_SIG + } +} + +abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor, val libraryAbiVersion: KotlinAbiVersion) { abstract operator fun contains(idSig: IdSignature): Boolean abstract fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol - open fun referenceSimpleFunctionByLocalSignature(file: IrFile, idSignature: IdSignature) : IrSimpleFunctionSymbol = + open fun referenceSimpleFunctionByLocalSignature(file: IrFile, idSignature: IdSignature): IrSimpleFunctionSymbol = error("Unsupported operation") open fun referencePropertyByLocalSignature(file: IrFile, idSignature: IdSignature): IrPropertySymbol = @@ -53,7 +78,9 @@ abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor) { open fun init(delegate: IrModuleDeserializer) {} - open fun addModuleReachableTopLevel(idSig: IdSignature) { error("Unsupported Operation (sig: $idSig") } + open fun addModuleReachableTopLevel(idSig: IdSignature) { + error("Unsupported Operation (sig: $idSig") + } open fun deserializeReachableDeclarations() { error("Unsupported Operation") } @@ -64,14 +91,16 @@ abstract class IrModuleDeserializer(val moduleDescriptor: ModuleDescriptor) { open val strategy: DeserializationStrategy = DeserializationStrategy.ONLY_DECLARATION_HEADERS open val isCurrent = false + + val compatibilityMode: CompatibilityMode get() = CompatibilityMode(libraryAbiVersion) } // Used to resolve built in symbols like `kotlin.ir.internal.*` or `kotlin.FunctionN` class IrModuleDeserializerWithBuiltIns( builtIns: IrBuiltIns, private val functionFactory: IrAbstractFunctionFactory, - private val delegate: IrModuleDeserializer -) : IrModuleDeserializer(delegate.moduleDescriptor) { + private val delegate: IrModuleDeserializer, +) : IrModuleDeserializer(delegate.moduleDescriptor, delegate.libraryAbiVersion) { init { // TODO: figure out how it should work for K/N @@ -205,7 +234,7 @@ class IrModuleDeserializerWithBuiltIns( open class CurrentModuleDeserializer( override val moduleFragment: IrModuleFragment, override val moduleDependencies: Collection -) : IrModuleDeserializer(moduleFragment.descriptor) { +) : IrModuleDeserializer(moduleFragment.descriptor, KotlinAbiVersion.CURRENT) { override fun contains(idSig: IdSignature): Boolean = false // TODO: override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt index 2e6657240a4..ce91796e418 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.SerializedIrModule -abstract class IrModuleSerializer(protected val messageLogger: IrMessageLogger) { +abstract class IrModuleSerializer(protected val messageLogger: IrMessageLogger, protected val compatibilityMode: CompatibilityMode) { abstract fun createSerializerForFile(file: IrFile): F /** diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 7336e0a06fd..849a45574e1 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -22,11 +22,6 @@ import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.file -import org.jetbrains.kotlin.library.IrLibrary -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.IrMessageLogger -import org.jetbrains.kotlin.ir.util.SymbolTable -import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.module @@ -90,7 +85,7 @@ abstract class KotlinIrLinker( protected abstract fun createModuleDeserializer( moduleDescriptor: ModuleDescriptor, - klib: IrLibrary?, + klib: KotlinLibrary?, strategy: DeserializationStrategy, ): IrModuleDeserializer diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/AbstractKotlinMangler.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/AbstractKotlinMangler.kt index b919e211ee9..ddaffc89962 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/AbstractKotlinMangler.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/AbstractKotlinMangler.kt @@ -11,6 +11,6 @@ import org.jetbrains.kotlin.ir.util.KotlinMangler abstract class AbstractKotlinMangler : KotlinMangler { override val String.hashMangle get() = cityHash64() - abstract fun getExportChecker(): KotlinExportChecker + abstract fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker abstract fun getMangleComputer(mode: MangleMode): KotlinMangleComputer } \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorBasedKotlinManglerImpl.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorBasedKotlinManglerImpl.kt index 2573a7cc2c1..5a4dbfba20d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorBasedKotlinManglerImpl.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorBasedKotlinManglerImpl.kt @@ -9,11 +9,11 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.* import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrEnumEntry import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.util.KotlinMangler +import org.jetbrains.kotlin.types.KotlinType abstract class DescriptorBasedKotlinManglerImpl : AbstractKotlinMangler(), KotlinMangler.DescriptorMangler { private fun withMode(mode: MangleMode, descriptor: DeclarationDescriptor): String = @@ -21,23 +21,15 @@ abstract class DescriptorBasedKotlinManglerImpl : AbstractKotlinMangler(), @@ -45,31 +37,26 @@ class Ir2DescriptorManglerAdapter(private val delegate: DescriptorBasedKotlinMan override val manglerName: String get() = delegate.manglerName - override fun IrDeclaration.isExported(): Boolean { + override fun IrDeclaration.isExported(compatibleMode: Boolean): Boolean { + return delegate.run { descriptor.isExported(compatibleMode) } + } + + override fun IrDeclaration.mangleString(): String { return when (this) { - is IrAnonymousInitializer -> false - is IrEnumEntry -> delegate.run { descriptor.isExportEnumEntry() } - is IrField -> delegate.run { descriptor.isExportField() } - else -> delegate.run { descriptor.isExported() } + is IrEnumEntry -> delegate.run { descriptor.mangleEnumEntryString() } + is IrField -> delegate.run { descriptor.mangleFieldString() } + else -> delegate.run { descriptor.mangleString() } } } - override val IrDeclaration.mangleString: String - get() { - return when (this) { - is IrEnumEntry -> delegate.run { descriptor.mangleEnumEntryString() } - is IrField -> delegate.run { descriptor.mangleFieldString() } - else -> delegate.run { descriptor.mangleString } - } - } + override fun IrDeclaration.signatureString(): String = delegate.run { descriptor.signatureString() } - override val IrDeclaration.signatureString: String - get() = delegate.run { descriptor.signatureString } + override fun IrDeclaration.fqnString(): String = delegate.run { descriptor.fqnString() } - override val IrDeclaration.fqnString: String - get() = delegate.run { descriptor.fqnString } + override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer = + error("Should not have been reached") - override fun getExportChecker() = error("Should not have been reached") - - override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer = error("Should not have been reached") + override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker { + error("Should not be called") + } } \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrBasedKotlinManglerImpl.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrBasedKotlinManglerImpl.kt index 3c31d54100e..973eebd2c93 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrBasedKotlinManglerImpl.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrBasedKotlinManglerImpl.kt @@ -12,14 +12,13 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.util.KotlinMangler abstract class IrBasedKotlinManglerImpl : AbstractKotlinMangler(), KotlinMangler.IrMangler { - override val IrDeclaration.mangleString: String - get() = getMangleComputer(MangleMode.FULL).computeMangle(this) - override val IrDeclaration.signatureString: String - get() = getMangleComputer(MangleMode.SIGNATURE).computeMangle(this) + override fun IrDeclaration.mangleString(): String = getMangleComputer(MangleMode.FULL).computeMangle(this) - override val IrDeclaration.fqnString: String - get() = getMangleComputer(MangleMode.FQNAME).computeMangle(this) + override fun IrDeclaration.signatureString(): String = getMangleComputer(MangleMode.SIGNATURE).computeMangle(this) - override fun IrDeclaration.isExported(): Boolean = getExportChecker().check(this, SpecialDeclarationType.REGULAR) + override fun IrDeclaration.fqnString(): String = getMangleComputer(MangleMode.FQNAME).computeMangle(this) + + override fun IrDeclaration.isExported(compatibleMode: Boolean): Boolean = + getExportChecker(compatibleMode).check(this, SpecialDeclarationType.REGULAR) } \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrExportCheckerVisitor.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrExportCheckerVisitor.kt index 8d77c1eb0e7..ae2cc2cc716 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrExportCheckerVisitor.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/ir/IrExportCheckerVisitor.kt @@ -23,15 +23,23 @@ import org.jetbrains.kotlin.name.SpecialNames abstract class IrExportCheckerVisitor(private val compatibleMode: Boolean) : KotlinExportChecker { private val compatibleChecker = CompatibleChecker() - private val newChecker = NewChecker() + private val checker = Checker() + /** + * @return true if [declaration] is exportable from klib point of view. + * Depending on [compatibleMode] option the same declaration could have FileLocal or Common signature. + */ override fun check(declaration: IrDeclaration, type: SpecialDeclarationType): Boolean { - return declaration.accept(if (compatibleMode) compatibleChecker else newChecker, null) + return declaration.accept(if (compatibleMode) compatibleChecker else checker, null) } abstract override fun IrDeclaration.isPlatformSpecificExported(): Boolean - private class NewChecker : IrElementVisitor { + /** + * Corresponding to export policy of klib ABI >= 1.6.0. + * In that case any non-local declaration (including type parameter and field) is exportable and could be navigated between modules + */ + private class Checker : IrElementVisitor { override fun visitElement(element: IrElement, data: Nothing?): Boolean { error("Should bot reach here ${element.render()}") } @@ -68,6 +76,14 @@ abstract class IrExportCheckerVisitor(private val compatibleMode: Boolean) : Kot override fun visitErrorDeclaration(declaration: IrErrorDeclaration, data: Nothing?): Boolean = false } + /** + * Was using for klib ABI version <= 1.5.0. In that case declaration which has itself or in their hierarchy private or local parent + * is considered non-exportable. + * + * Also type parameters and fields are not exportable. + * + * Is used to link libraries with ABI level <= 1.5.0 + */ private inner class CompatibleChecker : IrElementVisitor { private fun IrDeclaration.isExported(annotations: List, visibility: DescriptorVisibility?): Boolean { val speciallyExported = annotations.hasAnnotation(publishedApiAnnotation) || isPlatformSpecificExported() diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 990b3ea1ebd..14b240de686 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -105,7 +105,8 @@ fun generateKLib( irFactory: IrFactory, outputKlibPath: String, nopack: Boolean, - jsOutputName: String?, + abiVersion: KotlinAbiVersion = KotlinAbiVersion.CURRENT, + jsOutputName: String? ) { val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER) val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT @@ -196,6 +197,7 @@ fun generateKLib( nopack, perFile = false, hasErrors, + abiVersion, jsOutputName ) } @@ -495,15 +497,19 @@ fun serializeModuleIntoKlib( nopack: Boolean, perFile: Boolean, containsErrorCode: Boolean = false, + abiVersion: KotlinAbiVersion, jsOutputName: String?, ) { assert(files.size == moduleFragment.files.size) + val compatibilityMode = CompatibilityMode(abiVersion) + val serializedIr = JsIrModuleSerializer( messageLogger, moduleFragment.irBuiltins, - expectDescriptorToSymbol = expectDescriptorToSymbol, + expectDescriptorToSymbol, + compatibilityMode, skipExpects = !configuration.expectActualLinker ).serializedIrModule(moduleFragment) @@ -559,7 +565,7 @@ fun serializeModuleIntoKlib( val fullSerializedIr = SerializedIrModule(compiledKotlinFiles.map { it.irData }) val versions = KotlinLibraryVersioning( - abiVersion = KotlinAbiVersion.CURRENT, + abiVersion = compatibilityMode.abiVersion, libraryVersion = null, compilerVersion = KotlinCompilerVersion.VERSION, metadataVersion = KlibMetadataVersion.INSTANCE.toString(), diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt index e6dd420495f..f70b792ca87 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.backend.common.serialization.IdSignatureClashTracker import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt index 84a81912402..158bcb0683e 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.IrFileSerializer import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -19,6 +20,7 @@ class JsIrFileSerializer( messageLogger: IrMessageLogger, declarationTable: DeclarationTable, expectDescriptorToSymbol: MutableMap, + compatibilityMode: CompatibilityMode, skipExpects: Boolean, bodiesOnlyForInlines: Boolean = false, icMode: Boolean = false, @@ -26,6 +28,7 @@ class JsIrFileSerializer( messageLogger, declarationTable, expectDescriptorToSymbol, + compatibilityMode, bodiesOnlyForInlines = bodiesOnlyForInlines, skipExpects = skipExpects, skipMutableState = icMode, diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 48478bc63b3..18058b945a9 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.library.IrLibrary +import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.containsErrorCode @@ -37,17 +38,19 @@ class JsIrLinker( private val IrLibrary.libContainsErrorCode: Boolean get() = this is KotlinLibrary && this.containsErrorCode - override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer = - JsModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy, klib.libContainsErrorCode) + override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer = klib?.let { lib -> + JsModuleDeserializer(moduleDescriptor, lib, strategy, lib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, lib.libContainsErrorCode) + } ?: error("Expecting kotlin library") - private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy, allowErrorCode: Boolean) : - BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, allowErrorCode) + + private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy, libraryAbiVersion: KotlinAbiVersion, allowErrorCode: Boolean) : + BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion, allowErrorCode) override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection): IrModuleDeserializer { val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies) icData?.let { return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { lib -> - JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy, it.containsErrorCode) + JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy, KotlinAbiVersion.CURRENT, it.containsErrorCode) } } return currentModuleDeserializer diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt index 84399737dc0..83a76551c6b 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.IrModuleSerializer import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer @@ -19,11 +20,12 @@ class JsIrModuleSerializer( messageLogger: IrMessageLogger, irBuiltIns: IrBuiltIns, private val expectDescriptorToSymbol: MutableMap, + compatibilityMode: CompatibilityMode, val skipExpects: Boolean -) : IrModuleSerializer(messageLogger) { +) : IrModuleSerializer(messageLogger, compatibilityMode) { private val globalDeclarationTable = JsGlobalDeclarationTable(irBuiltIns) override fun createSerializerForFile(file: IrFile): JsIrFileSerializer = - JsIrFileSerializer(messageLogger, DeclarationTable(globalDeclarationTable), expectDescriptorToSymbol, skipExpects = skipExpects) + JsIrFileSerializer(messageLogger, DeclarationTable(globalDeclarationTable), expectDescriptorToSymbol, skipExpects = skipExpects, compatibilityMode = compatibilityMode) } \ No newline at end of file diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsMangler.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsMangler.kt index 0738cb64448..0d3065b2e85 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsMangler.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsMangler.kt @@ -19,11 +19,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclaration abstract class AbstractJsManglerIr : IrBasedKotlinManglerImpl() { - companion object { - private val exportChecker = JsIrExportChecker() - } - - private class JsIrExportChecker : IrExportCheckerVisitor() { + private class JsIrExportChecker(compatibleMode: Boolean) : IrExportCheckerVisitor(compatibleMode) { override fun IrDeclaration.isPlatformSpecificExported() = false } @@ -31,7 +27,7 @@ abstract class AbstractJsManglerIr : IrBasedKotlinManglerImpl() { override fun copy(newMode: MangleMode): IrMangleComputer = JsIrManglerComputer(builder, newMode) } - override fun getExportChecker(): KotlinExportChecker = exportChecker + override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker = JsIrExportChecker(compatibleMode) override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer { return JsIrManglerComputer(StringBuilder(256), mode) @@ -54,7 +50,7 @@ abstract class AbstractJsDescriptorMangler : DescriptorBasedKotlinManglerImpl() override fun copy(newMode: MangleMode): DescriptorMangleComputer = JsDescriptorManglerComputer(builder, newMode) } - override fun getExportChecker(): KotlinExportChecker = exportChecker + override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker = exportChecker override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer { return JsDescriptorManglerComputer(StringBuilder(256), mode) diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt index 5922cebcdb0..26b7219872f 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt @@ -21,12 +21,13 @@ import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.symbols.isPublicApi import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.library.IrLibrary +import org.jetbrains.kotlin.library.KotlinAbiVersion +import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment @@ -52,17 +53,17 @@ class JvmIrLinker( moduleDescriptor.name.asString().startsWith(") : - IrModuleDeserializer(moduleDescriptor) { + IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) { // TODO: implement proper check whether `idSig` belongs to this module override fun contains(idSig: IdSignature): Boolean = true diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt index b9fbb71dd68..ed43e10f7da 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmMangler.kt @@ -28,11 +28,7 @@ import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField abstract class AbstractJvmManglerIr : IrBasedKotlinManglerImpl() { - companion object { - private val exportChecker = JvmIrExportChecker() - } - - private class JvmIrExportChecker : IrExportCheckerVisitor() { + private class JvmIrExportChecker(compatibleMode: Boolean) : IrExportCheckerVisitor(compatibleMode) { override fun IrDeclaration.isPlatformSpecificExported() = false } @@ -44,7 +40,7 @@ abstract class AbstractJvmManglerIr : IrBasedKotlinManglerImpl() { irFunction.isFromJava() } - override fun getExportChecker(): KotlinExportChecker = exportChecker + override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker = JvmIrExportChecker(compatibleMode) override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer { return JvmIrManglerComputer(StringBuilder(256), mode) @@ -71,8 +67,7 @@ abstract class AbstractJvmDescriptorMangler(private val mainDetector: MainFuncti override fun addReturnTypeSpecialCase(functionDescriptor: FunctionDescriptor): Boolean = functionDescriptor is JavaMethodDescriptor - override fun copy(newMode: MangleMode): DescriptorMangleComputer = - JvmDescriptorManglerComputer(builder, mainDetector, newMode) + override fun copy(newMode: MangleMode): DescriptorMangleComputer = JvmDescriptorManglerComputer(builder, mainDetector, newMode) private fun isMainFunction(descriptor: FunctionDescriptor): Boolean = mainDetector?.isMain(descriptor) ?: false @@ -89,10 +84,14 @@ abstract class AbstractJvmDescriptorMangler(private val mainDetector: MainFuncti return if (isJavaField) MangleConstant.JAVA_FIELD_SUFFIX else null } - override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Nothing?) {} // SKIP in case of synthetic properties + override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Nothing?) { + // In general, having module descriptor as `containingDeclaration` for regular declaration is considered an error (in JS/Native) + // because there should be `PackageFragmentDescriptor` in between + // but on JVM there is `SyntheticJavaPropertyDescriptor` whose parent is a module. So let just skip it. + } } - override fun getExportChecker(): KotlinExportChecker = exportChecker + override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker = exportChecker override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer { return JvmDescriptorManglerComputer(StringBuilder(256), mainDetector, mode) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt index dd92a497702..e181406372b 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import junit.framework.TestCase +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataIncrementalSerializer @@ -134,7 +135,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() { protected fun serializeModule(irModuleFragment: IrModuleFragment, bindingContext: BindingContext, stdlib: KotlinLibrary, containsErrorCode: Boolean, expectActualSymbols: MutableMap, skipExpect: Boolean): String { val ktFiles = myFiles.psiFiles val serializedIr = - JsIrModuleSerializer(IrMessageLogger.None, irModuleFragment.irBuiltins, expectActualSymbols, skipExpect).serializedIrModule( + JsIrModuleSerializer(IrMessageLogger.None, irModuleFragment.irBuiltins, expectActualSymbols, CompatibilityMode.CURRENT, skipExpect).serializedIrModule( irModuleFragment ) diff --git a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt index 23183586a9e..61fa56b008d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt @@ -14,6 +14,7 @@ import com.intellij.psi.PsiManager import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor @@ -492,6 +493,7 @@ class GenerateIrRuntime { emptyList(), true, perFile, + abiVersion = KotlinAbiVersion.CURRENT, jsOutputName = null ) @@ -506,7 +508,7 @@ class GenerateIrRuntime { private fun doSerializeIrModule(module: IrModuleFragment): SerializedIrModule { - val serializedIr = JsIrModuleSerializer(IrMessageLogger.None, module.irBuiltins, mutableMapOf(), true).serializedIrModule(module) + val serializedIr = JsIrModuleSerializer(IrMessageLogger.None, module.irBuiltins, mutableMapOf(), CompatibilityMode.CURRENT, true).serializedIrModule(module) return serializedIr } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index 8fe7819005a..dfc92e72011 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -5,6 +5,7 @@ import org.jetbrains.kotlin.backend.common.IrValidator import org.jetbrains.kotlin.backend.common.IrValidatorConfig import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.* +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer import org.jetbrains.kotlin.backend.konan.MemoryModel import org.jetbrains.kotlin.backend.konan.llvm.* @@ -155,7 +156,7 @@ internal val serializerPhase = konanUnitPhase( serializedIr = irModule?.let { ir -> KonanIrModuleSerializer( - messageLogger, ir.irBuiltins, expectDescriptorToSymbol, skipExpects = !expectActualLinker + messageLogger, ir.irBuiltins, expectDescriptorToSymbol, skipExpects = !expectActualLinker, compatibilityMode = CompatibilityMode.CURRENT ).serializedIrModule(ir) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt index af85951e56e..c0ab278b06e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt @@ -34,9 +34,9 @@ import org.jetbrains.kotlin.name.Name object KonanBinaryInterface { private val mangler = object : AbstractKonanIrMangler(true) {} - private val exportChecker = mangler.getExportChecker() + private val exportChecker = mangler.getExportChecker(compatibleMode = true) - val IrFunction.functionName: String get() = mangler.run { signatureString } + val IrFunction.functionName: String get() = mangler.run { signatureString() } val IrFunction.symbolName: String get() = funSymbolNameImpl() val IrField.symbolName: String get() = @@ -65,7 +65,7 @@ object KonanBinaryInterface { return name // no wrapping currently required } - return withPrefix(MangleConstant.FUN_PREFIX, mangler.run { mangleString }) + return withPrefix(MangleConstant.FUN_PREFIX, mangler.run { mangleString() }) } private fun IrField.fieldSymbolNameImpl(): String { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt index 52d1371d352..439cf4da51e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt @@ -1,5 +1,6 @@ package org.jetbrains.kotlin.backend.konan.serialization +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.IrFileSerializer import org.jetbrains.kotlin.backend.konan.RuntimeNames @@ -16,8 +17,9 @@ class KonanIrFileSerializer( declarationTable: DeclarationTable, expectDescriptorToSymbol: MutableMap, skipExpects: Boolean, - bodiesOnlyForInlines: Boolean = false -): IrFileSerializer(messageLogger, declarationTable, expectDescriptorToSymbol, skipExpects = skipExpects, bodiesOnlyForInlines = bodiesOnlyForInlines) { + bodiesOnlyForInlines: Boolean = false, + compatibilityMode: CompatibilityMode +): IrFileSerializer(messageLogger, declarationTable, expectDescriptorToSymbol, compatibilityMode, bodiesOnlyForInlines, skipExpects) { override fun backendSpecificExplicitRoot(node: IrAnnotationContainer): Boolean { val fqn = when (node) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt index da413a51569..6171c8719d6 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleSerializer.kt @@ -1,6 +1,7 @@ package org.jetbrains.kotlin.backend.konan.serialization -import org.jetbrains.kotlin.backend.common.serialization.* +import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode +import org.jetbrains.kotlin.backend.common.serialization.IrModuleSerializer import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -13,8 +14,9 @@ class KonanIrModuleSerializer( messageLogger: IrMessageLogger, irBuiltIns: IrBuiltIns, private val expectDescriptorToSymbol: MutableMap, - val skipExpects: Boolean -) : IrModuleSerializer(messageLogger) { + val skipExpects: Boolean, + compatibilityMode: CompatibilityMode +) : IrModuleSerializer(messageLogger, compatibilityMode) { private val globalDeclarationTable = KonanGlobalDeclarationTable(irBuiltIns) @@ -28,5 +30,5 @@ class KonanIrModuleSerializer( file.fileEntry.name != IrProviderForCEnumAndCStructStubs.cTypeDefinitionsFileName override fun createSerializerForFile(file: IrFile): KonanIrFileSerializer = - KonanIrFileSerializer(messageLogger, KonanDeclarationTable(globalDeclarationTable), expectDescriptorToSymbol, skipExpects = skipExpects) + KonanIrFileSerializer(messageLogger, KonanDeclarationTable(globalDeclarationTable), expectDescriptorToSymbol, skipExpects = skipExpects, compatibilityMode = compatibilityMode) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt index 2a02eebc4d0..23470525ecf 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt @@ -41,7 +41,7 @@ import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.library.IrLibrary +import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -93,16 +93,16 @@ internal class KonanIrLinker( private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) } override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, KonanManglerIr, builtIns, KonanFakeOverrideClassFilter) - override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer { + override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer { if (moduleDescriptor === forwardModuleDescriptor) { return forwardDeclarationDeserializer ?: error("forward declaration deserializer expected") } - if (klib is KotlinLibrary && klib.isInteropLibrary()) { + if (klib != null && klib.isInteropLibrary()) { // See https://youtrack.jetbrains.com/issue/KT-43517. // Disabling this flag forces linker to generate IR. val isCached = false //cachedLibraries.isLibraryCached(klib) - return KonanInteropModuleDeserializer(moduleDescriptor, isCached) + return KonanInteropModuleDeserializer(moduleDescriptor, klib, isCached) } return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy) @@ -110,16 +110,17 @@ internal class KonanIrLinker( private inner class KonanModuleDeserializer( moduleDescriptor: ModuleDescriptor, - klib: IrLibrary, + klib: KotlinLibrary, strategy: DeserializationStrategy - ): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategy){ + ): BasicIrModuleDeserializer(this@KonanIrLinker, moduleDescriptor, klib, strategy, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) { override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList()) } private inner class KonanInteropModuleDeserializer( moduleDescriptor: ModuleDescriptor, + klib: KotlinLibrary, private val isLibraryCached: Boolean - ) : IrModuleDeserializer(moduleDescriptor) { + ) : IrModuleDeserializer(moduleDescriptor, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT) { init { assert(moduleDescriptor.kotlinLibrary.isInteropLibrary()) } @@ -170,7 +171,7 @@ internal class KonanIrLinker( override val moduleDependencies: Collection = listOfNotNull(forwardDeclarationDeserializer) } - private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor) { + private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) { init { assert(moduleDescriptor.isForwardDeclarationModule) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt index 0169c9c5415..0fb5d0fe486 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanMangler.kt @@ -1,5 +1,6 @@ package org.jetbrains.kotlin.backend.konan.serialization +import org.jetbrains.kotlin.backend.common.serialization.mangle.KotlinExportChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.DescriptorBasedKotlinManglerImpl import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.DescriptorExportCheckerVisitor @@ -12,40 +13,42 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.hasAnnotation +import org.jetbrains.kotlin.types.KotlinType abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrBasedKotlinManglerImpl() { - override fun getExportChecker(): IrExportCheckerVisitor = KonanIrExportChecker() + override fun getExportChecker(compatibleMode: Boolean): IrExportCheckerVisitor = KonanIrExportChecker(compatibleMode) - override fun getMangleComputer(mode: MangleMode): IrMangleComputer = - KonanIrManglerComputer(StringBuilder(256), mode, withReturnType) + override fun getMangleComputer(mode: MangleMode): IrMangleComputer = KonanIrManglerComputer(StringBuilder(256), mode, withReturnType) - private class KonanIrExportChecker : IrExportCheckerVisitor() { - override fun IrDeclaration.isPlatformSpecificExported(): Boolean { - if (this is IrSimpleFunction) if (isFakeOverride) return false + override fun IrDeclaration.isPlatformSpecificExport(): Boolean { + if (this is IrSimpleFunction) if (isFakeOverride) return false - // TODO: revise - if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) { - // Treat any `@SymbolName` declaration as exported. - return true - } - if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) { + // TODO: revise + if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) { + // Treat any `@SymbolName` declaration as exported. + return true + } + if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) { // Treat any `@GCUnsafeCall` declaration as exported. return true } if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) { - // Treat any `@ExportForCppRuntime` declaration as exported. - return true - } - if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) { - // Treat `@CName` declaration as exported. - return true - } - if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) { - return true - } - - return false + // Treat any `@ExportForCppRuntime` declaration as exported. + return true } + if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) { + // Treat `@CName` declaration as exported. + return true + } + if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) { + return true + } + + return false + } + + private inner class KonanIrExportChecker(compatibleMode: Boolean) : IrExportCheckerVisitor(compatibleMode) { + override fun IrDeclaration.isPlatformSpecificExported(): Boolean = isPlatformSpecificExport() } private class KonanIrManglerComputer(builder: StringBuilder, mode: MangleMode, private val withReturnType: Boolean) : IrMangleComputer(builder, mode) { @@ -88,39 +91,40 @@ abstract class AbstractKonanIrMangler(private val withReturnType: Boolean) : IrB object KonanManglerIr : AbstractKonanIrMangler(false) abstract class AbstractKonanDescriptorMangler : DescriptorBasedKotlinManglerImpl() { - override fun getExportChecker(): DescriptorExportCheckerVisitor = KonanDescriptorExportChecker() + override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker = KonanDescriptorExportChecker() - override fun getMangleComputer(mode: MangleMode): DescriptorMangleComputer = - KonanDescriptorMangleComputer(StringBuilder(256), mode) + override fun getMangleComputer(mode: MangleMode): DescriptorMangleComputer = KonanDescriptorMangleComputer(StringBuilder(256), mode) - private class KonanDescriptorExportChecker : DescriptorExportCheckerVisitor() { - override fun DeclarationDescriptor.isPlatformSpecificExported(): Boolean { - if (this is SimpleFunctionDescriptor) { - if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) return false - } - // TODO: revise - if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) { - // Treat any `@SymbolName` declaration as exported. - return true - } - if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) { - // Treat any `@GCUnsafeCall` declaration as exported. - return true - } - if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) { - // Treat any `@ExportForCppRuntime` declaration as exported. - return true - } - if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) { - // Treat `@CName` declaration as exported. - return true - } - if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) { - return true - } + private inner class KonanDescriptorExportChecker : DescriptorExportCheckerVisitor() { + override fun DeclarationDescriptor.isPlatformSpecificExported(): Boolean = isPlatformSpecificExport() + } - return false + override fun DeclarationDescriptor.isPlatformSpecificExport(): Boolean { + if (this is SimpleFunctionDescriptor) { + if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) return false } + // TODO: revise + if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) { + // Treat any `@SymbolName` declaration as exported. + return true + } + if (annotations.hasAnnotation(KonanFqNames.gcUnsafeCall)) { + // Treat any `@GCUnsafeCall` declaration as exported. + return true + } + if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) { + // Treat any `@ExportForCppRuntime` declaration as exported. + return true + } + if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) { + // Treat `@CName` declaration as exported. + return true + } + if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) { + return true + } + + return false } private class KonanDescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) : DescriptorMangleComputer(builder, mode) {