[KLIB] Introduce compatible mode for klibs.

Based on library ABI version linker could decide which signature mode
to be used to guarantee backward compatibility.
This commit is contained in:
Roman Artemev
2021-05-26 19:42:06 +03:00
committed by TeamCityServer
parent 3e99951a66
commit b5c28c1912
38 changed files with 343 additions and 256 deletions
@@ -14,18 +14,15 @@ import org.jetbrains.kotlin.fir.signaturer.FirMangler
@NoMutableState
class FirJvmKotlinMangler(private val session: FirSession) : AbstractKotlinMangler<FirDeclaration>(), 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<FirDeclaration> {
override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<FirDeclaration> {
return object : KotlinExportChecker<FirDeclaration> {
override fun check(declaration: FirDeclaration, type: SpecialDeclarationType): Boolean = true
@@ -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)
}
@@ -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<IrOverridableMember> = emptyList()) {
IrOverridingUtil(irBuiltIns, FakeOverrideBuilderForLowerings())
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers)
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers, compatibilityMode = false)
.forEach { addChild(it) }
}
@@ -34,7 +34,7 @@ import kotlin.math.abs
private fun <T> 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 {
@@ -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<IrOverridableMember> = emptyList()
implementedMembers: List<IrOverridableMember> = emptyList(),
compatibilityMode: Boolean
): List<IrOverridableMember> {
val overriddenMembers = (clazz.declarations.filterIsInstance<IrOverridableMember>() + implementedMembers)
.flatMap { member -> member.overriddenSymbols.map { it.owner } }
@@ -189,7 +190,7 @@ class IrOverridingUtil(
val unoverriddenSuperMembersGroupedByName = unoverriddenSuperMembers.groupBy { it.name }
val fakeOverrides = mutableListOf<IrOverridableMember>()
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<IrOverridableMember>,
membersFromCurrent: List<IrOverridableMember>,
current: IrClass
current: IrClass,
compatibilityMode: Boolean
) {
val notOverridden = membersFromSupertypes.toMutableSet()
@@ -217,7 +219,7 @@ class IrOverridingUtil(
}
val addedFakeOverrides = mutableListOf<IrOverridableMember>()
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<IrOverridableMember>,
addedFakeOverrides: MutableList<IrOverridableMember>
addedFakeOverrides: MutableList<IrOverridableMember>,
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<IrOverridableMember>,
current: IrClass,
addedFakeOverrides: MutableList<IrOverridableMember>
addedFakeOverrides: MutableList<IrOverridableMember>,
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(
@@ -14,14 +14,16 @@ interface KotlinMangler<D : Any> {
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
@@ -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
@@ -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<IrClass>()
fun enqueueClass(clazz: IrClass, signature: IdSignature) {
// private class CompatibilityMode(val oldSignatures: Boolean)
private val fakeOverrideCandidates = mutableMapOf<IrClass, CompatibilityMode>()
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)
}
}
}
@@ -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<IrFile, IrFileDeserializer>()
@@ -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) {
@@ -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
}
}
@@ -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<SerializedIrFile>,
icReaderFactory: (IrLibrary) -> IrModuleDeserializer) :
IrModuleDeserializer(delegate.moduleDescriptor) {
IrModuleDeserializer(delegate.moduleDescriptor, KotlinAbiVersion.CURRENT) {
private val dirtyDeclarations = mutableMapOf<IdSignature, IrSymbol>()
private val icKlib = ICKotlinLibrary(icData)
@@ -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<String, IrStatementOrigin> = 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)
}
}
}
@@ -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)
@@ -120,6 +120,7 @@ open class IrFileSerializer(
val messageLogger: IrMessageLogger,
private val declarationTable: DeclarationTable,
private val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
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
@@ -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>
) : 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 {
@@ -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<F : IrFileSerializer>(protected val messageLogger: IrMessageLogger) {
abstract class IrModuleSerializer<F : IrFileSerializer>(protected val messageLogger: IrMessageLogger, protected val compatibilityMode: CompatibilityMode) {
abstract fun createSerializerForFile(file: IrFile): F
/**
@@ -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
@@ -11,6 +11,6 @@ import org.jetbrains.kotlin.ir.util.KotlinMangler
abstract class AbstractKotlinMangler<D : Any> : KotlinMangler<D> {
override val String.hashMangle get() = cityHash64()
abstract fun getExportChecker(): KotlinExportChecker<D>
abstract fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<D>
abstract fun getMangleComputer(mode: MangleMode): KotlinMangleComputer<D>
}
@@ -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<DeclarationDescriptor>(), KotlinMangler.DescriptorMangler {
private fun withMode(mode: MangleMode, descriptor: DeclarationDescriptor): String =
@@ -21,23 +21,15 @@ abstract class DescriptorBasedKotlinManglerImpl : AbstractKotlinMangler<Declarat
override fun ClassDescriptor.mangleEnumEntryString(): String = withMode(MangleMode.FQNAME, this)
override fun ClassDescriptor.isExportEnumEntry(): Boolean =
getExportChecker().check(this, SpecialDeclarationType.ENUM_ENTRY)
override fun PropertyDescriptor.mangleFieldString(): String = mangleString()
override fun PropertyDescriptor.isExportField(): Boolean = false
override fun DeclarationDescriptor.mangleString(): String = withMode(MangleMode.FULL, this)
override fun PropertyDescriptor.mangleFieldString(): String = error("Fields supposed to be non-exporting")
override fun DeclarationDescriptor.signatureString(): String = withMode(MangleMode.SIGNATURE, this)
override val DeclarationDescriptor.mangleString: String
get() = withMode(MangleMode.FULL, this)
override fun DeclarationDescriptor.fqnString(): String = withMode(MangleMode.FQNAME, this)
override val DeclarationDescriptor.signatureString: String
get() = withMode(MangleMode.SIGNATURE, this)
override val DeclarationDescriptor.fqnString: String
get() = withMode(MangleMode.FQNAME, this)
override fun DeclarationDescriptor.isExported(): Boolean = getExportChecker().check(this, SpecialDeclarationType.REGULAR)
override fun DeclarationDescriptor.isExported(compatibleMode: Boolean): Boolean = getExportChecker(compatibleMode).check(this, SpecialDeclarationType.REGULAR)
}
class Ir2DescriptorManglerAdapter(private val delegate: DescriptorBasedKotlinManglerImpl) : AbstractKotlinMangler<IrDeclaration>(),
@@ -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<IrDeclaration> =
error("Should not have been reached")
override fun getExportChecker() = error("Should not have been reached")
override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer<IrDeclaration> = error("Should not have been reached")
override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<IrDeclaration> {
error("Should not be called")
}
}
@@ -12,14 +12,13 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.util.KotlinMangler
abstract class IrBasedKotlinManglerImpl : AbstractKotlinMangler<IrDeclaration>(), 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)
}
@@ -23,15 +23,23 @@ import org.jetbrains.kotlin.name.SpecialNames
abstract class IrExportCheckerVisitor(private val compatibleMode: Boolean) : KotlinExportChecker<IrDeclaration> {
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<Boolean, Nothing?> {
/**
* 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<Boolean, Nothing?> {
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<Boolean, Nothing?> {
private fun IrDeclaration.isExported(annotations: List<IrConstructorCall>, visibility: DescriptorVisibility?): Boolean {
val speciallyExported = annotations.hasAnnotation(publishedApiAnnotation) || isPlatformSpecificExported()
@@ -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(),
@@ -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
@@ -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<DeclarationDescriptor, IrSymbol>,
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,
@@ -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>): 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
@@ -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<DeclarationDescriptor, IrSymbol>,
compatibilityMode: CompatibilityMode,
val skipExpects: Boolean
) : IrModuleSerializer<JsIrFileSerializer>(messageLogger) {
) : IrModuleSerializer<JsIrFileSerializer>(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)
}
@@ -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<IrDeclaration> = exportChecker
override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<IrDeclaration> = JsIrExportChecker(compatibleMode)
override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer<IrDeclaration> {
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<DeclarationDescriptor> = exportChecker
override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<DeclarationDescriptor> = exportChecker
override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer<DeclarationDescriptor> {
return JsDescriptorManglerComputer(StringBuilder(256), mode)
@@ -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("<dependencies of ")
// TODO: implement special Java deserializer
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: KotlinLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {
if (klib != null) {
assert(moduleDescriptor.getCapability(KlibModuleOrigin.CAPABILITY) != null)
return JvmModuleDeserializer(moduleDescriptor, klib, strategy)
return JvmModuleDeserializer(moduleDescriptor, klib, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, strategy)
}
return MetadataJVMModuleDeserializer(moduleDescriptor, emptyList())
}
private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy) :
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy)
private inner class JvmModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, libraryAbiVersion: KotlinAbiVersion, strategy: DeserializationStrategy) :
BasicIrModuleDeserializer(this, moduleDescriptor, klib, strategy, libraryAbiVersion)
private fun DeclarationDescriptor.isJavaDescriptor(): Boolean {
if (this is PackageFragmentDescriptor) {
@@ -122,7 +123,7 @@ class JvmIrLinker(
}
private inner class MetadataJVMModuleDeserializer(moduleDescriptor: ModuleDescriptor, dependencies: List<IrModuleDeserializer>) :
IrModuleDeserializer(moduleDescriptor) {
IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) {
// TODO: implement proper check whether `idSig` belongs to this module
override fun contains(idSig: IdSignature): Boolean = true
@@ -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<IrDeclaration> = exportChecker
override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<IrDeclaration> = JvmIrExportChecker(compatibleMode)
override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer<IrDeclaration> {
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<DeclarationDescriptor> = exportChecker
override fun getExportChecker(compatibleMode: Boolean): KotlinExportChecker<DeclarationDescriptor> = exportChecker
override fun getMangleComputer(mode: MangleMode): KotlinMangleComputer<DeclarationDescriptor> {
return JvmDescriptorManglerComputer(StringBuilder(256), mainDetector, mode)
@@ -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<DeclarationDescriptor, IrSymbol>, 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
)
@@ -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
}
@@ -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)
}
@@ -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 {
@@ -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<DeclarationDescriptor, IrSymbol>,
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) {
@@ -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<DeclarationDescriptor, IrSymbol>,
val skipExpects: Boolean
) : IrModuleSerializer<KonanIrFileSerializer>(messageLogger) {
val skipExpects: Boolean,
compatibilityMode: CompatibilityMode
) : IrModuleSerializer<KonanIrFileSerializer>(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)
}
@@ -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<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer)
}
private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor) {
private inner class KonanForwardDeclarationModuleDeserializer(moduleDescriptor: ModuleDescriptor) : IrModuleDeserializer(moduleDescriptor, KotlinAbiVersion.CURRENT) {
init {
assert(moduleDescriptor.isForwardDeclarationModule)
}
@@ -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<DeclarationDescriptor> = 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) {