[ObjCExport] KtObjCExportHeaderGenerator: Separate 'requiresClassForwardDeclaration' from ObjCType.classId
There are two different objectives associated with this newly introduced extras: - originClassId: Used to track where a type came from; Will ensure that the translation queue will be populated to also translate potential dependency classes - requiresForwardDeclaration: Used to track if a certain type requires rendering as forward declaration KT-65891
This commit is contained in:
committed by
Space Team
parent
85854a6b8d
commit
a5baf42422
@@ -11,8 +11,9 @@ sourceSets {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(intellijCore())
|
api(intellijCore())
|
||||||
api(project(":native:base"))
|
|
||||||
api(project(":core:compiler.common"))
|
api(project(":core:compiler.common"))
|
||||||
|
api(project(":kotlin-tooling-core"))
|
||||||
|
api(project(":native:base"))
|
||||||
|
|
||||||
testApi(libs.junit.jupiter.api)
|
testApi(libs.junit.jupiter.api)
|
||||||
testApi(libs.junit.jupiter.engine)
|
testApi(libs.junit.jupiter.engine)
|
||||||
|
|||||||
+2
-2
@@ -4,6 +4,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.backend.konan.objcexport.*
|
import org.jetbrains.kotlin.backend.konan.objcexport.*
|
||||||
import org.jetbrains.kotlin.objcexport.KtObjCExportSession
|
import org.jetbrains.kotlin.objcexport.KtObjCExportSession
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.withRequiresForwardDeclaration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traverses stubs and returns true if [objCErrorType] is used as a return, parameter or property type
|
* Traverses stubs and returns true if [objCErrorType] is used as a return, parameter or property type
|
||||||
@@ -44,5 +45,4 @@ internal val errorInterface
|
|||||||
superClassGenerics = emptyList()
|
superClassGenerics = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val objCErrorType = ObjCClassType(errorClassName, classId = null)
|
internal val objCErrorType = ObjCClassType(errorClassName).withRequiresForwardDeclaration()
|
||||||
internal val errorForwardClass = ObjCClassForwardDeclaration(errorClassName)
|
|
||||||
|
|||||||
+10
-6
@@ -6,6 +6,8 @@ import org.jetbrains.kotlin.backend.konan.objcexport.ObjCClassType
|
|||||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProperty
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProperty
|
||||||
import org.jetbrains.kotlin.backend.konan.objcexport.swiftNameAttribute
|
import org.jetbrains.kotlin.backend.konan.objcexport.swiftNameAttribute
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isCompanion
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isCompanion
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.withOriginClassId
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.withRequiresForwardDeclaration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If object class has companion object it needs to have property which returns this companion.
|
* If object class has companion object it needs to have property which returns this companion.
|
||||||
@@ -13,18 +15,20 @@ import org.jetbrains.kotlin.objcexport.analysisApiUtils.isCompanion
|
|||||||
*/
|
*/
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
internal fun KtClassOrObjectSymbol.buildCompanionProperty(): ObjCProperty {
|
internal fun KtClassOrObjectSymbol.buildCompanionProperty(): ObjCProperty {
|
||||||
|
|
||||||
val companion = this.getStaticMemberScope().getClassifierSymbols().toList()
|
val companion = this.getStaticMemberScope().getClassifierSymbols().toList()
|
||||||
.firstOrNull { (it as? KtClassOrObjectSymbol)?.isCompanion == true }
|
.firstOrNull { (it as? KtClassOrObjectSymbol)?.isCompanion == true }
|
||||||
|
|
||||||
val typeName = (companion as KtClassOrObjectSymbol).getObjCClassOrProtocolName()
|
val typeName = (companion as KtClassOrObjectSymbol).getObjCClassOrProtocolName()
|
||||||
val propertyName = ObjCPropertyNames.companionObjectPropertyName
|
val propertyName = ObjCPropertyNames.companionObjectPropertyName
|
||||||
|
|
||||||
return ObjCProperty(
|
return ObjCProperty(
|
||||||
propertyName,
|
name = propertyName,
|
||||||
null,
|
comment = null,
|
||||||
null,
|
origin = null,
|
||||||
ObjCClassType(typeName.objCName, classId = companion.classIdIfNonLocal),
|
type = ObjCClassType(typeName.objCName)
|
||||||
listOf("class", "readonly"),
|
.withRequiresForwardDeclaration()
|
||||||
|
.withOriginClassId(companion.classIdIfNonLocal),
|
||||||
|
propertyAttributes = listOf("class", "readonly"),
|
||||||
getterName = propertyName,
|
getterName = propertyName,
|
||||||
declarationAttributes = listOf(swiftNameAttribute(propertyName))
|
declarationAttributes = listOf(swiftNameAttribute(propertyName))
|
||||||
)
|
)
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.objcexport.extras
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCNullableReferenceType
|
||||||
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCReferenceType
|
||||||
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCType
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.tooling.core.extrasKeyOf
|
||||||
|
|
||||||
|
private val originClassIdKey = extrasKeyOf<ClassId>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks the Kotlin origin associated with [this] [ObjCType].
|
||||||
|
* Providing the [originClassId] can signal a header generation that the class associated with the [ClassId] should
|
||||||
|
* also be translated for the header.
|
||||||
|
*/
|
||||||
|
internal val ObjCType.originClassId: ClassId?
|
||||||
|
get() {
|
||||||
|
extras[originClassIdKey]?.let { return it }
|
||||||
|
|
||||||
|
if (this is ObjCNullableReferenceType) {
|
||||||
|
return this.nonNullType.extras[originClassIdKey]?.let { return it }
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [originClassId]
|
||||||
|
*/
|
||||||
|
internal fun <T : ObjCReferenceType> T.withOriginClassId(classId: ClassId?): T = also { type ->
|
||||||
|
if (classId != null) type.extras[originClassIdKey] = classId
|
||||||
|
else type.extras.remove(originClassIdKey)
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.objcexport.extras
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCReferenceType
|
||||||
|
import org.jetbrains.kotlin.tooling.core.extrasKeyOf
|
||||||
|
import org.jetbrains.kotlin.tooling.core.readWriteProperty
|
||||||
|
|
||||||
|
private val requiresForwardDeclarationKey = extrasKeyOf<Boolean>("isForwardDeclaration")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a type such that the generated header renders a forward declaration to this type when used.
|
||||||
|
* - Default value: `false`.
|
||||||
|
* - Example: All types used in function and method signature are expected to render forward declarations
|
||||||
|
*/
|
||||||
|
internal val ObjCReferenceType.requiresForwardDeclaration by requiresForwardDeclarationKey.readWriteProperty.notNull(false)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ⚠️ Marks [this] [ObjCReferenceType] as 'requires forward declaration' and returns the same instance.
|
||||||
|
* This method shall be used during the construction of a new type.
|
||||||
|
* @see ObjCReferenceType.requiresForwardDeclaration
|
||||||
|
*/
|
||||||
|
internal fun <T : ObjCReferenceType> T.withRequiresForwardDeclaration(): T = also { type ->
|
||||||
|
type.extras[requiresForwardDeclarationKey] = true
|
||||||
|
}
|
||||||
+79
-34
@@ -12,8 +12,9 @@ import org.jetbrains.kotlin.backend.konan.objcexport.*
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.objcexport.KtObjCExportHeaderGenerator.QueueElement
|
import org.jetbrains.kotlin.objcexport.KtObjCExportHeaderGenerator.QueueElement
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.*
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.*
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.originClassId
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.requiresForwardDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
|
||||||
|
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
@@ -52,9 +53,19 @@ private class KtObjCExportHeaderGenerator {
|
|||||||
private val objCStubsByClassId = hashMapOf<ClassId, ObjCClass?>()
|
private val objCStubsByClassId = hashMapOf<ClassId, ObjCClass?>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mutable aggregate of all entities that shall later be rendered as forward declarations
|
* An index of already translated classes (by ObjC name)
|
||||||
*/
|
*/
|
||||||
private val objCForwardDeclarations = mutableSetOf<ClassId>()
|
private val objCStubsByClassName = hashMapOf<String, ObjCClass>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mutable aggregate of all protocol names that shall later be rendered as forward declarations
|
||||||
|
*/
|
||||||
|
private val objCProtocolForwardDeclarations = mutableSetOf<String>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mutable aggregate of all class names that shall later be rendered as forward declarations
|
||||||
|
*/
|
||||||
|
private val objCClassForwardDeclarations = mutableSetOf<String>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See [symbolDeque]:
|
* See [symbolDeque]:
|
||||||
@@ -98,18 +109,25 @@ private class KtObjCExportHeaderGenerator {
|
|||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
private fun translateFileSymbol(symbol: KtFileSymbol) {
|
private fun translateFileSymbol(symbol: KtFileSymbol) {
|
||||||
val objCFacades = listOfNotNull(symbol.getExtensionsFacade(), symbol.getTopLevelFacade()).ifEmpty { return }
|
symbol.getExtensionsFacade()?.let { extensionFacade ->
|
||||||
objCStubs += objCFacades
|
objCStubs += extensionFacade
|
||||||
objCFacades.forEach { enqueueDependencyClasses(it) }
|
enqueueDependencyClasses(extensionFacade)
|
||||||
|
objCClassForwardDeclarations += extensionFacade.name
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol.getTopLevelFacade()?.let { topLevelFacade ->
|
||||||
|
objCStubs += topLevelFacade
|
||||||
|
enqueueDependencyClasses(topLevelFacade)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
private fun translateClassOrObjectSymbol(symbol: KtClassOrObjectSymbol) {
|
private fun translateClassOrObjectSymbol(symbol: KtClassOrObjectSymbol): ObjCClass? {
|
||||||
/* No classId, no stubs ¯\_(ツ)_/¯ */
|
/* No classId, no stubs ¯\_(ツ)_/¯ */
|
||||||
val classId = symbol.classIdIfNonLocal ?: return
|
val classId = symbol.classIdIfNonLocal ?: return null
|
||||||
|
|
||||||
/* Already processed this class, therefore nothing to do! */
|
/* Already processed this class, therefore nothing to do! */
|
||||||
if (classId in objCStubsByClassId) return
|
if (classId in objCStubsByClassId) return objCStubsByClassId[classId]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate: Note: Even if the result was 'null', the classId will still be marked as 'handled' by adding it
|
* Translate: Note: Even if the result was 'null', the classId will still be marked as 'handled' by adding it
|
||||||
@@ -117,7 +135,7 @@ private class KtObjCExportHeaderGenerator {
|
|||||||
*/
|
*/
|
||||||
val objCClass = symbol.translateToObjCExportStub()
|
val objCClass = symbol.translateToObjCExportStub()
|
||||||
objCStubsByClassId[classId] = objCClass
|
objCStubsByClassId[classId] = objCClass
|
||||||
objCClass ?: return
|
objCClass ?: return null
|
||||||
|
|
||||||
/*
|
/*
|
||||||
To replicate the translation (and result stub order) of the K1 implementation:
|
To replicate the translation (and result stub order) of the K1 implementation:
|
||||||
@@ -125,19 +143,24 @@ private class KtObjCExportHeaderGenerator {
|
|||||||
2) Super interface / superclass symbol export stubs (result of translation) have to be present in the stubs list before the
|
2) Super interface / superclass symbol export stubs (result of translation) have to be present in the stubs list before the
|
||||||
original stub
|
original stub
|
||||||
*/
|
*/
|
||||||
val superInterfaceOrClassSymbols = buildList {
|
symbol.getDeclaredSuperInterfaceSymbols().forEach { superInterfaceSymbol ->
|
||||||
addAll(symbol.getDeclaredSuperInterfaceSymbols())
|
translateClassOrObjectSymbol(superInterfaceSymbol)?.let {
|
||||||
addIfNotNull(symbol.getSuperClassSymbolNotAny())
|
objCProtocolForwardDeclarations += it.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
superInterfaceOrClassSymbols.forEach { superInterfaceOrClassSymbol ->
|
symbol.getSuperClassSymbolNotAny()?.let { superClassSymbol ->
|
||||||
translateClassOrObjectSymbol(superInterfaceOrClassSymbol)
|
translateClassOrObjectSymbol(superClassSymbol)?.let {
|
||||||
|
objCClassForwardDeclarations += it.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Note: It is important to add *this* stub to the result list only after translating/processing the superclass symbols */
|
/* Note: It is important to add *this* stub to the result list only after translating/processing the superclass symbols */
|
||||||
objCStubs += objCClass
|
objCStubs += objCClass
|
||||||
objCForwardDeclarations += superInterfaceOrClassSymbols.mapNotNull { it.classIdIfNonLocal }
|
objCStubsByClassName[objCClass.name] = objCClass
|
||||||
enqueueDependencyClasses(objCClass)
|
enqueueDependencyClasses(objCClass)
|
||||||
|
return objCClass
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,32 +177,54 @@ private class KtObjCExportHeaderGenerator {
|
|||||||
* and `Array` has to be registered as forward declaration.
|
* and `Array` has to be registered as forward declaration.
|
||||||
*/
|
*/
|
||||||
private fun enqueueDependencyClasses(stub: ObjCExportStub) {
|
private fun enqueueDependencyClasses(stub: ObjCExportStub) {
|
||||||
symbolDeque += stub.closureSequence().mapNotNull { child ->
|
symbolDeque += stub.closureSequence()
|
||||||
when (child) {
|
.mapNotNull { child ->
|
||||||
is ObjCMethod -> child.returnType
|
when (child) {
|
||||||
is ObjCParameter -> child.type
|
is ObjCMethod -> child.returnType
|
||||||
is ObjCProperty -> child.type
|
is ObjCParameter -> child.type
|
||||||
is ObjCTopLevel -> null
|
is ObjCProperty -> child.type
|
||||||
|
is ObjCTopLevel -> null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.flatMap { type ->
|
.flatMap { type ->
|
||||||
if (type is ObjCClassType) type.typeArguments + type
|
if (type is ObjCClassType) type.typeArguments + type
|
||||||
else listOf(type)
|
else listOf(type)
|
||||||
}.mapNotNull { if (it is ObjCReferenceType) it.classId else null }.onEach { objCForwardDeclarations += it }
|
}
|
||||||
.map { QueueElement.Class(it) }.toList()
|
.filterIsInstance<ObjCReferenceType>()
|
||||||
|
.onEach { type ->
|
||||||
|
if (!type.requiresForwardDeclaration) return@onEach
|
||||||
|
if (type is ObjCClassType) objCClassForwardDeclarations += type.className
|
||||||
|
if (type is ObjCProtocolType) objCProtocolForwardDeclarations += type.protocolName
|
||||||
|
}
|
||||||
|
.mapNotNull { it.originClassId }
|
||||||
|
.map(QueueElement::Class).toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [objCClassForwardDeclarations] are recorded by their respective class name:
|
||||||
|
* This method will resolve the objc interface that was translated, which is associated with the [className] and
|
||||||
|
* build the respective [ObjCClassForwardDeclaration] from it.
|
||||||
|
*
|
||||||
|
* If no such class was explicitly translated a simple [ObjCClassForwardDeclaration] will be emitted that does not
|
||||||
|
* carry any generics.
|
||||||
|
*/
|
||||||
|
private fun resolveObjCClassForwardDeclaration(className: String): ObjCClassForwardDeclaration {
|
||||||
|
objCStubsByClassName[className]
|
||||||
|
.let { it as? ObjCInterface }
|
||||||
|
?.let { objCClass -> return ObjCClassForwardDeclaration(objCClass.name, objCClass.generics) }
|
||||||
|
|
||||||
|
return ObjCClassForwardDeclaration(className)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
fun buildObjCHeader(): ObjCHeader {
|
fun buildObjCHeader(): ObjCHeader {
|
||||||
val hasErrorTypes = objCStubs.hasErrorTypes()
|
val hasErrorTypes = objCStubs.hasErrorTypes()
|
||||||
|
|
||||||
val resolvedObjCForwardDeclarations = objCForwardDeclarations.mapNotNull { classId -> objCStubsByClassId[classId] }.asSequence()
|
val protocolForwardDeclarations = objCProtocolForwardDeclarations.toSet()
|
||||||
|
|
||||||
val protocolForwardDeclarations = resolvedObjCForwardDeclarations.filterIsInstance<ObjCProtocol>().map { it.name }.toSet()
|
val classForwardDeclarations = objCClassForwardDeclarations
|
||||||
|
.map { className -> resolveObjCClassForwardDeclaration(className) }
|
||||||
val classForwardDeclarations = resolvedObjCForwardDeclarations.filterIsInstance<ObjCInterface>()
|
|
||||||
.map { stub -> ObjCClassForwardDeclaration(stub.name, stub.generics) }
|
|
||||||
.plus(listOfNotNull(errorForwardClass.takeIf { hasErrorTypes }))
|
|
||||||
.plus(objCStubs.filterIsInstance<ObjCInterface>().filter { it.isExtensionsFacade }.map { ObjCClassForwardDeclaration(it.name) })
|
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
val stubs = (if (configuration.generateBaseDeclarationStubs) objCBaseDeclarations() else emptyList()).plus(objCStubs)
|
val stubs = (if (configuration.generateBaseDeclarationStubs) objCBaseDeclarations() else emptyList()).plus(objCStubs)
|
||||||
|
|||||||
+4
-5
@@ -8,6 +8,8 @@ import org.jetbrains.kotlin.backend.konan.objcexport.*
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isCompanion
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isCompanion
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.withOriginClassId
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.withRequiresForwardDeclaration
|
||||||
|
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
fun KtClassOrObjectSymbol.translateToObjCObject(): ObjCClass? {
|
fun KtClassOrObjectSymbol.translateToObjCObject(): ObjCClass? {
|
||||||
@@ -83,11 +85,8 @@ private fun KtClassOrObjectSymbol.getDefaultMembers(): List<ObjCExportStub> {
|
|||||||
* See also: [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.mapReferenceType]
|
* See also: [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.mapReferenceType]
|
||||||
*/
|
*/
|
||||||
context(KtAnalysisSession, KtObjCExportSession)
|
context(KtAnalysisSession, KtObjCExportSession)
|
||||||
private fun KtClassOrObjectSymbol.toPropertyType() = ObjCClassType(
|
private fun KtClassOrObjectSymbol.toPropertyType() = ObjCClassType(getObjCClassOrProtocolName().objCName, emptyList(),)
|
||||||
getObjCClassOrProtocolName().objCName,
|
.withRequiresForwardDeclaration().withOriginClassId(classIdIfNonLocal)
|
||||||
emptyList(),
|
|
||||||
classIdIfNonLocal!!
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl.getObjectInstanceSelector]
|
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl.getObjectInstanceSelector]
|
||||||
|
|||||||
+5
-3
@@ -19,6 +19,8 @@ import org.jetbrains.kotlin.objcexport.analysisApiUtils.getInlineTargetTypeOrNul
|
|||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isError
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isError
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isObjCObjectType
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isObjCObjectType
|
||||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.objCErrorType
|
import org.jetbrains.kotlin.objcexport.analysisApiUtils.objCErrorType
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.withOriginClassId
|
||||||
|
import org.jetbrains.kotlin.objcexport.extras.withRequiresForwardDeclaration
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,10 +109,10 @@ internal fun KtType.mapToReferenceTypeIgnoringNullability(): ObjCNonNullReferenc
|
|||||||
|
|
||||||
// TODO NOW: create type translation test
|
// TODO NOW: create type translation test
|
||||||
return if (classSymbol?.classKind == KtClassKind.INTERFACE) {
|
return if (classSymbol?.classKind == KtClassKind.INTERFACE) {
|
||||||
ObjCProtocolType(fullyExpandedType.objCTypeName, classId)
|
ObjCProtocolType(fullyExpandedType.objCTypeName)
|
||||||
} else {
|
} else {
|
||||||
ObjCClassType(fullyExpandedType.objCTypeName, translateTypeArgumentsToObjC(), classId)
|
ObjCClassType(fullyExpandedType.objCTypeName, translateTypeArgumentsToObjC())
|
||||||
}
|
}.withRequiresForwardDeclaration().withOriginClassId(classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullyExpandedType is KtTypeParameterType) {
|
if (fullyExpandedType is KtTypeParameterType) {
|
||||||
|
|||||||
+7
-12
@@ -6,10 +6,14 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.objcexport
|
package org.jetbrains.kotlin.backend.konan.objcexport
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
|
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
||||||
|
import org.jetbrains.kotlin.tooling.core.MutableExtras
|
||||||
|
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
sealed class ObjCType {
|
sealed class ObjCType : HasMutableExtras {
|
||||||
|
override val extras: MutableExtras = mutableExtrasOf()
|
||||||
|
|
||||||
final override fun toString(): String = this.render()
|
final override fun toString(): String = this.render()
|
||||||
|
|
||||||
abstract fun render(attrsAndName: String): String
|
abstract fun render(attrsAndName: String): String
|
||||||
@@ -26,20 +30,13 @@ data class ObjCRawType(
|
|||||||
override fun render(attrsAndName: String): String = rawText.withAttrsAndName(attrsAndName)
|
override fun render(attrsAndName: String): String = rawText.withAttrsAndName(attrsAndName)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ObjCReferenceType : ObjCType() {
|
sealed class ObjCReferenceType : ObjCType()
|
||||||
@InternalKotlinNativeApi
|
|
||||||
open val classId: ClassId? = null
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class ObjCNonNullReferenceType : ObjCReferenceType()
|
sealed class ObjCNonNullReferenceType : ObjCReferenceType()
|
||||||
|
|
||||||
data class ObjCNullableReferenceType(
|
data class ObjCNullableReferenceType(
|
||||||
val nonNullType: ObjCNonNullReferenceType,
|
val nonNullType: ObjCNonNullReferenceType,
|
||||||
val isNullableResult: Boolean = false,
|
val isNullableResult: Boolean = false,
|
||||||
) : ObjCReferenceType() {
|
) : ObjCReferenceType() {
|
||||||
|
|
||||||
override val classId: ClassId? get() = nonNullType.classId
|
|
||||||
|
|
||||||
override fun render(attrsAndName: String): String {
|
override fun render(attrsAndName: String): String {
|
||||||
val attribute = if (isNullableResult) objcNullableResultAttribute else objcNullableAttribute
|
val attribute = if (isNullableResult) objcNullableResultAttribute else objcNullableAttribute
|
||||||
return nonNullType.render(" $attribute".withAttrsAndName(attrsAndName))
|
return nonNullType.render(" $attribute".withAttrsAndName(attrsAndName))
|
||||||
@@ -49,7 +46,6 @@ data class ObjCNullableReferenceType(
|
|||||||
data class ObjCClassType(
|
data class ObjCClassType(
|
||||||
val className: String,
|
val className: String,
|
||||||
val typeArguments: List<ObjCNonNullReferenceType> = emptyList(),
|
val typeArguments: List<ObjCNonNullReferenceType> = emptyList(),
|
||||||
override val classId: ClassId? = null,
|
|
||||||
) : ObjCNonNullReferenceType() {
|
) : ObjCNonNullReferenceType() {
|
||||||
|
|
||||||
|
|
||||||
@@ -80,7 +76,6 @@ data class ObjCGenericTypeParameterUsage(
|
|||||||
|
|
||||||
data class ObjCProtocolType(
|
data class ObjCProtocolType(
|
||||||
val protocolName: String,
|
val protocolName: String,
|
||||||
override val classId: ClassId? = null,
|
|
||||||
) : ObjCNonNullReferenceType() {
|
) : ObjCNonNullReferenceType() {
|
||||||
override fun render(attrsAndName: String) = "id<$protocolName>".withAttrsAndName(attrsAndName)
|
override fun render(attrsAndName: String) = "id<$protocolName>".withAttrsAndName(attrsAndName)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user