[ObjCExport] Translate ObjCObject types, respecting the @ExternalObjCClass annotation
KT-65891 Fixed
This commit is contained in:
committed by
Space Team
parent
a5baf42422
commit
622a88ff26
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.annotations.hasAnnotation
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.nameOrAnonymous
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.NativeForwardDeclarationKind
|
||||
import org.jetbrains.kotlin.name.NativeStandardInteropNames
|
||||
import org.jetbrains.kotlin.name.NativeStandardInteropNames.cInteropPackage
|
||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getDeclaredSuperInterfaceSymbols
|
||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getSuperClassSymbolNotAny
|
||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.objCErrorType
|
||||
import org.jetbrains.kotlin.objcexport.extras.withRequiresForwardDeclaration
|
||||
|
||||
/**
|
||||
* ClassId for 'kotlinx.cinterop.ObjCClass'
|
||||
*/
|
||||
private val objCClassClassId = ClassId(cInteropPackage, Name.identifier("ObjCClass"))
|
||||
|
||||
/**
|
||||
* ClassId for 'kotlinx.cinterop.ObjCProtocol'
|
||||
*/
|
||||
private val objCProtocolClassId = ClassId(cInteropPackage, Name.identifier("ObjCProtocol"))
|
||||
|
||||
|
||||
/**
|
||||
* Special type translation for types that implement `ObjCObject`:
|
||||
* Such types cannot be directly translated but need to use a supertype that is explicitly marked with an
|
||||
* `@ExternalObjCClass` annotation. (See [org.jetbrains.kotlin.objcexport.analysisApiUtils.isObjCObjectType]
|
||||
*/
|
||||
context(KtAnalysisSession, KtObjCExportSession)
|
||||
internal fun KtType.translateToObjCObjectType(): ObjCNonNullReferenceType {
|
||||
if (this !is KtNonErrorClassType) return objCErrorType
|
||||
val classSymbol = this.classSymbol as? KtClassOrObjectSymbol ?: return ObjCIdType
|
||||
return classSymbol.translateToObjCObjectType()
|
||||
}
|
||||
|
||||
context(KtAnalysisSession, KtObjCExportSession)
|
||||
private fun KtClassOrObjectSymbol.translateToObjCObjectType(): ObjCNonNullReferenceType {
|
||||
if (isObjCMetaClass()) return ObjCMetaClassType
|
||||
if (isObjCProtocolClass()) return ObjCClassType("Protocol").withRequiresForwardDeclaration()
|
||||
|
||||
if (isExternalObjCClass() || isObjCForwardDeclaration()) {
|
||||
return if (classKind == KtClassKind.INTERFACE) {
|
||||
ObjCProtocolType(nameOrAnonymous.asString().removeSuffix("Protocol")).withRequiresForwardDeclaration()
|
||||
} else {
|
||||
ObjCClassType(nameOrAnonymous.asString()).withRequiresForwardDeclaration()
|
||||
}
|
||||
}
|
||||
|
||||
return getSuperClassSymbolNotAny()?.translateToObjCObjectType() ?: ObjCIdType
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtClassOrObjectSymbol.isObjCMetaClass(): Boolean {
|
||||
if (classIdIfNonLocal == objCClassClassId) return true
|
||||
return getDeclaredSuperInterfaceSymbols().any { superInterfaceSymbol -> superInterfaceSymbol.isObjCMetaClass() }
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtClassOrObjectSymbol.isObjCProtocolClass(): Boolean {
|
||||
if (classIdIfNonLocal == objCProtocolClassId) return true
|
||||
return getDeclaredSuperInterfaceSymbols().any { superInterfaceSymbol -> superInterfaceSymbol.isObjCProtocolClass() }
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtClassOrObjectSymbol.isExternalObjCClass(): Boolean {
|
||||
return hasAnnotation(NativeStandardInteropNames.externalObjCClassClassId)
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtClassOrObjectSymbol.isObjCForwardDeclaration(): Boolean {
|
||||
val classId = classIdIfNonLocal ?: return false
|
||||
return when (NativeForwardDeclarationKind.packageFqNameToKind[classId.packageFqName]) {
|
||||
null, NativeForwardDeclarationKind.Struct -> false
|
||||
NativeForwardDeclarationKind.ObjCProtocol, NativeForwardDeclarationKind.ObjCClass -> true
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -89,7 +89,7 @@ internal fun KtType.mapToReferenceTypeIgnoringNullability(): ObjCNonNullReferenc
|
||||
|
||||
if (isObjCObjectType()) {
|
||||
// KT-65891: mapObjCObjectReferenceTypeIgnoringNullability
|
||||
return ObjCIdType
|
||||
return translateToObjCObjectType()
|
||||
}
|
||||
|
||||
/* Check if inline type represents 'regular' inline class */
|
||||
|
||||
Reference in New Issue
Block a user