[StubIr][UniqId] Extend StubIrUniqIdProvider

1. Add support for classes and constructors
2. Lift restrictions on functions and properties
This commit is contained in:
Sergey Bogolepov
2019-12-12 11:44:18 +07:00
committed by Sergey Bogolepov
parent 47fe152748
commit c42b588f12
3 changed files with 50 additions and 17 deletions
@@ -53,7 +53,7 @@ interface InteropMangler {
/** /**
* Mangler that mimics behaviour of the one from the Kotlin compiler. * Mangler that mimics behaviour of the one from the Kotlin compiler.
*/ */
class KotlinLikeInteropMangler(val context: ManglingContext = ManglingContext.Empty) : InteropMangler { class KotlinLikeInteropMangler(context: ManglingContext = ManglingContext.Empty) : InteropMangler {
private val prefix = context.prefix private val prefix = context.prefix
@@ -33,7 +33,7 @@ internal class ModuleMetadataEmitter(
private val packageFqName: String private val packageFqName: String
) : StubIrVisitor<StubContainer?, Unit> { ) : StubIrVisitor<StubContainer?, Unit> {
private val uniqIds = StubIrUniqIdProvider() private val uniqIds = StubIrUniqIdProvider(ManglingContext.Module(packageFqName))
private val classes = mutableListOf<KmClass>() private val classes = mutableListOf<KmClass>()
private val properties = mutableListOf<KmProperty>() private val properties = mutableListOf<KmProperty>()
@@ -7,31 +7,27 @@ package org.jetbrains.kotlin.native.interop.gen
import kotlinx.metadata.klib.UniqId import kotlinx.metadata.klib.UniqId
import org.jetbrains.kotlin.backend.common.serialization.cityHash64 import org.jetbrains.kotlin.backend.common.serialization.cityHash64
internal class StubIrUniqIdProvider { /**
private val mangler = KotlinLikeInteropMangler() * Returns stable [UniqId] for the given element of StubIr.
*/
internal class StubIrUniqIdProvider(private val context: ManglingContext) {
private val mangler: InteropMangler = KotlinLikeInteropMangler(context)
fun createChild(suffix: String): StubIrUniqIdProvider =
StubIrUniqIdProvider(ManglingContext.Entity(suffix, context))
fun uniqIdForFunction(function: FunctionStub): UniqId = with(mangler) { fun uniqIdForFunction(function: FunctionStub): UniqId = with(mangler) {
when (function.origin) { when (function.origin) {
is StubOrigin.Function -> function.origin.function.uniqueSymbolName is StubOrigin.Function -> function.origin.function.uniqueSymbolName
is StubOrigin.ObjCMethod -> { is StubOrigin.ObjCMethod -> function.origin.method.uniqueSymbolName
require(this.context is ManglingContext.Entity) { is StubOrigin.ObjCCategoryInitMethod -> "${function.origin.method.uniqueSymbolName}#Create"
"Unexpected mangling context $context for method ${function.name}."
}
function.origin.method.uniqueSymbolName
}
// TODO: What to do with "create" method in Objective-C categories?
else -> error("Unexpected origin ${function.origin} for function ${function.name}.") else -> error("Unexpected origin ${function.origin} for function ${function.name}.")
}.toUniqId() }.toUniqId()
} }
fun uniqIdForProperty(property: PropertyStub): UniqId = with (mangler) { fun uniqIdForProperty(property: PropertyStub): UniqId = with (mangler) {
when (property.origin) { when (property.origin) {
is StubOrigin.ObjCProperty -> { is StubOrigin.ObjCProperty -> property.origin.property.uniqueSymbolName
require(this.context is ManglingContext.Entity) {
"Unexpected mangling context $context for property ${property.name}."
}
property.origin.property.uniqueSymbolName
}
is StubOrigin.Constant -> property.origin.constantDef.uniqueSymbolName is StubOrigin.Constant -> property.origin.constantDef.uniqueSymbolName
is StubOrigin.Global -> property.origin.global.uniqueSymbolName is StubOrigin.Global -> property.origin.global.uniqueSymbolName
// TODO: What to do with origin for enum entries and struct fields? // TODO: What to do with origin for enum entries and struct fields?
@@ -51,6 +47,43 @@ internal class StubIrUniqIdProvider {
?: error("Unexpected origin ${typeAlias.origin} for typealias ${typeAlias.alias.fqName}.") ?: error("Unexpected origin ${typeAlias.origin} for typealias ${typeAlias.alias.fqName}.")
}.toUniqId() }.toUniqId()
private fun InteropMangler.uniqSymbolNameForClass(origin: StubOrigin): String? = when (origin) {
is StubOrigin.ObjCClass -> if (origin.isMeta) {
origin.clazz.metaClassUniqueSymbolName
} else {
origin.clazz.uniqueSymbolName
}
is StubOrigin.ObjCProtocol -> if (origin.isMeta) {
origin.protocol.metaClassUniqueSymbolName
} else {
origin.protocol.uniqueSymbolName
}
is StubOrigin.Struct -> origin.struct.uniqueSymbolName
is StubOrigin.Enum -> origin.enum.uniqueSymbolName
else -> null
}
fun uniqIdForClass(classStub: ClassStub): UniqId = with (mangler) {
when (classStub) {
is ClassStub.Simple,
is ClassStub.Enum -> uniqSymbolNameForClass(classStub.origin)
is ClassStub.Companion -> "${context.prefix}#Companion"
} ?: error("Unexpected origin ${classStub.origin} for class ${classStub.classifier.fqName}.")
}.toUniqId()
private fun InteropMangler.uniqSymbolNameForConstructor(origin: StubOrigin): String? = when (origin) {
is StubOrigin.SyntheticDefaultConstructor -> "${context.prefix}#Constructor"
is StubOrigin.Enum -> "${origin.enum.uniqueSymbolName}#Constructor"
is StubOrigin.Struct -> "${origin.struct.uniqueSymbolName}#Constructor"
is StubOrigin.ObjCMethod -> "${origin.method.uniqueSymbolName}#Constructor"
else -> null
}
fun uniqIdForConstructor(constructorStub: ConstructorStub): UniqId = with (mangler) {
uniqSymbolNameForConstructor(constructorStub.origin)
?: error("Unexpected origin ${constructorStub.origin} for constructor.")
}.toUniqId()
/** /**
* MSB should be set to 1 for public declarations. * MSB should be set to 1 for public declarations.
* @see org.jetbrains.kotlin.ir.util.UniqId * @see org.jetbrains.kotlin.ir.util.UniqId