Refactor building of reverse adapters in ObjCExportCodeGenerator
* Make it more understandable and reliable: don't predict which reverse adapters are inherited, reuse information from generating super types instead. * Drop usages of obsolete "IrDeclaration.descriptor"
This commit is contained in:
committed by
Vasily Levchenko
parent
39ef940a7b
commit
61d3ae1477
+46
-7
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.LinkerOutputKind
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
|
||||
internal fun TypeBridge.makeNothing() = when (this) {
|
||||
is ReferenceBridge, is BlockPointerBridge -> kNullInt8Ptr
|
||||
@@ -235,7 +236,7 @@ internal class ObjCExportCodeGenerator(
|
||||
val allReverseAdapters = createReverseAdapters(types)
|
||||
|
||||
return types.map {
|
||||
val reverseAdapters = allReverseAdapters.getValue(it)
|
||||
val reverseAdapters = allReverseAdapters.getValue(it).adapters
|
||||
when (it) {
|
||||
objCClassForAny -> {
|
||||
createTypeAdapter(it, superClass = null, reverseAdapters)
|
||||
@@ -1355,14 +1356,51 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
|
||||
|
||||
private fun ObjCExportCodeGenerator.createReverseAdapters(
|
||||
types: List<ObjCTypeForKotlinType>
|
||||
): Map<ObjCTypeForKotlinType, List<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter>> {
|
||||
return types.associateWith { createReverseAdapters(it) }
|
||||
): Map<ObjCTypeForKotlinType, ReverseAdapters> {
|
||||
val irClassSymbolToType = types.associateBy { it.irClassSymbol }
|
||||
|
||||
val result = mutableMapOf<ObjCTypeForKotlinType, ReverseAdapters>()
|
||||
|
||||
fun getOrCreateFor(type: ObjCTypeForKotlinType): ReverseAdapters = result.getOrPut(type) {
|
||||
// Each type also inherits reverse adapters from super types.
|
||||
// This is handled in runtime when building TypeInfo for Swift or Obj-C type
|
||||
// subclassing Kotlin classes or interfaces. See [createTypeInfo] in ObjCExport.mm.
|
||||
val allSuperClasses = DFS.dfs(
|
||||
type.irClassSymbol.owner.superClasses,
|
||||
{ it.owner.superClasses },
|
||||
object : DFS.NodeHandlerWithListResult<IrClassSymbol, IrClassSymbol>() {
|
||||
override fun afterChildren(current: IrClassSymbol) {
|
||||
this.result += current
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
val inheritsAdaptersFrom = allSuperClasses.mapNotNull { irClassSymbolToType[it] }
|
||||
|
||||
val inheritedAdapters = inheritsAdaptersFrom.map { getOrCreateFor(it) }
|
||||
|
||||
createReverseAdapters(type, inheritedAdapters)
|
||||
}
|
||||
|
||||
types.forEach { getOrCreateFor(it) }
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private class ReverseAdapters(
|
||||
val adapters: List<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter>,
|
||||
val coveredMethods: Set<IrSimpleFunction>
|
||||
)
|
||||
|
||||
private fun ObjCExportCodeGenerator.createReverseAdapters(
|
||||
type: ObjCTypeForKotlinType
|
||||
): List<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter> {
|
||||
type: ObjCTypeForKotlinType,
|
||||
inheritedAdapters: List<ReverseAdapters>
|
||||
): ReverseAdapters {
|
||||
val result = mutableListOf<ObjCExportCodeGenerator.KotlinToObjCMethodAdapter>()
|
||||
val coveredMethods = mutableSetOf<IrSimpleFunction>()
|
||||
|
||||
val methodsCoveredByInheritedAdapters = inheritedAdapters.flatMapTo(mutableSetOf()) { it.coveredMethods }
|
||||
|
||||
val allBaseMethodsByIr = type.kotlinMethods.map { it.baseMethod }.associateBy { it.symbol.owner }
|
||||
|
||||
for (method in type.irClassSymbol.owner.simpleFunctions()) {
|
||||
@@ -1381,7 +1419,7 @@ private fun ObjCExportCodeGenerator.createReverseAdapters(
|
||||
val allOverriddenMethods = method.allOverriddenFunctions
|
||||
|
||||
val (inherited, uninherited) = allOverriddenMethods.partition {
|
||||
it != method && mapper.shouldBeExposed(it.descriptor)
|
||||
it in methodsCoveredByInheritedAdapters
|
||||
}
|
||||
|
||||
inherited.forEach {
|
||||
@@ -1401,6 +1439,7 @@ private fun ObjCExportCodeGenerator.createReverseAdapters(
|
||||
presentMethodTableBridges += functionName
|
||||
presentItableBridges += itablePlace
|
||||
result += createReverseAdapter(it, baseMethod, functionName, vtableIndex, itablePlace)
|
||||
coveredMethods += it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1412,7 +1451,7 @@ private fun ObjCExportCodeGenerator.createReverseAdapters(
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
return ReverseAdapters(result, coveredMethods)
|
||||
}
|
||||
|
||||
private fun ObjCExportCodeGenerator.nonOverridableAdapter(
|
||||
|
||||
@@ -902,6 +902,8 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
}
|
||||
};
|
||||
|
||||
// Compiler relies on using reverse adapters here from all supertypes
|
||||
// in [ObjCExportCodeGenerator.createReverseAdapters].
|
||||
for (const TypeInfo* t : supers) {
|
||||
const ObjCTypeAdapter* typeAdapter = getTypeAdapter(t);
|
||||
if (typeAdapter == nullptr) continue;
|
||||
@@ -921,6 +923,8 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
}
|
||||
}
|
||||
|
||||
// Compiler relies on using reverse adapters here from all supertypes
|
||||
// in [ObjCExportCodeGenerator.createReverseAdapters].
|
||||
for (const TypeInfo* typeInfo : addedInterfaces) {
|
||||
const ObjCTypeAdapter* typeAdapter = getTypeAdapter(typeInfo);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user